Merge branch 'hvm' of 10.141.1.101:/var/lib/qubes/git/marmarek/core into hvm

This commit is contained in:
Joanna Rutkowska 2012-04-24 16:06:33 +02:00
commit ab64b45120
8 changed files with 107 additions and 25 deletions

View File

@ -36,6 +36,9 @@ start()
touch /var/run/qubes/xl-lock touch /var/run/qubes/xl-lock
chgrp qubes /var/run/qubes/xl-lock chgrp qubes /var/run/qubes/xl-lock
chmod 660 /var/run/qubes/xl-lock chmod 660 /var/run/qubes/xl-lock
chgrp -R qubes /var/log/xen
chmod -R g+rX /var/log/xen
chmod g+s /var/log/xen/console
mkdir -p /var/run/xen-hotplug mkdir -p /var/run/xen-hotplug
xenstore-write /local/domain/0/name dom0 xenstore-write /local/domain/0/name dom0

View File

@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Version=1.0 Version=1.0
Type=Application Type=Application
Exec=qvm-start --quiet %VMNAME% Exec=qvm-start --quiet --tray %VMNAME%
Icon=%VMDIR%/icon.png Icon=%VMDIR%/icon.png
Terminal=false Terminal=false
Name=%VMNAME%: Start Name=%VMNAME%: Start

View File

@ -18,6 +18,8 @@ device_model='stubdom-dm'
usbdevice='tablet' usbdevice='tablet'
sdl=0 sdl=0
vnc=0 vnc=0
localtime = {localtime}
rtc_timeoffset = {timeoffset}
disk = [ {rootdev} disk = [ {rootdev}
{privatedev} {privatedev}
{otherdevs} {otherdevs}

View File

@ -256,6 +256,7 @@ class QubesVm(object):
"mac": { "attr": "_mac", "default": None }, "mac": { "attr": "_mac", "default": None },
"include_in_backups": { "default": True }, "include_in_backups": { "default": True },
"services": { "default": {}, "eval": "eval(str(value))" }, "services": { "default": {}, "eval": "eval(str(value))" },
"debug": { "default": False },
##### Internal attributes - will be overriden in __init__ regardless of args ##### Internal attributes - will be overriden in __init__ regardless of args
"appmenus_templates_dir": { "eval": \ "appmenus_templates_dir": { "eval": \
'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \ 'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \
@ -272,7 +273,7 @@ class QubesVm(object):
for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\ for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\
'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\ 'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\
'kernelopts', 'services', 'installed_by_rpm',\ 'kernelopts', 'services', 'installed_by_rpm',\
'uses_default_netvm', 'include_in_backups' ]: 'uses_default_netvm', 'include_in_backups', 'debug' ]:
attrs[prop]['save'] = 'str(self.%s)' % prop attrs[prop]['save'] = 'str(self.%s)' % prop
# Simple paths # Simple paths
for prop in ['conf_file', 'root_img', 'volatile_img', 'private_img']: for prop in ['conf_file', 'root_img', 'volatile_img', 'private_img']:
@ -899,6 +900,9 @@ class QubesVm(object):
args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode) args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode)
if hasattr(self, 'kernelopts'): if hasattr(self, 'kernelopts'):
args['kernelopts'] = self.kernelopts args['kernelopts'] = self.kernelopts
if self.debug:
print >> sys.stderr, "--> Debug mode: adding 'earlyprintk=xen' to kernel opts"
args['kernelopts'] += ' earlyprintk=xen'
return args return args
@ -1332,7 +1336,10 @@ class QubesVm(object):
print >> sys.stderr, "--> Starting Qubes GUId..." print >> sys.stderr, "--> Starting Qubes GUId..."
xid = self.get_xid() xid = self.get_xid()
retcode = subprocess.call ([qubes_guid_path, "-d", str(xid), "-c", self.label.color, "-i", self.label.icon, "-l", str(self.label.index)]) guid_cmd = [qubes_guid_path, "-d", str(xid), "-c", self.label.color, "-i", self.label.icon, "-l", str(self.label.index)]
if self.debug:
guid_cmd += ['-v', '-v']
retcode = subprocess.call (guid_cmd)
if (retcode != 0) : if (retcode != 0) :
raise QubesException("Cannot start qubes_guid!") raise QubesException("Cannot start qubes_guid!")
@ -1384,7 +1391,7 @@ class QubesVm(object):
qmemman_client = QMemmanClient() qmemman_client = QMemmanClient()
if not qmemman_client.request_memory(mem_required): if not qmemman_client.request_memory(mem_required):
qmemman_client.close() qmemman_client.close()
raise MemoryError ("ERROR: insufficient memory to start this VM") raise MemoryError ("ERROR: insufficient memory to start VM '%s'" % self.name)
# Bind pci devices to pciback driver # Bind pci devices to pciback driver
for pci in self.pcidevs: for pci in self.pcidevs:
@ -2167,6 +2174,7 @@ class QubesHVm(QubesVm):
attrs['config_file_template']['eval'] = 'config_template_hvm' attrs['config_file_template']['eval'] = 'config_template_hvm'
attrs['drive'] = { 'save': 'str(self.drive)' } attrs['drive'] = { 'save': 'str(self.drive)' }
attrs['maxmem'].pop('save') attrs['maxmem'].pop('save')
attrs['timezone'] = { 'default': 'localtime', 'save': 'str(self.timezone)' }
return attrs return attrs
@ -2182,7 +2190,6 @@ class QubesHVm(QubesVm):
kwargs["memory"] = default_hvm_memory kwargs["memory"] = default_hvm_memory
super(QubesHVm, self).__init__(**kwargs) super(QubesHVm, self).__init__(**kwargs)
self.config_file_template = config_template_hvm
# HVM doesn't support dynamic memory management # HVM doesn't support dynamic memory management
self.maxmem = self.memory self.maxmem = self.memory
@ -2199,6 +2206,7 @@ class QubesHVm(QubesVm):
attrs.remove('uses_default_kernel') attrs.remove('uses_default_kernel')
attrs.remove('kernelopts') attrs.remove('kernelopts')
attrs.remove('uses_default_kernelopts') attrs.remove('uses_default_kernelopts')
attrs += [ 'timezone' ]
return attrs return attrs
def create_on_disk(self, verbose, source_template = None): def create_on_disk(self, verbose, source_template = None):
@ -2286,6 +2294,17 @@ class QubesHVm(QubesVm):
params['otherdevs'] = "'script:file:%s,xvdc%s%s'," % (drive_path, type_mode, backend_domain) params['otherdevs'] = "'script:file:%s,xvdc%s%s'," % (drive_path, type_mode, backend_domain)
else: else:
params['otherdevs'] = '' params['otherdevs'] = ''
if self.timezone.lower() == 'localtime':
params['localtime'] = '1'
params['timeoffset'] = '0'
elif self.timezone.isdigit():
params['localtime'] = '0'
params['timeoffset'] = self.timezone
else:
print >>sys.stderr, "WARNING: invalid 'timezone' value: %s" % self.timezone
params['localtime'] = '0'
params['timeoffset'] = '0'
return params return params
def verify_files(self): def verify_files(self):
@ -2357,11 +2376,6 @@ class QubesHVm(QubesVm):
xc.domain_unpause(self.stubdom_xid) xc.domain_unpause(self.stubdom_xid)
super(QubesHVm, self).unpause() super(QubesHVm, self).unpause()
def get_xml_attrs(self):
attrs = super(QubesHVm, self).get_xml_attrs()
attrs["drive"] = str(self.drive)
return attrs
class QubesVmCollection(dict): class QubesVmCollection(dict):
""" """
A collection of Qubes VMs indexed by Qubes id (qid) A collection of Qubes VMs indexed by Qubes id (qid)
@ -2724,7 +2738,7 @@ class QubesVmCollection(dict):
"installed_by_rpm", "internal", "installed_by_rpm", "internal",
"uses_default_netvm", "label", "memory", "vcpus", "pcidevs", "uses_default_netvm", "label", "memory", "vcpus", "pcidevs",
"maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts", "maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts",
"mac", "services", "include_in_backups" ) "mac", "services", "include_in_backups", "debug", "drive" )
for attribute in common_attr_list: for attribute in common_attr_list:
kwargs[attribute] = element.get(attribute) kwargs[attribute] = element.get(attribute)
@ -2783,6 +2797,12 @@ class QubesVmCollection(dict):
if "kernelopts" not in kwargs: if "kernelopts" not in kwargs:
kwargs["uses_default_kernelopts"] = True kwargs["uses_default_kernelopts"] = True
if "debug" in kwargs:
kwargs["debug"] = True if kwargs["debug"] == "True" else False
if "drive" in kwargs and kwargs["drive"] == "None":
kwargs["drive"] = None
return kwargs return kwargs
def set_netvm_dependency(self, element): def set_netvm_dependency(self, element):

View File

@ -300,7 +300,7 @@ def main():
if not options.numeric: if not options.numeric:
load_services() load_services()
if not vm.has_firewall(): if not vm.has_firewall():
print "INFO: This VM has no firewall set, below defaults are listed" print "INFO: This VM has no firewall rules set, below defaults are listed"
display_firewall(conf) display_firewall(conf)
if changed: if changed:

View File

@ -75,10 +75,15 @@ def do_list(vm):
print fmt.format ("kernelopts", "%s (default)" % vm.kernelopts) print fmt.format ("kernelopts", "%s (default)" % vm.kernelopts)
else: else:
print fmt.format ("kernelopts", vm.kernelopts) print fmt.format ("kernelopts", vm.kernelopts)
if hasattr(vm, 'debug'):
print fmt.format("debug", "on" if vm.debug else "off")
if hasattr(vm, 'drive'): if hasattr(vm, 'drive'):
print fmt.format("drive", str(vm.drive)) print fmt.format("drive", str(vm.drive))
if hasattr(vm, 'timezone'):
print fmt.format("timezone", str(vm.timezone))
def set_label(vms, vm, args): def set_label(vms, vm, args):
if len (args) != 1: if len (args) != 1:
print >> sys.stderr, "Missing label name argument!" print >> sys.stderr, "Missing label name argument!"
@ -104,8 +109,9 @@ def set_memory(vms, vm, args):
print >>sys.stderr, "Memory size must be positive" print >>sys.stderr, "Memory size must be positive"
return False return False
if new_memory > vm.maxmem: qubes_host = QubesHost()
print >>sys.stderr, "Memory size must be less or equal to maxmem" if new_memory > qubes_host.memory_total/1024:
print >> sys.stderr, "This host has only {0} MB of RAM".format(qubes_host.memory_total/1024)
return False return False
vm.memory = new_memory vm.memory = new_memory
@ -127,7 +133,7 @@ def set_maxmem(vms, vm, args):
return False return False
if new_maxmem < vm.memory: if new_maxmem < vm.memory:
print >> sys.stderr, "WARNING: new maxmem smaller than memory property - VM will be able to use only 'maxmem' memory amount". print >> sys.stderr, "WARNING: new maxmem smaller than memory property - VM will be able to use only 'maxmem' memory amount"
vm.maxmem = new_maxmem vm.maxmem = new_maxmem
@ -278,7 +284,10 @@ def set_drive(vms, vm, args):
print >> sys.stderr, "Missing new drive content (file/device)!" print >> sys.stderr, "Missing new drive content (file/device)!"
return False return False
vm.drive = args[0] if args[0] == '' or args[0].lower() == 'none':
vm.drive = None
else:
vm.drive = args[0]
return True return True
def set_include_in_backups(vms, vm, args): def set_include_in_backups(vms, vm, args):
@ -289,12 +298,29 @@ def set_include_in_backups(vms, vm, args):
vm.include_in_backups = bool(eval(args[0].capitalize())) vm.include_in_backups = bool(eval(args[0].capitalize()))
return True return True
def set_include_in_backups(vms, vm, args): def set_debug(vms, vm, args):
if len (args) != 1: if len (args) != 1:
print >> sys.stderr, "Missing value (True/False)!" print >> sys.stderr, "Missing value (True/False or on/off)!"
return False return False
vm.include_in_backups = bool(eval(args[0].capitalize())) if args[0].lower() == "on":
vm.debug = True
elif args[0].lower() == "off":
vm.debug = False
else:
vm.debug = bool(eval(args[0].capitalize()))
return True
def set_timezone(vms, vm, args):
if len (args) != 1:
print >> sys.stderr, "Missing value ('localtime' or timeoffset in seconds)!"
return False
if not args[0].isdigit() and args[0].lower() == 'localtime':
print >> sys.stderr, "Invalid timezone value!"
return False
vm.timezone = args[0]
return True return True
properties = { properties = {
@ -311,6 +337,8 @@ properties = {
"name": set_name, "name": set_name,
"drive": set_drive, "drive": set_drive,
"mac": set_mac, "mac": set_mac,
"debug": set_debug,
"timezone": set_timezone,
} }

View File

@ -87,6 +87,8 @@ def vm_run_cmd(vm, cmd, options):
notify_function = tray_notify_generic if options.tray else None, notify_function = tray_notify_generic if options.tray else None,
passio = options.passio, localcmd = options.localcmd) passio = options.passio, localcmd = options.localcmd)
except QubesException as err: except QubesException as err:
if options.tray:
tray_notify_error(str(err))
print >> sys.stderr, "ERROR: %s" % str(err) print >> sys.stderr, "ERROR: %s" % str(err)
exit(1) exit(1)

View File

@ -26,17 +26,26 @@ from optparse import OptionParser
import subprocess import subprocess
import os import os
import sys import sys
import dbus
qubes_guid_path = "/usr/bin/qubes_guid" qubes_guid_path = "/usr/bin/qubes_guid"
notify_object = None
def tray_notify(str, label, timeout = 3000):
notify_object.Notify("Qubes", 0, label.icon, "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
def tray_notify_error(str, timeout = 3000):
notify_object.Notify("Qubes", 0, "dialog-error", "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
def main(): def main():
usage = "usage: %prog [options] <vm-name>" usage = "usage: %prog [options] <vm-name>"
parser = OptionParser (usage) parser = OptionParser (usage)
parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True) parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True)
parser.add_option ("--tray", action="store_true", dest="tray", default=False,
help="Use tray notifications instead of stdout" )
parser.add_option ("--no-guid", action="store_true", dest="noguid", default=False, parser.add_option ("--no-guid", action="store_true", dest="noguid", default=False,
help="Do not start the GUId (ignored)") help="Do not start the GUId (ignored)")
parser.add_option ("--console", action="store_true", dest="debug_console", default=False,
help="Attach debugging console to the newly started VM")
parser.add_option ("--drive", dest="drive", default=None, parser.add_option ("--drive", dest="drive", default=None,
help="Temporarily attach specified drive as CD/DVD or hard disk (can be specified with prefix 'hd:' or 'cdrom:', default is cdrom)") help="Temporarily attach specified drive as CD/DVD or hard disk (can be specified with prefix 'hd:' or 'cdrom:', default is cdrom)")
parser.add_option ("--hddisk", dest="drive_hd", default=None, parser.add_option ("--hddisk", dest="drive_hd", default=None,
@ -47,12 +56,18 @@ def main():
help="Do actions necessary when preparing DVM image") help="Do actions necessary when preparing DVM image")
parser.add_option ("--custom-config", action="store", dest="custom_config", default=None, parser.add_option ("--custom-config", action="store", dest="custom_config", default=None,
help="Use custom Xen config instead of Qubes-generated one") help="Use custom Xen config instead of Qubes-generated one")
parser.add_option ("--debug", action="store_true", dest="debug", default=False,
help="Enable debug mode for this VM (until its shutdown)")
(options, args) = parser.parse_args () (options, args) = parser.parse_args ()
if (len (args) != 1): if (len (args) != 1):
parser.error ("You must specify VM name!") parser.error ("You must specify VM name!")
vmname = args[0] vmname = args[0]
if options.tray:
global notify_object
notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
qvm_collection = QubesVmCollection() qvm_collection = QubesVmCollection()
qvm_collection.lock_db_for_reading() qvm_collection.lock_db_for_reading()
qvm_collection.load() qvm_collection.load()
@ -71,7 +86,7 @@ def main():
options.drive = 'hd:' + options.drive_hd options.drive = 'hd:' + options.drive_hd
if options.drive_cdrom: if options.drive_cdrom:
options.drive = 'cdrom:' + options.drive_hd options.drive = 'cdrom:' + options.drive_cdrom
if options.drive: if options.drive:
if hasattr(vm, 'drive'): if hasattr(vm, 'drive'):
@ -83,11 +98,23 @@ def main():
if options.custom_config: if options.custom_config:
vm.conf_file = options.custom_config vm.conf_file = options.custom_config
if options.debug:
vm.debug = True
try: try:
vm.verify_files() vm.verify_files()
xid = vm.start(debug_console=options.debug_console, verbose=options.verbose, preparing_dvm=options.preparing_dvm, start_guid=not options.noguid) xid = vm.start(verbose=options.verbose, preparing_dvm=options.preparing_dvm, start_guid=not options.noguid)
except (IOError, OSError, QubesException) as err: except (IOError, OSError, QubesException, MemoryError) as err:
print >> sys.stderr, "ERROR: {0}".format(err) if options.tray:
tray_notify_error(str(err))
else:
print >> sys.stderr, "ERROR: {0}".format(err)
exit (1) exit (1)
if options.debug:
print >> sys.stderr, "--> Debug mode enabled. Useful logs: "
print >> sys.stderr, " /var/log/xen/console/guest-%s.log" % vmname
print >> sys.stderr, " /var/log/qubes/guid.%d.log" % xid
print >> sys.stderr, " /var/log/qubes/qrexec.%d.log" % xid
main() main()