This commit is contained in:
kfraser@localhost.localdomain committed 2006-09-22 13:06:20 +01:00
commit 7f59f8a683
24 files changed
+722 -496

No files matched your search

+1
View File
@@ -36,6 +36,7 @@
#define CR4_VME (1 << 0)
#define CR4_PVI (1 << 1)
#define CR4_PSE (1 << 4)
#define CR4_PAE (1 << 5)
#define EFLAGS_ZF (1 << 6)
#define EFLAGS_TF (1 << 8)
+63 -16
View File
@@ -52,29 +52,74 @@ char *states[] = {
static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
#endif /* DEBUG */
#define PDE_PS (1 << 7)
#define PT_ENTRY_PRESENT 0x1
/* We only support access to <=4G physical memory due to 1:1 mapping */
static unsigned
guest_linear_to_real(unsigned long base, unsigned off)
guest_linear_to_real(uint32_t base)
{
unsigned int gcr3 = oldctx.cr3;
unsigned int l1_mfn;
unsigned int l0_mfn;
uint32_t gcr3 = oldctx.cr3;
uint64_t l2_mfn;
uint64_t l1_mfn;
uint64_t l0_mfn;
if (!(oldctx.cr0 & CR0_PG))
return base + off;
return base;
l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ];
if (!(l1_mfn & PT_ENTRY_PRESENT))
panic("l2 entry not present\n");
l1_mfn = l1_mfn & 0xfffff000 ;
if (!(oldctx.cr4 & CR4_PAE)) {
l1_mfn = ((uint32_t *)gcr3)[(base >> 22) & 0x3ff];
l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff];
if (!(l0_mfn & PT_ENTRY_PRESENT))
panic("l1 entry not present\n");
l0_mfn = l0_mfn & 0xfffff000;
if (oldctx.cr4 & CR4_PSE || l1_mfn & PDE_PS) {
/* 1 level page table */
l0_mfn = l1_mfn;
if (!(l0_mfn & PT_ENTRY_PRESENT))
panic("l1 entry not present\n");
return l0_mfn + off + (base & 0xfff);
l0_mfn &= 0xffc00000;
return l0_mfn + (base & 0x3fffff);
}
if (!(l1_mfn & PT_ENTRY_PRESENT))
panic("l2 entry not present\n");
l1_mfn &= 0xfffff000;
l0_mfn = ((uint32_t *)l1_mfn)[(base >> 12) & 0x3ff];
if (!(l0_mfn & PT_ENTRY_PRESENT))
panic("l1 entry not present\n");
l0_mfn &= 0xfffff000;
return l0_mfn + (base & 0xfff);
} else if (oldctx.cr4 & CR4_PAE && !(oldctx.cr4 & CR4_PSE)) {
l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
if (!(l2_mfn & PT_ENTRY_PRESENT))
panic("l3 entry not present\n");
l2_mfn &= 0x3fffff000ULL;
l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff];
if (!(l1_mfn & PT_ENTRY_PRESENT))
panic("l2 entry not present\n");
l1_mfn &= 0x3fffff000ULL;
l0_mfn = ((uint64_t *)l1_mfn)[(base >> 12) & 0x1ff];
if (!(l0_mfn & PT_ENTRY_PRESENT))
panic("l1 entry not present\n");
l0_mfn &= 0x3fffff000ULL;
return l0_mfn + (base & 0xfff);
} else { /* oldctx.cr4 & CR4_PAE && oldctx.cr4 & CR4_PSE */
l1_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
if (!(l1_mfn & PT_ENTRY_PRESENT))
panic("l2 entry not present\n");
l1_mfn &= 0x3fffff000ULL;
l0_mfn = ((uint64_t *)l1_mfn)[(base >> 21) & 0x1ff];
if (!(l0_mfn & PT_ENTRY_PRESENT))
panic("l1 entry not present\n");
l0_mfn &= 0x3ffe00000ULL;
return l0_mfn + (base & 0x1fffff);
}
}
static unsigned
@@ -95,7 +140,8 @@ address(struct regs *regs, unsigned seg, unsigned off)
(mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
return ((seg & 0xFFFF) << 4) + off;
entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[seg >> 3];
entry = ((unsigned long long *)
guest_linear_to_real(oldctx.gdtr_base))[seg >> 3];
entry_high = entry >> 32;
entry_low = entry & 0xFFFFFFFF;
@@ -780,7 +826,8 @@ load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes
return 1;
}
entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[sel >> 3];
entry = ((unsigned long long *)
guest_linear_to_real(oldctx.gdtr_base))[sel >> 3];
/* Check the P bit first */
if (!((entry >> (15+32)) & 0x1) && sel != 0)
+20 -17
View File
@@ -19,19 +19,23 @@
"""Labeling a domain configuration file or a resoruce.
"""
import sys, os
import os
import sys
from xen.util import dictio
from xen.util import security
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]"
print " xm addlabel <label> res <resource> [<policy>]\n"
print " This program adds an acm_label entry into the 'configfile'"
print " for a domain or to the global resource label file for a"
print " resource. It derives the policy from the running hypervisor"
print " if it is not given (optional parameter). If a label already"
print " exists for the given domain or resource, then addlabel fails.\n"
security.err("Usage")
def help():
return """
Format: xm addlabel <label> dom <configfile> [<policy>]
xm addlabel <label> res <resource> [<policy>]
This program adds an acm_label entry into the 'configfile'
for a domain or to the global resource label file for a
resource. It derives the policy from the running hypervisor
if it is not given (optional parameter). If a label already
exists for the given domain or resource, then addlabel fails."""
def validate_config_file(configfile):
@@ -114,9 +118,8 @@ def add_domain_label(label, configfile, policyref):
def main (argv):
try:
policyref = None
if len(argv) not in [4,5]:
usage()
return
if len(argv) not in (4, 5):
raise OptionError('Needs either 2 or 3 arguments')
label = argv[1]
@@ -135,20 +138,20 @@ def main (argv):
if os.path.isfile(configfile):
break
if not validate_config_file(configfile):
usage()
raise OptionError('Invalid config file')
else:
add_domain_label(label, configfile, policyref)
elif argv[2].lower() == "res":
resource = argv[3]
add_resource_label(label, resource, policyref)
else:
usage()
raise OptionError('Need to specify either "dom" or "res" as object to add label to.')
except security.ACMError:
sys.exit(-1)
if __name__ == '__main__':
main(sys.argv)
+11 -14
View File
@@ -28,20 +28,17 @@ from xen.util.security import ACMError, err
from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
from xen.util.security import empty_line_re, binary_name_re, policy_name_re
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
print " Adds a 'module' line to the Xen grub.conf entry"
print " so that xen boots into a specific access control"
print " policy. If kernelversion is not given, then this"
print " script tries to determine it by looking for a grub"
print " entry with a line kernel xen.* If there are multiple"
print " Xen entries, then it must be called with an explicit"
print " version (it will fail otherwise).\n"
err("Usage")
def help():
return """
Adds a 'module' line to the Xen grub.conf entry
so that xen boots into a specific access control
policy. If kernelversion is not given, then this
script tries to determine it by looking for a grub
entry with a line kernel xen.* If there are multiple
Xen entries, then it must be called with an explicit
version (it will fail otherwise).\n"""
def determine_kernelversion(user_specified):
within_xen_title = 0
@@ -152,7 +149,7 @@ def main(argv):
policy = argv[1]
user_kver = argv[2]
else:
usage()
raise OptionError('Invalid number of arguments')
if not policy_name_re.match(policy):
err("Illegal policy name \'" + policy + "\'")
-2
View File
@@ -18,9 +18,7 @@
XENCONSOLE = "xenconsole"
import xen.util.auxbin
def execConsole(domid):
xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
+33 -38
View File
@@ -25,7 +25,6 @@ import sys
import socket
import re
import xmlrpclib
import traceback
from xen.xend import sxp
from xen.xend import PrettyPrint
@@ -65,35 +64,36 @@ gopts.opt('quiet', short='q',
gopts.opt('path', val='PATH',
fn=set_value, default='.:/etc/xen',
use="""Search path for configuration scripts.
The value of PATH is a colon-separated directory list.""")
use="Search path for configuration scripts. "
"The value of PATH is a colon-separated directory list.")
gopts.opt('defconfig', short='f', val='FILE',
fn=set_value, default='xmdefconfig',
use="""Use the given Python configuration script.
The configuration script is loaded after arguments have been processed.
Each command-line option sets a configuration variable named after
its long option name, and these variables are placed in the
environment of the script before it is loaded.
Variables for options that may be repeated have list values.
Other variables can be set using VAR=VAL on the command line.
After the script is loaded, option values that were not set on the
command line are replaced by the values set in the script.""")
use="Use the given Python configuration script."
"The configuration script is loaded after arguments have been "
"processed. Each command-line option sets a configuration "
"variable named after its long option name, and these "
"variables are placed in the environment of the script before "
"it is loaded. Variables for options that may be repeated have "
"list values. Other variables can be set using VAR=VAL on the "
"command line. "
"After the script is loaded, option values that were not set "
"on the command line are replaced by the values set in the script.")
gopts.default('defconfig')
gopts.opt('config', short='F', val='FILE',
fn=set_value, default=None,
use="""Domain configuration to use (SXP).
SXP is the underlying configuration format used by Xen.
SXP configurations can be hand-written or generated from Python configuration
scripts, using the -n (dryrun) option to print the configuration.""")
use="Domain configuration to use (SXP).\n"
"SXP is the underlying configuration format used by Xen.\n"
"SXP configurations can be hand-written or generated from Python "
"configuration scripts, using the -n (dryrun) option to print\n"
"the configuration.")
gopts.opt('dryrun', short='n',
fn=set_true, default=0,
use="""Dry run - print the configuration but don't create the domain.
Loads the configuration script, creates the SXP configuration and prints it.""")
use="Dry run - prints the resulting configuration in SXP but "
"does not create the domain.")
gopts.opt('paused', short='p',
fn=set_true, default=0,
@@ -105,18 +105,16 @@ gopts.opt('console_autoconnect', short='c',
gopts.var('vncviewer', val='no|yes',
fn=set_bool, default=None,
use="""Spawn a vncviewer listening for a vnc server in the domain.
The address of the vncviewer is passed to the domain on the kernel command
line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
A display value with a free port is chosen if possible.
Only valid when vnc=1.
""")
use="Spawn a vncviewer listening for a vnc server in the domain.\n"
"The address of the vncviewer is passed to the domain on the "
"kernel command line using 'VNC_SERVER=<host>:<port>'. The port "
"used by vnc is 5500 + DISPLAY. A display value with a free port "
"is chosen if possible.\nOnly valid when vnc=1.")
gopts.var('vncconsole', val='no|yes',
fn=set_bool, default=None,
use="""Spawn a vncviewer process for the domain's graphical console.
Only valid when vnc=1.
""")
use="Spawn a vncviewer process for the domain's graphical console.\n"
"Only valid when vnc=1.")
gopts.var('name', val='NAME',
fn=set_value, default=None,
@@ -440,7 +438,6 @@ gopts.var('uuid', val='',
addresses for virtual network interfaces. This must be a unique
value across the entire cluster.""")
def err(msg):
"""Print an error to stderr and exit.
"""
@@ -490,7 +487,6 @@ def configure_disks(config_devs, vals):
"""Create the config for disks (virtual block devices).
"""
for (uname, dev, mode, backend) in vals.disk:
if uname.startswith('tap:'):
cls = 'tap'
else:
@@ -851,7 +847,6 @@ def choose_vnc_display():
if port in ports: continue
return d
return None
vncpid = None
def daemonize(prog, args):
@@ -885,7 +880,6 @@ def daemonize(prog, args):
w.write(str(pid2 or 0))
w.close()
os._exit(0)
os.close(w)
r = os.fdopen(r)
daemon_pid = int(r.read())
@@ -904,6 +898,7 @@ def spawn_vnc(display):
vncpid = daemonize("vncviewer", vncargs)
if vncpid == 0:
return 0
return VNC_BASE_PORT + display
def preprocess_vnc(vals):
@@ -1091,7 +1086,6 @@ def check_domain_label(config, verbose):
return answer
def config_security_check(config, verbose):
"""Checks each resource listed in the config to see if the active
policy will permit creation of a new domain using the config.
@@ -1145,7 +1139,6 @@ def config_security_check(config, verbose):
return answer
def create_security_check(config):
passed = 0
try:
@@ -1158,7 +1151,9 @@ def create_security_check(config):
sys.exit(-1)
return passed
def help():
return str(gopts)
def main(argv):
try:
@@ -1176,11 +1171,11 @@ def main(argv):
PrettyPrint.prettyprint(config)
else:
if not create_security_check(config):
err("Security configuration prevents domain from starting.")
raise OptionError('Security Configuration prevents domain from starting')
else:
dom = make_domain(opts, config)
if opts.vals.console_autoconnect:
console.execConsole(dom)
console.execConsole(dom)
if __name__ == '__main__':
main(sys.argv)
+9 -11
View File
@@ -22,20 +22,18 @@ import sys
from xen.util import security
from xen.xm import create
from xen.xend import sxp
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm dry-run <configfile>\n"
print "This program checks each resource listed in the configfile"
print "to see if the domain created by the configfile can access"
print "the resources. The status of each resource is listed"
print "individually along with the final security decision.\n"
security.err("Usage")
def help():
return """
This program checks each resource listed in the configfile
to see if the domain created by the configfile can access
the resources. The status of each resource is listed
individually along with the final security decision."""
def main (argv):
try:
if len(argv) != 2:
usage()
if len(argv) != 2:
raise OptionError('Invalid number of arguments')
passed = 0
(opts, config) = create.parseCommandLine(argv)
+4 -7
View File
@@ -21,12 +21,10 @@ import sys
from xen.util.security import ACMError, err, dump_policy
def usage():
print "\nUsage: xm dumppolicy\n"
print " Retrieve and print currently enforced"
print " hypervisor policy information (low-level).\n"
err("Usage")
def help():
return """
Retrieve and print currently enforced hypervisor policy information
(low-level)."""
def main(argv):
try:
@@ -34,7 +32,6 @@ def main(argv):
usage()
dump_policy()
except ACMError:
sys.exit(-1)
+16 -20
View File
@@ -21,13 +21,13 @@
import sys, os, re
from xen.util import dictio
from xen.util import security
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm getlabel dom <configfile>"
print " xm getlabel res <resource>\n"
print " This program shows the label for a domain or resource.\n"
security.err("Usage")
def help():
return """
Usage: xm getlabel dom <configfile>"
xm getlabel res <resource>\n"
This program shows the label for a domain or resource."""
def get_resource_label(resource):
"""Gets the resource label
@@ -90,21 +90,17 @@ def get_domain_label(configfile):
def main (argv):
try:
if len(argv) != 3:
usage()
if len(argv) != 3:
raise OptionError('Requires 2 arguments')
if argv[1].lower() == "dom":
configfile = argv[2]
get_domain_label(configfile)
elif argv[1].lower() == "res":
resource = argv[2]
get_resource_label(resource)
else:
usage()
except security.ACMError:
sys.exit(-1)
if argv[1].lower() == "dom":
configfile = argv[2]
get_domain_label(configfile)
elif argv[1].lower() == "res":
resource = argv[2]
get_resource_label(resource)
else:
raise OptionError('First subcommand argument must be "dom" or "res"')
if __name__ == '__main__':
main(sys.argv)
+34 -39
View File
@@ -23,49 +23,46 @@ import traceback
import string
from xen.util.security import ACMError, err, list_labels, active_policy
from xen.util.security import vm_label_re, res_label_re, all_label_re
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n"
print " Prints labels of the specified type (default is dom)"
print " that are defined in policy (default is current"
print " hypervisor policy).\n"
err("Usage")
def help():
return """
Prints labels of the specified type (default is dom)
that are defined in policy (default is current hypervisor policy)."""
def main(argv):
try:
policy = None
type = None
for i in argv[1:]:
i_s = string.split(i, '=')
if len(i_s) > 1:
if (i_s[0] == 'type') and (len(i_s) == 2):
if not type:
type = i_s[1]
else:
usage()
else:
usage()
else:
if not policy:
policy = i
else:
usage()
policy = None
ptype = None
for arg in argv[1:]:
key_val = arg.split('=')
if len(key_val) == 2 and key_val[0] == 'type':
if ptype:
raise OptionError('type is definied twice')
ptype = key_val[1].lower()
if not policy:
policy = active_policy
if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
err("No policy active. Please specify the <policy> parameter.")
if not type or (type in ['DOM', 'dom']):
condition = vm_label_re
elif type in ['RES', 'res']:
condition = res_label_re
elif type in ['ANY', 'any']:
condition = all_label_re
elif len(key_val) == 1:
if policy:
raise OptionError('policy is defined twice')
policy = arg
else:
err("Unknown label type \'" + type + "\'")
raise OptionError('Unrecognised option: %s' % arg)
if not policy:
policy = active_policy
if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
raise OptionError('No policy active, you must specify a <policy>')
if not ptype or ptype == 'dom':
condition = vm_label_re
elif ptype == 'res':
condition = res_label_re
elif ptype == 'any':
condition = all_label_re
else:
err("Unknown label type \'" + ptype + "\'")
try:
labels = list_labels(policy, condition)
labels.sort()
for label in labels:
@@ -74,9 +71,7 @@ def main(argv):
except ACMError:
sys.exit(-1)
except:
traceback.print_exc(limit=1)
sys.exit(-1)
traceback.print_exc(limit = 1)
if __name__ == '__main__':
main(sys.argv)
+8 -11
View File
@@ -21,26 +21,23 @@
import sys
import traceback
from xen.util.security import ACMError, err, load_policy
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm loadpolicy <policy>\n"
print " Load the compiled binary (.bin) policy"
print " into the running hypervisor.\n"
err("Usage")
def help():
return """Load the compiled binary (.bin) policy into the running
hypervisor."""
def main(argv):
if len(argv) != 2:
raise OptionError('No policy defined')
try:
if len(argv) != 2:
usage()
load_policy(argv[1])
except ACMError:
sys.exit(-1)
except:
traceback.print_exc(limit=1)
sys.exit(-1)
traceback.print_exc(limit = 1)
if __name__ == '__main__':
main(sys.argv)
+366 -258
View File
@@ -22,28 +22,27 @@
"""Grand unified management application for Xen.
"""
import os
import os.path
import sys
import re
import getopt
import socket
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
import traceback
import xmlrpclib
import traceback
import datetime
from select import select
import xen.xend.XendProtocol
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
from xen.xend import PrettyPrint
from xen.xend import sxp
from xen.xm.opts import *
import console
import xen.xend.XendClient
from xen.xend import XendClient
from xen.xend.XendClient import server
from xen.xm.opts import OptionError, Opts, wrap, set_true
from xen.xm import console
from xen.util import security
from select import select
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
@@ -51,93 +50,148 @@ from select import select
if not hasattr(getopt, 'gnu_getopt'):
getopt.gnu_getopt = getopt.getopt
# General help message
# Strings for shorthelp
console_help = "console <DomId> Attach to domain DomId's console."
create_help = """create [-c] <ConfigFile>
[Name=Value].. Create a domain based on Config File"""
destroy_help = "destroy <DomId> Terminate a domain immediately"
dump_core_help = """dump-core [-L|--live][-C|--crash]
<DomId> [FileName] Dump core of the specified domain"""
USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
"Control, list, and manipulate Xen guest instances.\n"
help_help = "help Display this message"
list_help = "list [--long] [DomId, ...] List information about domains"
list_label_help = "list [--label] [DomId, ...] List information about domains including their labels"
USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \
'For more help on \'xm\' see the xm(1) man page.\n' \
'For more help on \'xm create\' see the xmdomain.cfg(5) '\
' man page.\n'
mem_max_help = "mem-max <DomId> <Mem> Set maximum memory reservation for a domain"
mem_set_help = "mem-set <DomId> <Mem> Adjust the current memory usage for a domain"
migrate_help = "migrate <DomId> <Host> Migrate a domain to another machine"
pause_help = "pause <DomId> Pause execution of a domain"
reboot_help = "reboot <DomId> [-w][-a] Reboot a domain"
restore_help = "restore <File> Create a domain from a saved state file"
save_help = "save <DomId> <File> Save domain state (and config) to file"
shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain"
top_help = "top Monitor system and domains in real-time"
unpause_help = "unpause <DomId> Unpause a paused domain"
uptime_help = "uptime [-s|--short] [DomId, ...] List uptime for domains"
# Help strings are indexed by subcommand name in this way:
# 'subcommand': (argstring, description)
help_spacer = """
"""
SUBCOMMAND_HELP = {
# common commands
'console' : ('<Domain>',
'Attach to <Domain>\'s console.'),
'create' : ('<ConfigFile> [options] [vars]',
'Create a domain based on <ConfigFile>.'),
'destroy' : ('<Domain>',
'Terminate a domain immediately.'),
'help' : ('', 'Display this message.'),
'list' : ('[options] [Domain, ...]',
'List information about all/some domains.'),
'mem-max' : ('<Domain> <Mem>',
'Set the maximum amount reservation for a domain.'),
'mem-set' : ('<Domain> <Mem>',
'Set the current memory usage for a domain.'),
'migrate' : ('<Domain> <Host>',
'Migrate a domain to another machine.'),
'pause' : ('<Domain>', 'Pause execution of a domain.'),
'reboot' : ('<Domain> [-wa]', 'Reboot a domain.'),
'restore' : ('<CheckpointFile>',
'Restore a domain from a saved state.'),
'save' : ('<Domain> <CheckpointFile>',
'Save a domain state to restore later.'),
'shutdown' : ('<Domain> [-waRH]', 'Shutdown a domain.'),
'top' : ('', 'Monitor a host and the domains in real time.'),
'unpause' : ('<Domain>', 'Unpause a paused domain.'),
'uptime' : ('[-s] <Domain>', 'Print uptime for a domain.'),
# Strings for longhelp
sysrq_help = "sysrq <DomId> <letter> Send a sysrq to a domain"
domid_help = "domid <DomName> Converts a domain name to a domain id"
domname_help = "domname <DomId> Convert a domain id to a domain name"
vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of active VCPUs for a domain
within the range allowed by the domain
configuration"""
vcpu_list_help = "vcpu-list <DomId> List the VCPUs for a domain (or all domains)"
vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs> Set which cpus a VCPU can use"
dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buffer"
info_help = "info Get information about the xen host"
rename_help = "rename <DomId> <New Name> Rename a domain"
log_help = "log Print the xend log"
sched_sedf_help = "sched-sedf [DOM] [OPTIONS] Show|Set simple EDF parameters\n" + \
" -p, --period Relative deadline(ms).\n\
-s, --slice Worst-case execution time(ms)\n\
(slice < period).\n\
-l, --latency scaled period(ms) in case the domain\n\
is doing heavy I/O.\n\
-e, --extra flag (0/1) which controls whether the\n\
domain can run in extra-time\n\
-w, --weight mutually exclusive with period/slice and\n\
specifies another way of setting a domain's\n\
cpu period/slice."
# less used commands
sched_credit_help = "sched-credit Set or get credit scheduler parameters"
block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
[BackDomId] Create a new virtual block device"""
block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device,
where <DevId> may either be the device ID
or the device name as mounted in the guest"""
'dmesg' : ('[-c|--clear]',
'Read and/or clear Xend\'s message buffer.'),
'domid' : ('<DomainName>', 'Convert a domain name to domain id.'),
'domname' : ('<DomId>', 'Convert a domain id to domain name.'),
'dump-core' : ('[-L|--live] [-C|--crash] <Domain> [Filename]',
'Dump core for a specific domain.'),
'info' : ('', 'Get information about Xen host.'),
'log' : ('', 'Print Xend log'),
'rename' : ('<Domain> <NewDomainName>', 'Rename a domain.'),
'sched-sedf' : ('<Domain> [options]', 'Get/set EDF parameters.'),
'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]',
'Get/set credit scheduler parameters.'),
'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
'vcpu-list' : ('[<Domain>]',
'List the VCPUs for a domain or all domains.'),
'vcpu-pin' : ('<Domain> <VCPU> <CPUs>',
'Set which CPUs a VCPU can use.'),
'vcpu-set' : ('<Domain> <vCPUs>',
'Set the number of active VCPUs for allowed for the'
' domain.'),
block_list_help = "block-list <DomId> [--long] List virtual block devices for a domain"
block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode>
[BackDomId] Change block device configuration"""
network_attach_help = """network-attach <DomID> [script=<script>] [ip=<ip>] [mac=<mac>]
[bridge=<bridge>] [backend=<backDomID>]
Create a new virtual network device """
network_detach_help = """network-detach <DomId> <DevId> Destroy a domain's virtual network
device, where <DevId> is the device ID."""
# device commands
network_list_help = "network-list <DomId> [--long] List virtual network interfaces for a domain"
vnet_list_help = "vnet-list [-l|--long] list vnets"
vnet_create_help = "vnet-create <config> create a vnet from a config file"
vnet_delete_help = "vnet-delete <vnetid> delete a vnet"
vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices"
addlabel_help = "addlabel <label> dom <configfile> Add security label to domain\n <label> res <resource> or resource"
rmlabel_help = "rmlabel dom <configfile> Remove security label from domain\n res <resource> or resource"
getlabel_help = "getlabel dom <configfile> Show security label for domain\n res <resource> or resource"
dry_run_help = "dry-run <configfile> Tests if domain can access its resources"
resources_help = "resources Show info for each labeled resource"
cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration "
dumppolicy_help = "dumppolicy Print hypervisor ACM state information"
loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor"
makepolicy_help = "makepolicy <policy> Build policy and create .bin/.map files"
labels_help = "labels [policy] [type=DOM|..] List <type> labels for (active) policy."
serve_help = "serve Proxy Xend XML-RPC over stdio"
'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode>',
'Create a new virtual block device.'),
'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]',
'Change block device configuration'),
'block-detach' : ('<Domain> <DevId>',
'Destroy a domain\'s virtual block device.'),
'block-list' : ('<Domain> [--long]',
'List virtual block devices for a domain.'),
'network-attach': ('<Domain> [--script=<script>] [--ip=<ip>] '
'[--mac=<mac>]',
'Create a new virtual network device.'),
'network-detach': ('<Domain> <DevId>',
'Destroy a domain\'s virtual network device.'),
'network-list' : ('<Domain> [--long]',
'List virtual network interfaces for a domain.'),
'vnet-create' : ('<ConfigFile>','Create a vnet from ConfigFile.'),
'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'),
'vnet-list' : ('[-l|--long]', 'List Vnets.'),
'vtpm-list' : ('<Domain> [--long]', 'List virtual TPM devices.'),
short_command_list = [
# security
'addlabel' : ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
'Add security label to domain.'),
'rmlabel' : ('{dom <ConfigFile>|res <Resource>}',
'Remove a security label from domain.'),
'getlabel' : ('{dom <ConfigFile>|res <Resource>}',
'Show security label for domain or resource.'),
'dry-run' : ('<ConfigFile>',
'Test if a domain can access its resources.'),
'resources' : ('', 'Show info for each labeled resource.'),
'cfgbootpolicy' : ('<policy> [kernelversion]',
'Add policy to boot configuration.'),
'dumppolicy' : ('', 'Print hypervisor ACM state information.'),
'loadpolicy' : ('<policy.bin>', 'Load binary policy into hypervisor.'),
'makepolicy' : ('<policy>', 'Build policy and create .bin/.map '
'files.'),
'labels' : ('[policy] [type=dom|res|any]',
'List <type> labels for (active) policy.'),
'serve' : ('', 'Proxy Xend XMLRPC over stdio.'),
}
SUBCOMMAND_OPTIONS = {
'sched-sedf': (
('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'),
('-s [MS]', '--slice[=MS]' ,
'Worst-case execution time(ms). (slice < period)'),
('-l [MS]', '--latency[=MS]',
'Scaled period (ms) when domain performs heavy I/O'),
('-e [FLAG]', '--extra[=FLAG]',
'Flag (0 or 1) controls if domain can run in extra time.'),
('-w [FLOAT]', '--weight[=FLOAT]',
'CPU Period/slice (do not set with --period/--slice)'),
),
'sched-credit': (
('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'),
('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'),
('-c CAP', '--cap=CAP', 'Cap (int)'),
),
'list': (
('-l', '--long', 'Output all VM details in SXP'),
('', '--label', 'Include security labels'),
),
'dmesg': (
('-c', '--clear', 'Clear dmesg buffer'),
),
'vnet-list': (
('-l', '--long', 'List Vnets as SXP'),
),
'network-list': (
('-l', '--long', 'List resources as SXP'),
),
}
common_commands = [
"console",
"create",
"destroy",
@@ -165,7 +219,6 @@ domain_commands = [
"domname",
"dump-core",
"list",
"list_label",
"mem-max",
"mem-set",
"migrate",
@@ -223,67 +276,105 @@ acm_commands = [
"makepolicy",
"loadpolicy",
"cfgbootpolicy",
"dumppolicy"
"dumppolicy",
]
all_commands = (domain_commands + host_commands + scheduler_commands +
device_commands + vnet_commands + acm_commands)
####################################################################
#
# Help/usage printing functions
#
####################################################################
def commandToHelp(cmd):
return eval(cmd.replace("-", "_") + "_help")
def cmdHelp(cmd):
"""Print help for a specific subcommand."""
try:
args, desc = SUBCOMMAND_HELP[cmd]
except KeyError:
shortHelp()
return
print 'Usage: xm %s %s' % (cmd, args)
print
print desc
try:
# If options help message is defined, print this.
for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]:
if shortopt and longopt:
optdesc = '%s, %s' % (shortopt, longopt)
elif shortopt:
optdesc = shortopt
elif longopt:
optdesc = longopt
wrapped_desc = wrap(desc, 43)
print ' %-30s %-43s' % (optdesc, wrapped_desc[0])
for line in wrapped_desc[1:]:
print ' ' * 33 + line
print
except KeyError:
# if the command is an external module, we grab usage help
# from the module itself.
if cmd in IMPORTED_COMMANDS:
try:
cmd_module = __import__(cmd, globals(), locals(), 'xen.xm')
cmd_usage = getattr(cmd_module, "help", None)
if cmd_usage:
print cmd_usage()
except ImportError:
pass
def shortHelp():
"""Print out generic help when xm is called without subcommand."""
print USAGE_HELP
print 'Common \'xm\' commands:\n'
for command in common_commands:
try:
args, desc = SUBCOMMAND_HELP[command]
except KeyError:
continue
wrapped_desc = wrap(desc, 50)
print ' %-20s %-50s' % (command, wrapped_desc[0])
for line in wrapped_desc[1:]:
print ' ' * 22 + line
shorthelp = """Usage: xm <subcommand> [args]
Control, list, and manipulate Xen guest instances
print
print USAGE_FOOTER
print 'For a complete list of subcommands run \'xm help\'.'
def longHelp():
"""Print out full help when xm is called with xm --help or xm help"""
print USAGE_HELP
print 'xm full list of subcommands:\n'
for command in all_commands:
try:
args, desc = SUBCOMMAND_HELP[command]
except KeyError:
continue
xm common subcommands:
""" + help_spacer.join(map(commandToHelp, short_command_list)) + """
wrapped_desc = wrap(desc, 50)
print ' %-20s %-50s' % (command, wrapped_desc[0])
for line in wrapped_desc[1:]:
print ' ' * 22 + line
<DomName> can be substituted for <DomId> in xm subcommands.
print
print USAGE_FOOTER
For a complete list of subcommands run 'xm help --long'
For more help on xm see the xm(1) man page
For more help on xm create, see the xmdomain.cfg(5) man page"""
longhelp = """Usage: xm <subcommand> [args]
Control, list, and manipulate Xen guest instances
xm full list of subcommands:
Domain Commands:
""" + help_spacer.join(map(commandToHelp, domain_commands)) + """
Xen Host Commands:
""" + help_spacer.join(map(commandToHelp, host_commands)) + """
Scheduler Commands:
""" + help_spacer.join(map(commandToHelp, scheduler_commands)) + """
Virtual Device Commands:
""" + help_spacer.join(map(commandToHelp, device_commands)) + """
Vnet commands:
""" + help_spacer.join(map(commandToHelp, vnet_commands)) + """
Access Control commands:
""" + help_spacer.join(map(commandToHelp, acm_commands)) + """
<DomName> can be substituted for <DomId> in xm subcommands.
For a short list of subcommands run 'xm help'
For more help on xm see the xm(1) man page
For more help on xm create, see the xmdomain.cfg(5) man page"""
# array for xm help <command>
help = {
"--long": longhelp
}
for command in all_commands:
# create is handled specially
if (command != 'create'):
help[command] = commandToHelp(command)
def usage(cmd = None):
""" Print help usage information and exits """
if cmd:
cmdHelp(cmd)
else:
shortHelp()
sys.exit(1)
####################################################################
@@ -298,7 +389,7 @@ def arg_check(args, name, lo, hi = -1):
if hi == -1:
if n != lo:
err("'xm %s' requires %d argument%s.\n" % (name, lo,
lo > 1 and 's' or ''))
lo == 1 and '' or 's'))
usage(name)
else:
if n < lo or n > hi:
@@ -345,14 +436,19 @@ def err(msg):
def xm_save(args):
arg_check(args, "save", 2)
dom = args[0] # TODO: should check if this exists
try:
dominfo = parse_doms_info(server.xend.domain(args[0]))
except xmlrpclib.Fault, ex:
raise ex
domid = dominfo['domid']
savefile = os.path.abspath(args[1])
if not os.access(os.path.dirname(savefile), os.W_OK):
err("xm save: Unable to create file %s" % savefile)
sys.exit(1)
server.xend.domain.save(dom, savefile)
server.xend.domain.save(domid, savefile)
def xm_restore(args):
arg_check(args, "restore", 1)
@@ -366,9 +462,9 @@ def xm_restore(args):
server.xend.domain.restore(savefile)
def getDomains(domain_names):
def getDomains(domain_names, full = 0):
if domain_names:
return map(server.xend.domain, domain_names)
return [server.xend.domain(dom) for dom in domain_names]
else:
return server.xend.domains(1)
@@ -378,9 +474,11 @@ def xm_list(args):
show_vcpus = 0
show_labels = 0
try:
(options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label'])
(options, params) = getopt.gnu_getopt(args, 'lv',
['long','vcpus','label'])
except getopt.GetoptError, opterr:
err(opterr)
usage('list')
sys.exit(1)
for (k, v) in options:
@@ -397,7 +495,7 @@ def xm_list(args):
xm_vcpu_list(params)
return
doms = getDomains(params)
doms = getDomains(params, use_long)
if use_long:
map(PrettyPrint.prettyprint, doms)
@@ -412,7 +510,7 @@ def parse_doms_info(info):
return t(sxp.child_value(info, n, d))
return {
'dom' : get_info('domid', int, -1),
'domid' : get_info('domid', int, -1),
'name' : get_info('name', str, '??'),
'mem' : get_info('memory', int, 0),
'vcpus' : get_info('online_vcpus', int, 0),
@@ -428,7 +526,7 @@ def parse_sedf_info(info):
return t(sxp.child_value(info, n, d))
return {
'dom' : get_info('domain', int, -1),
'domid' : get_info('domid', int, -1),
'period' : get_info('period', int, -1),
'slice' : get_info('slice', int, -1),
'latency' : get_info('latency', int, -1),
@@ -436,34 +534,40 @@ def parse_sedf_info(info):
'weight' : get_info('weight', int, -1),
}
def xm_brief_list(doms):
print 'Name ID Mem(MiB) VCPUs State Time(s)'
print '%-40s %3s %8s %5s %5s %9s' % \
('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)')
format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \
"%(cpu_time)8.1f"
for dom in doms:
d = parse_doms_info(dom)
print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d)
print format % d
def xm_label_list(doms):
print '%-32s %3s %8s %5s %5s %9s %-8s' % \
('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label')
output = []
print 'Name ID Mem(MiB) VCPUs State Time(s) Label'
format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \
'%(cpu_time)8.1f %(seclabel)9s'
for dom in doms:
d = parse_doms_info(dom)
l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f " % d
if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
if d['seclabel']:
line = (l, d['seclabel'])
else:
line = (l, "ERROR")
if not d['seclabel']:
d['seclabel'] = 'ERROR'
elif security.active_policy in ['DEFAULT']:
line = (l, "DEFAULT")
d['seclabel'] = 'DEFAULT'
else:
line = (l, "INACTIVE")
output.append(line)
d['seclabel'] = 'INACTIVE'
output.append((format % d, d['seclabel']))
#sort by labels
output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
for l in output:
print l[0] + l[1]
for line, label in output:
print line
def xm_vcpu_list(args):
@@ -474,7 +578,11 @@ def xm_vcpu_list(args):
doms = server.xend.domains(False)
dominfo = map(server.xend.domain.getVCPUInfo, doms)
print 'Name ID VCPU CPU State Time(s) CPU Affinity'
print '%-32s %3s %5s %5s %5s %9s %s' % \
('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
' %(cpu_time)8.1f %(cpumap)s'
for dom in dominfo:
def get_info(n):
@@ -568,10 +676,7 @@ def xm_vcpu_list(args):
c = "-"
s = "--p"
print (
"%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" %
locals())
print format % locals()
def xm_reboot(args):
arg_check(args, "reboot", 1, 3)
@@ -634,31 +739,31 @@ def xm_dump_core(args):
def xm_rename(args):
arg_check(args, "rename", 2)
server.xend.domain.setName(args[0], args[1])
def xm_subcommand(command, args):
def xm_importcommand(command, args):
cmd = __import__(command, globals(), locals(), 'xen.xm')
cmd.main([command] + args)
#############################################################
def cpu_make_map(cpulist):
cpus = []
for c in cpulist.split(','):
if c.find('-') != -1:
(x,y) = c.split('-')
for i in range(int(x),int(y)+1):
cpus.append(int(i))
else:
cpus.append(int(c))
cpus.sort()
return cpus
def xm_vcpu_pin(args):
arg_check(args, "vcpu-pin", 3)
def cpu_make_map(cpulist):
cpus = []
for c in cpulist.split(','):
if c.find('-') != -1:
(x,y) = c.split('-')
for i in range(int(x),int(y)+1):
cpus.append(int(i))
else:
cpus.append(int(c))
cpus.sort()
return cpus
dom = args[0]
vcpu = int(args[1])
cpumap = cpu_make_map(args[2])
@@ -719,11 +824,12 @@ def xm_sched_sedf(args):
info['period'] = ns_to_ms(info['period'])
info['slice'] = ns_to_ms(info['slice'])
info['latency'] = ns_to_ms(info['latency'])
print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" +
print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" +
" %(latency)7.1f %(extratime)6d %(weight)6d") % info)
def domid_match(domid, info):
return domid is None or domid == info['name'] or domid == str(info['dom'])
return domid is None or domid == info['name'] or \
domid == str(info['domid'])
# we want to just display current info if no parameters are passed
if len(args) == 0:
@@ -757,20 +863,25 @@ def xm_sched_sedf(args):
elif k in ['-w', '--weight']:
opts['weight'] = v
# print header if we aren't setting any parameters
if len(opts.keys()) == 0:
print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)',
'Slice(ms)', 'Lat(ms)',
'Extra','Weight')
doms = filter(lambda x : domid_match(domid, x),
[parse_doms_info(dom) for dom in getDomains("")])
# print header if we aren't setting any parameters
if len(opts.keys()) == 0:
print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \
('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
'Extra','Weight')
for d in doms:
# fetch current values so as not to clobber them
sedf_info = \
parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
sedf_info['name'] = d['name']
try:
sedf_raw = server.xend.domain.cpu_sedf_get(d['domid'])
except xmlrpclib.Fault:
# domain does not support sched-sedf?
sedf_raw = {}
sedf_info = parse_sedf_info(sedf_raw)
sedf_info['name'] = d['name']
# update values in case of call to set
if len(opts.keys()) > 0:
for k in opts.keys():
@@ -780,7 +891,7 @@ def xm_sched_sedf(args):
v = map(int, [sedf_info['period'], sedf_info['slice'],
sedf_info['latency'],sedf_info['extratime'],
sedf_info['weight']])
rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
rv = server.xend.domain.cpu_sedf_set(d['domid'], *v)
if int(rv) != 0:
err("Failed to set sedf parameters (rv=%d)."%(rv))
@@ -789,17 +900,14 @@ def xm_sched_sedf(args):
print_sedf(sedf_info)
def xm_sched_credit(args):
usage_msg = """sched-credit: Set or get credit scheduler parameters
Usage:
sched-credit -d domain [-w weight] [-c cap]
"""
"""Get/Set options for Credit Scheduler."""
try:
opts, args = getopt.getopt(args[0:], "d:w:c:",
opts, params = getopt.getopt(args, "d:w:c:",
["domain=", "weight=", "cap="])
except getopt.GetoptError:
# print help information and exit:
print usage_msg
except getopt.GetoptError, opterr:
err(opterr)
usage('sched-credit')
sys.exit(1)
domain = None
@@ -816,15 +924,16 @@ def xm_sched_credit(args):
if domain is None:
# place holder for system-wide scheduler parameters
print usage_msg
err("No domain given.")
usage('sched-credit')
sys.exit(1)
if weight is None and cap is None:
print server.xend.domain.sched_credit_get(domain)
else:
err = server.xend.domain.sched_credit_set(domain, weight, cap)
if err != 0:
print err
result = server.xend.domain.sched_credit_set(domain, weight, cap)
if result != 0:
err(str(result))
def xm_info(args):
arg_check(args, "info", 0)
@@ -843,6 +952,8 @@ def xm_console(args):
dom = args[0]
info = server.xend.domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
if domid == -1:
raise Exception("Domain is not started")
console.execConsole(domid)
def xm_uptime(args):
@@ -920,8 +1031,11 @@ its contents if the [-c|--clear] flag is specified.
myargs = args
myargs.insert(0, 'dmesg')
gopts.parse(myargs)
if not (1 <= len(myargs) <= 2):
if len(myargs) not in (1, 2):
err('Invalid arguments: ' + str(myargs))
usage('dmesg')
sys.exit(1)
if not gopts.vals.clear:
print server.xend.node.dmesg.info()
@@ -939,7 +1053,7 @@ def xm_serve(args):
from fcntl import fcntl, F_SETFL
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(xen.xend.XendClient.XML_RPC_SOCKET)
s.connect(XendClient.XML_RPC_SOCKET)
fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK)
while True:
@@ -1085,7 +1199,7 @@ def parse_block_configuration(args):
cls = 'tap'
else:
cls = 'vbd'
vbd = [cls,
['uname', args[1]],
['dev', args[2]],
@@ -1094,19 +1208,12 @@ def parse_block_configuration(args):
vbd.append(['backend', args[4]])
# verify that policy permits attaching this resource
try:
if security.on():
dominfo = server.xend.domain(dom)
label = security.get_security_printlabel(dominfo)
else:
label = None
if security.on():
dominfo = server.xend.domain(dom)
label = security.get_security_printlabel(dominfo)
else:
label = None
security.res_security_check(args[1], label)
except security.ACMError, e:
print e.value
sys.exit(1)
except:
traceback.print_exc(limit=1)
sys.exit(1)
return (dom, vbd)
@@ -1206,10 +1313,10 @@ commands = {
"domid": xm_domid,
"domname": xm_domname,
"dump-core": xm_dump_core,
"reboot": xm_reboot,
"rename": xm_rename,
"restore": xm_restore,
"save": xm_save,
"reboot": xm_reboot,
"shutdown": xm_shutdown,
"uptime": xm_uptime,
"list": xm_list,
@@ -1249,24 +1356,24 @@ commands = {
}
## The commands supported by a separate argument parser in xend.xm.
subcommands = [
IMPORTED_COMMANDS = [
'create',
'migrate',
'sysrq',
'labels',
'addlabel',
'rmlabel',
'getlabel',
'dry-run',
'resources',
'cfgbootpolicy',
'makepolicy',
'loadpolicy',
'dumppolicy'
'rmlabel',
'getlabel',
'dry-run',
'resources',
]
for c in subcommands:
commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
for c in IMPORTED_COMMANDS:
commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c)
aliases = {
"balloon": "mem-set",
@@ -1284,11 +1391,18 @@ def xm_lookup_cmd(cmd):
elif aliases.has_key(cmd):
deprecated(cmd,aliases[cmd])
return commands[aliases[cmd]]
elif cmd == 'help':
longHelp()
sys.exit(0)
else:
if len( cmd ) > 1:
matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
if len( matched_commands ) == 1:
return matched_commands[0][1]
# simulate getopt's prefix matching behaviour
if len(cmd) > 1:
same_prefix_cmds = [commands[c] for c in commands.keys() \
if c[:len(cmd)] == cmd]
# only execute if there is only 1 match
if len(same_prefix_cmds) == 1:
return same_prefix_cmds[0]
err('Sub Command %s not found!' % cmd)
usage()
@@ -1296,27 +1410,17 @@ def deprecated(old,new):
print >>sys.stderr, (
"Command %s is deprecated. Please use xm %s instead." % (old, new))
def usage(cmd=None):
if cmd == 'create':
mycmd = xm_lookup_cmd(cmd)
mycmd( ['--help'] )
sys.exit(1)
if help.has_key(cmd):
print " " + help[cmd]
else:
print shorthelp
sys.exit(1)
def main(argv=sys.argv):
if len(argv) < 2:
usage()
if re.compile('-*help').match(argv[1]):
if len(argv) > 2:
usage(argv[2])
else:
usage()
sys.exit(0)
# intercept --help and output our own help
if '--help' in argv[1:]:
if '--help' == argv[1]:
longHelp()
else:
usage(argv[1])
sys.exit(0)
cmd = xm_lookup_cmd(argv[1])
@@ -1329,9 +1433,9 @@ def main(argv=sys.argv):
usage()
except socket.error, ex:
if os.geteuid() != 0:
err("Most commands need root access. Please try again as root.")
err("Most commands need root access. Please try again as root.")
else:
err("Error connecting to xend: %s. Is xend running?" % ex[1])
err("Unable to connect to xend: %s. Is xend running?" % ex[1])
sys.exit(1)
except KeyboardInterrupt:
print "Interrupted."
@@ -1340,16 +1444,16 @@ def main(argv=sys.argv):
if os.geteuid() != 0:
err("Most commands need root access. Please try again as root.")
else:
err("Error connecting to xend: %s." % ex[1])
err("Unable to connect to xend: %s." % ex[1])
sys.exit(1)
except SystemExit:
sys.exit(1)
except xmlrpclib.Fault, ex:
if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
print >>sys.stderr, (
"Error: the domain '%s' does not exist." % ex.faultString)
if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
err("Domain '%s' does not exist." % ex.faultString)
else:
print >>sys.stderr, "Error: %s" % ex.faultString
err(ex.faultString)
usage(argv[1])
sys.exit(1)
except xmlrpclib.ProtocolError, ex:
if ex.errcode == -1:
@@ -1364,6 +1468,10 @@ def main(argv=sys.argv):
except (ValueError, OverflowError):
err("Invalid argument.")
usage(argv[1])
except OptionError, e:
err(str(e))
usage(argv[1])
print e.usage()
except:
print "Unexpected error:", sys.exc_info()[0]
print
+5 -7
View File
@@ -20,7 +20,7 @@
import sys
import traceback
from xen.util.security import ACMError, err, make_policy
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm makepolicy <policy>\n"
@@ -29,13 +29,12 @@ def usage():
err("Usage")
def main(argv):
try:
if len(argv) != 2:
usage()
make_policy(argv[1])
if len(argv) != 2:
raise OptionError('No XML policy file specified')
try:
make_policy(argv[1])
except ACMError:
sys.exit(-1)
except:
@@ -43,7 +42,6 @@ def main(argv):
sys.exit(-1)
if __name__ == '__main__':
main(sys.argv)
+7 -9
View File
@@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MBIT',
fn=set_int, default=0,
use="Set level of resource usage for migration.")
def help(argv):
gopts.argv = argv
gopts.usage()
def help():
return str(gopts)
def main(argv):
opts = gopts
args = opts.parse(argv)
if opts.vals.help:
opts.usage()
return
if len(args) != 2:
opts.usage()
sys.exit(1)
raise OptionError('Invalid number of arguments')
dom = args[0]
dst = args[1]
server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port)
server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
+79 -11
View File
@@ -24,6 +24,46 @@ import os.path
import sys
import types
def wrap(text, width = 70):
""" Really basic textwrap. Useful because textwrap is not available
for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+.
"""
import string
if len(text) < width:
return [text]
lines = []
for line in text.split('\n'):
line = line.strip()
if len(line) < width:
lines.append(line)
continue
pos = 0
while pos <= len(line):
wline = line[pos:pos+width].strip()
if len(wline) < 2:
break
if wline[-1] in tuple(string.punctuation):
pos += width
else:
lastword = wline.split()[-1]
wline = wline[:-len(lastword)]
pos += width - len(lastword)
lines.append(wline)
return lines
class OptionError(Exception):
"""Denotes an error in option parsing."""
def __init__(self, message, usage = ''):
self.message = message
self.usage = usage
def __str__(self):
return self.message
class Opt:
"""An individual option.
"""
@@ -72,7 +112,21 @@ class Opt:
def __repr__(self):
return self.name + '=' + str(self.specified_val)
__str__ = __repr__
def __str__(self):
""" Formats the option into:
'-k, --key description'
"""
PARAM_WIDTH = 20
if self.val:
keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys])
else:
keys = ', '.join(self.optkeys)
desc = wrap(self.use, 55)
if len(keys) > PARAM_WIDTH:
desc = [''] + desc
wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc)
return keys.ljust(PARAM_WIDTH + 1) + wrapped
def set(self, value):
"""Set the option value.
@@ -243,7 +297,19 @@ class Opts:
def __repr__(self):
return '\n'.join(map(str, self.options))
__str__ = __repr__
def __str__(self):
options = [s for s in self.options if s.optkeys[0][0] == '-']
optvals = [s for s in self.options if s.optkeys[0][0] != '-']
output = ''
if options:
output += '\nOptions:\n\n'
output += '\n'.join([str(o) for o in options])
output += '\n'
if optvals:
output += '\nValues:\n\n'
output += '\n'.join([str(o) for o in optvals])
output += '\n'
return output
def opt(self, name, **args):
"""Add an option.
@@ -338,14 +404,14 @@ class Opts:
self.short_opts(),
self.long_opts())
except getopt.GetoptError, err:
self.err(str(err))
raise OptionError(str(err), self.use)
#self.err(str(err))
for (k, v) in xvals:
for opt in self.options:
if opt.specify(k, v): break
else:
print >>sys.stderr, "Error: Unknown option:", k
self.usage()
raise OptionError('Unknown option: %s' % k, self.use)
if not args:
break
@@ -390,10 +456,10 @@ class Opts:
def usage(self):
print 'Usage: ', self.argv[0], self.use or 'OPTIONS'
print
for opt in self.options:
opt.show()
print
if self.options:
for opt in self.options:
opt.show()
print
print
def var_usage(self):
@@ -427,7 +493,9 @@ class Opts:
self.load(p, help)
break
else:
self.err('Cannot open config file "%s"' % self.vals.defconfig)
raise OptionError('Unable to open config file: %s' % \
self.vals.defconfig,
self.use)
def load(self, defconfig, help):
"""Load a defconfig file. Local variables in the file
@@ -478,9 +546,9 @@ def set_false(opt, k, v):
def set_bool(opt, k, v):
"""Set a boolean option.
"""
if v in ['yes']:
if v in ('yes', 'y'):
opt.set(1)
elif v in ['no']:
elif v in ('no', 'n'):
opt.set(0)
else:
opt.opts.err('Invalid value:' +v)
+13 -12
View File
@@ -21,13 +21,12 @@
import sys
from xen.util import dictio
from xen.util import security
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm resource\n"
print " This program lists information for each resource in the"
print " global resource label file\n"
security.err("Usage")
def help():
return """Usage: xm resource
This program lists information for each resource in the
global resource label file."""
def print_resource_data(access_control):
"""Prints out a resource dictionary to stdout
@@ -38,11 +37,16 @@ def print_resource_data(access_control):
print " policy: "+policy
print " label: "+label
def main (argv):
if len(argv) > 1:
raise OptionError("No arguments required")
try:
if len(argv) != 1:
usage()
filename = security.res_label_filename
access_control = dictio.dict_read("resources", filename)
except:
print "Resource file not found."
return
try:
file = security.res_label_filename
@@ -52,9 +56,6 @@ def main (argv):
print_resource_data(access_control)
except security.ACMError:
sys.exit(-1)
if __name__ == '__main__':
main(sys.argv)
+17 -15
View File
@@ -21,15 +21,17 @@
import sys, os, re
from xen.util import dictio
from xen.util import security
from xen.xm.opts import OptionError
def usage():
print "\nUsage: xm rmlabel dom <configfile>"
print " xm rmlabel res <resource>\n"
print " This program removes an acm_label entry from the 'configfile'"
print " for a domain or from the global resource label file for a"
print " resource. If the label does not exist for the given domain or"
print " resource, then rmlabel fails.\n"
security.err("Usage")
def help():
return """
Example: xm rmlabel dom <configfile>
xm rmlabel res <resource>
This program removes an acm_label entry from the 'configfile'
for a domain or from the global resource label file for a
resource. If the label does not exist for the given domain or
resource, then rmlabel fails."""
def rm_resource_label(resource):
@@ -93,23 +95,23 @@ def rm_domain_label(configfile):
def main (argv):
try:
if len(argv) != 3:
usage()
if len(argv) != 3:
raise OptionError('Requires 2 arguments')
if argv[1].lower() not in ('dom', 'res'):
raise OptionError('Unrecognised type argument: %s' % argv[1])
try:
if argv[1].lower() == "dom":
configfile = argv[2]
rm_domain_label(configfile)
elif argv[1].lower() == "res":
resource = argv[2]
rm_resource_label(resource)
else:
usage()
except security.ACMError:
sys.exit(-1)
if __name__ == '__main__':
main(sys.argv)
+6 -8
View File
@@ -19,14 +19,12 @@ gopts.opt('help', short='h',
def main(argv):
opts = gopts
args = opts.parse(argv)
if opts.vals.help:
opts.usage()
return
# no options for the moment
if len(args) != 2:
opts.usage()
sys.exit(1)
if len(args) < 1:
raise OptionError('Missing domain argument')
if len(args) < 2:
raise OptionError('Missing sysrq character')
dom = args[0]
req = ord(args[1][0])
server.xend.domain.send_sysrq(dom, req)
+12
View File
@@ -259,6 +259,17 @@ static int svm_paging_enabled(struct vcpu *v)
return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
}
static int svm_pae_enabled(struct vcpu *v)
{
unsigned long cr4;
if(!svm_paging_enabled(v))
return 0;
cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
return (cr4 & X86_CR4_PAE);
}
#define IS_CANO_ADDRESS(add) 1
@@ -865,6 +876,7 @@ int start_svm(void)
hvm_funcs.realmode = svm_realmode;
hvm_funcs.paging_enabled = svm_paging_enabled;
hvm_funcs.long_mode_enabled = svm_long_mode_enabled;
hvm_funcs.pae_enabled = svm_pae_enabled;
hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
hvm_funcs.instruction_length = svm_instruction_length;
hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
+1
View File
@@ -746,6 +746,7 @@ static void vmx_setup_hvm_funcs(void)
hvm_funcs.realmode = vmx_realmode;
hvm_funcs.paging_enabled = vmx_paging_enabled;
hvm_funcs.long_mode_enabled = vmx_long_mode_enabled;
hvm_funcs.pae_enabled = vmx_pae_enabled;
hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
hvm_funcs.instruction_length = vmx_instruction_length;
hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
+1 -1
View File
@@ -2343,7 +2343,7 @@ void sh_update_paging_modes(struct vcpu *v)
}
else
#endif
if ( hvm_get_guest_ctrl_reg(v, 4) & X86_CR4_PAE )
if ( hvm_pae_enabled(v) )
{
#if CONFIG_PAGING_LEVELS >= 3
// 32-bit PAE mode guest...
+7
View File
@@ -57,6 +57,7 @@ struct hvm_function_table {
int (*realmode)(struct vcpu *v);
int (*paging_enabled)(struct vcpu *v);
int (*long_mode_enabled)(struct vcpu *v);
int (*pae_enabled)(struct vcpu *v);
int (*guest_x86_mode)(struct vcpu *v);
int (*instruction_length)(struct vcpu *v);
unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
@@ -146,6 +147,12 @@ hvm_long_mode_enabled(struct vcpu *v)
return hvm_funcs.long_mode_enabled(v);
}
static inline int
hvm_pae_enabled(struct vcpu *v)
{
return hvm_funcs.pae_enabled(v);
}
static inline int
hvm_guest_x86_mode(struct vcpu *v)
{
+3
View File
@@ -39,6 +39,9 @@ enum {
#define VMX_LONG_GUEST(ed) \
(test_bit(VMX_CPU_STATE_LMA_ENABLED, &ed->arch.hvm_vmx.cpu_state))
#define VMX_PAE_GUEST(ed) \
(test_bit(VMX_CPU_STATE_PAE_ENABLED, &ed->arch.hvm_vmx.cpu_state))
struct vmcs_struct {
u32 vmcs_revision_id;
unsigned char data [0]; /* vmcs size is read from MSR */
+6
View File
@@ -418,6 +418,12 @@ static inline int vmx_long_mode_enabled(struct vcpu *v)
return VMX_LONG_GUEST(current);
}
static inline int vmx_pae_enabled(struct vcpu *v)
{
ASSERT(v == current);
return VMX_PAE_GUEST(current);
}
/* Works only for vcpu == current */
static inline int vmx_realmode(struct vcpu *v)
{
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.