WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 1/8] [xm] Domain Groups: xm group commands

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 1/8] [xm] Domain Groups: xm group commands
From: Chris <hap10@xxxxxxxxxxxxxx>
Date: Tue, 20 Feb 2007 14:55:47 -0500
Delivery-date: Tue, 20 Feb 2007 11:56:46 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.9 (Macintosh/20061207)
xm:

1. Add the following commands: grp-create, grp-shutdown, grp-destroy,
grp-join, grp-pause, grp-unpause, grp-reboot, grp-save, grp-restore,
grp-migrate, grp-list

2. Add example group configuration file and parsing mechanism.




diff -r ecb6cd61a9cf tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/python/xen/xm/create.py     Tue Feb 20 12:59:11 2007 -0500
@@ -489,6 +489,11 @@ gopts.var('on_xend_stop', val='continue|
           - shutdown:       Domain is shutdown;
           - suspend:        Domain is suspended;
           """)
+
+gopts.var('dgid', val='NUM',
+          fn=set_int, default=32767,
+          use='Default domain group to join.')
+
 
 def err(msg):
     """Print an error to stderr and exit.
@@ -749,6 +754,8 @@ def make_config(vals):
         config.append(['backend', ['tpmif']])
     if vals.localtime:
         config.append(['localtime', vals.localtime])
+    if vals.dgid is not None:
+        config.append(['dgid', vals.dgid])
 
     config_image = configure_image(vals)
     if vals.bootloader:
@@ -1268,6 +1275,7 @@ def main(argv):
                     print("Could not start console\n");
                     sys.exit(0)
             dom = make_domain(opts, config)
+            return dom
 
 
 if __name__ == '__main__':
diff -r ecb6cd61a9cf tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/python/xen/xm/main.py       Tue Feb 20 12:59:11 2007 -0500
@@ -50,6 +50,7 @@ from xen.xm import console
 from xen.xm import console
 from xen.util import security
 from xen.util.xmlrpclib2 import ServerProxy
+from xen.xm import group
 
 import XenAPI
 
@@ -184,6 +185,25 @@ SUBCOMMAND_HELP = {
     'labels'        :  ('[policy] [type=dom|res|any]',
                         'List <type> labels for (active) policy.'),
     'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
+
+    # domain groups
+
+    'grp-create'    :  ('<config> [--managed | -m]','Create a domain group'),
+    'grp-shutdown'  :  ('<grp> [--keep| -k]','Shutdown all domains in group'),
+    'grp-destroy'   :  ('<grp> [--force | -f]','Destroy group'),
+    'grp-reboot'    :  ('<grp>','Reboot all domains in group'),
+    'grp-pause'     :  ('<grp>','Pause all domains in group'),
+    'grp-unpause'   :  ('<grp>','Unpause all domains in group'),
+    'grp-save'      :  ('<grp> <prefix>','Save all domains in group to ' 
+                        'files with the specified prefix'),
+    'grp-restore'   :  ('<CheckpointFile> [CheckpointFile ...]',
+                        'Restore all domains in group from file(s)'),
+    'grp-suspend'   :  ('<grp>','Suspend all domains in group'),
+    'grp-resume'    :  ('<grp>','Resume all domains in group'),
+    'grp-migrate'   :  ('<grp> <host> [--live | -l]',
+                        'Migrate all domains in group to host'),
+    'grp-join'      :  ('<dom> <grp>','Add domain to group'),
+    'grp-list'      :  ('','List groups and their members'),
 }
 
 SUBCOMMAND_OPTIONS = {
@@ -292,6 +312,20 @@ domain_commands = [
     "vcpu-set",
     ]
 
+group_commands = [
+    "grp-create",
+    "grp-shutdown",
+    "grp-destroy",
+    "grp-reboot",
+    "grp-pause",
+    "grp-unpause",
+    "grp-suspend",
+    "grp-resume",
+    "grp-migrate",
+    "grp-join",
+    "grp-list",
+]
+
 host_commands = [
     "dmesg",
     "info",
@@ -335,7 +369,8 @@ acm_commands = [
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
-                device_commands + vnet_commands + acm_commands + ['shell'])
+                device_commands + vnet_commands + acm_commands + ['shell'] +
+                group_commands )
 
 
 ##
@@ -482,12 +517,17 @@ def usage(cmd = None):
 #
 ####################################################################
 
-def arg_check(args, name, lo, hi = -1):
+def arg_check(args, name, lo, hi = None):
     n = len([i for i in args if i != '--'])
     
-    if hi == -1:
+    if hi == None:
         if n != lo:
             err("'xm %s' requires %d argument%s.\n" % (name, lo,
+                                                       lo == 1 and '' or 's'))
+            usage(name)
+    elif hi == -1:
+        if n < lo:
+            err("'xm %s' requires at least %d argument%s.\n" % (name, lo,
                                                        lo == 1 and '' or 's'))
             usage(name)
     else:
@@ -694,6 +734,7 @@ def parse_doms_info(info):
 
     return {
         'domid'    : get_info('domid',              str,   ''),
+        'dgid'     : get_info('dgid',               int,   -1),
         'name'     : get_info('name',               str,   '??'),
         'mem'      : get_info('memory_dynamic_min', int,   0),
         'state'    : get_info('state',              str,   ''),
@@ -733,6 +774,7 @@ def domid_match(domid, info):
     return domid is None or domid == info['name'] or \
            domid == str(info['domid'])
 
+
 def xm_brief_list(doms):
     print '%-40s %3s %5s %5s %10s %9s' % \
           ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)')
@@ -744,13 +786,14 @@ def xm_brief_list(doms):
         d = parse_doms_info(dom)
         print format % d
 
+
 def xm_label_list(doms):
-    print '%-32s %3s %5s %5s %5s %9s %-8s' % \
+    print '%-32s %3s %5s %5s %5s %9s %-8s %7s' % \
           ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
     
     output = []
     format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
-             '%(cpu_time)8.1f %(seclabel)9s'
+             '%(cpu_time)8.1f %(seclabel)9s %(dgid)7d'
     
     for dom in doms:
         d = parse_doms_info(dom)
@@ -1647,6 +1690,100 @@ def xm_vnet_delete(args):
     arg_check(args, "vnet-delete", 1)
     vnet = args[0]
     server.xend_vnet_delete(vnet)
+
+def xm_grp_create(args):
+    arg_check(args, "grp-create", 1)
+
+    CONFIG_ROOT = '/etc/xen/'
+    config_path = args[0]
+
+    if ( os.path.exists( config_path ) ):
+        verified_config_path = config_path
+    elif ( os.path.exists(CONFIG_ROOT + config_path ) ):
+        verified_config_path = CONFIG_ROOT + config_path
+    else:
+        err( "configuration file [%s] not found" % config_path )
+        return 1
+
+    return group.grp_create( verified_config_path )
+
+def xm_grp_destroy(args):
+    force = False
+    arg_check(args, "grp-destroy", 1, 2)
+    dgid = args[0]
+    for clflag in ['--force', '-f']:
+        if clflag in args:
+            force = True
+    return group.grp_destroy(dgid, force)
+
+def xm_grp_shutdown(args):
+    keep = False
+    arg_check(args, "grp-shutdown", 1, 2)
+    dgid = args[0]
+    for clflag in ['--keep', '-k']:
+        if clflag in args:
+            keep = True
+    return group.grp_shutdown(dgid, "poweroff", keep)
+
+def xm_grp_reboot(args):
+    arg_check(args, "grp-reboot", 1)
+    dgid = args[0]
+    return group.grp_shutdown(dgid, "reboot", True)
+
+def xm_grp_pause(args):
+    arg_check(args, "grp-pause", 1)
+    dgid = args[0]
+    return group.grp_pause(dgid)
+
+def xm_grp_unpause(args):
+    arg_check(args, "grp-unpause", 1)
+    dgid = args[0]
+    return group.grp_unpause(dgid)
+
+def xm_grp_save(args):
+    arg_check(args, "grp-save", 2)
+    dgid = args[0]
+    prefix = args[1]
+    return group.grp_save(dgid, prefix)
+
+def xm_grp_restore(args):
+    arg_check(args, "grp-restore", 1, -1)
+    return group.grp_restore(args)
+
+def xm_grp_suspend(args):
+    print "Not yet implemented"
+    #arg_check(args, "grp-suspend", 1)
+    #dgid = args[0]
+    #return group.grp_suspend(dgid)
+
+def xm_grp_resume(args):
+    print "Not yet implemented"
+    #arg_check(args, "grp-resume", 1)
+    #dgid = args[0]
+    #return group.grp_resume(dgid)
+
+def xm_grp_migrate(args):
+    live = False
+    arg_check(args, "grp-migrate", 2, 3)
+    dgid = args[0]
+    dst = args[1]
+    for clflag in ['--live', '-l']:
+        if clflag in args:
+            live = True
+    # hardcode these options for now
+    resource = 0
+    port = 0
+    return group.grp_migrate(dgid,dst,live,resource,port)
+
+def xm_grp_join(args):
+    arg_check(args, "grp-join", 2)
+    domid = args[0]
+    dgid = args[1]
+    return group.grp_join(domid, dgid)
+
+def xm_grp_list(args):
+    arg_check(args, "grp-list", 0)
+    return group.grp_list()
 
 commands = {
     "shell": xm_shell,
@@ -1704,6 +1841,20 @@ commands = {
     "vnet-delete": xm_vnet_delete,
     # vtpm
     "vtpm-list": xm_vtpm_list,
+    # group
+    "grp-create": xm_grp_create,
+    "grp-shutdown": xm_grp_shutdown,
+    "grp-destroy": xm_grp_destroy,
+    "grp-reboot": xm_grp_reboot,
+    "grp-pause": xm_grp_pause,
+    "grp-unpause": xm_grp_unpause,
+    "grp-save": xm_grp_save,
+    "grp-restore": xm_grp_restore,
+    "grp-suspend": xm_grp_suspend,
+    "grp-resume": xm_grp_resume,
+    "grp-migrate": xm_grp_migrate,
+    "grp-join": xm_grp_join,
+    "grp-list": xm_grp_list,
     }
 
 ## The commands supported by a separate argument parser in xend.xm.
diff -r ecb6cd61a9cf tools/python/xen/xm/group.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xm/group.py      Tue Feb 20 12:59:11 2007 -0500
@@ -0,0 +1,274 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Author: Chris Bookholt <hap10@xxxxxxxxxxxxxx>
+#============================================================================
+import os.path
+import sys
+import xmlrpclib
+import time
+from xen.xm.opts import Opts
+from xen.xend import sxp
+from xen.xend.XendClient import server
+from sets import Set
+
+opts = Opts()
+
+# print an error to stderr and exit.
+def err(msg):
+    print >>sys.stderr, "Error:", msg
+    sys.exit(1)
+
+
+def get_grp(dgid):
+    grpinfo = server.xend.group(dgid)
+    if not grpinfo:
+        err("group %s does not exist" % dgid)
+    return grpinfo
+
+
+def idCheck(dgid, op):
+    dgid = int(dgid)
+    if (dgid == 0 or dgid == 32767):
+        err("cannot %s group %d" % (op,dgid))
+
+
+def wait_create(domname, timeout):
+    counter = 0
+    while counter < timeout:
+        domains = server.xend.domains(0)
+        if domname in domains:
+            return
+        counter += 1
+        time.sleep(1)
+    err("timeout reached; problem starting group member dom: %s" % domname)
+
+
+# read and parse sxp config from file
+def make_config(config_file_path):
+    try:
+        fin = file(config_file_path, 'rb')
+        try:
+            config = sxp.parse(fin)
+        finally:
+            fin.close()
+        if config is None:
+            config = ['grp_config']
+        else:
+            config.insert(0, 'grp_config')
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+    return config
+
+
+# create a domain group
+def make_domain_group(config):
+    try:
+        grpinfo = server.xend.group.create(config)
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+    return grpinfo
+
+
+# start the group members
+def populate_group(grpinfo, managed):
+    if managed:
+        from xen.xm import new
+    else:
+        from xen.xm import create
+
+    for domdata in grpinfo['member_list']:
+        domdata_list = domdata.split(":")
+        domname = domdata_list[0]
+        dom_config_path = domdata_list[1]
+        if managed:
+            #print "creating managed domain %s from file: %s" % 
(domname,dom_config_path)
+            new.main([None,dom_config_path])
+            #print "starting managed domain %s" % domname
+            server.xend.domain.start(domname, False)
+            domid = sxp.child_value(server.xend.domain(domname), 'domid')
+        else:
+            domid = create.main([None,dom_config_path])
+        wait_create(domname, 10)
+        dgid = grpinfo['dgid']
+        grp_join(domid, dgid)
+    #grp_unpause(grp.dgid)
+
+
+def grp_create(config_file_path, managed = False):
+    config = make_config(config_file_path)
+    grpinfo = make_domain_group(config)
+    populate_group(grpinfo, managed)
+
+
+# shutdown or reboot a group of domains
+def grp_shutdown(dgid, reason, keep):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"shutdown or reboot")
+    try:
+        server.xend.group.shutdown(dgid, reason)
+        if reason == "poweroff" and not keep:
+            print "waiting for group members to shutdown..."
+            from xen.xm.shutdown import wait_shutdown
+            wait_shutdown(opts, grpinfo['members'])
+            grp_destroy(dgid, force = False)
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# destroy a domain group
+def grp_destroy(dgid, force = False):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"destroy")
+    try:
+        if force:
+            grp_pause(dgid)
+            for domid in grpinfo['members']:
+                server.xend.domain.destroy(domid)
+            print "waiting for group members to be destroyed..."
+            from xen.xm.shutdown import wait_shutdown
+            wait_shutdown(opts, grpinfo['members'])
+        server.xend.group.destroy(grpinfo['dgid'])
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+    return
+
+
+# save a group of running domains
+def grp_save(dgid, prefix):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"save")
+    try:
+        server.xend.group.save(dgid, prefix)
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# retore a group of running domains
+def grp_restore(srcs):
+    try:
+        server.xend.group.restore(srcs)
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# suspend a group of running, managed domains
+#def grp_suspend(dgid):
+#    grpinfo = get_grp(dgid)
+#    idCheck(grpinfo['dgid'],"suspend")
+#    try:
+#        server.xend.group.suspend(dgid)
+#    except xmlrpclib.Fault, ex:
+#        err(str(ex))
+#    except Exception, ex:
+#        print("Error: %s" % str(ex))
+#        raise Exception
+    
+
+# resume a suspended domain group
+#def grp_resume(dgid):
+#    try:
+#        server.xend.group.resume(dgid)
+#    except xmlrpclib.Fault, ex:
+#        err(str(ex))
+#    except Exception, ex:
+#        print("Error: %s" % str(ex))
+#        raise Exception
+    
+
+# pause a domain group
+def grp_pause(dgid):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"pause")
+    try:
+        server.xend.group.pause(grpinfo['dgid'])
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# unpause a domain group
+def grp_unpause(dgid):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"unpause")
+    try:
+        server.xend.group.unpause(grpinfo['dgid'])
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# migrate a domain group
+def grp_migrate(dgid, dst, live, resource, port):
+    grpinfo = get_grp(dgid)
+    idCheck(grpinfo['dgid'],"unpause")
+    try:
+        server.xend.group.migrate(grpinfo['dgid'], dst, live, resource, port)
+    except xmlrpclib.Fault, ex:
+       err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# cause a domain to join a group
+def grp_join( dom, dgid ):
+    grpinfo = get_grp(dgid)
+    domid = sxp.child_value(server.xend.domain(dom), 'domid')
+    try:
+        server.xend.group.join(domid, grpinfo['dgid'])
+    except xmlrpclib.Fault, ex:
+       err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception
+
+
+# print list of domain group stats
+def grp_list():
+    try:
+        domgrps = server.xend.group.list()
+        format = "%-20s %-6s %-5s %-46s"
+        print format % ('Name', 'ID', 'Size', 'Members')
+        for grpinfo in domgrps:
+            name = grpinfo['grp_name']
+            dgid = grpinfo['dgid']
+            size = grpinfo['size']
+            members = ", ".join(grpinfo['members'])
+            print format % (name, dgid, size, members)
+    except xmlrpclib.Fault, ex:
+        err(str(ex))
+    except Exception, ex:
+        print("Error: %s" % str(ex))
+        raise Exception




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 1/8] [xm] Domain Groups: xm group commands, Chris <=