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
chgrp qubes /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
xenstore-write /local/domain/0/name dom0

View File

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

View File

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

View File

@ -256,6 +256,7 @@ class QubesVm(object):
"mac": { "attr": "_mac", "default": None },
"include_in_backups": { "default": True },
"services": { "default": {}, "eval": "eval(str(value))" },
"debug": { "default": False },
##### Internal attributes - will be overriden in __init__ regardless of args
"appmenus_templates_dir": { "eval": \
'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',\
'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\
'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
# Simple paths
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)
if hasattr(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
@ -1332,7 +1336,10 @@ class QubesVm(object):
print >> sys.stderr, "--> Starting Qubes GUId..."
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) :
raise QubesException("Cannot start qubes_guid!")
@ -1384,7 +1391,7 @@ class QubesVm(object):
qmemman_client = QMemmanClient()
if not qmemman_client.request_memory(mem_required):
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
for pci in self.pcidevs:
@ -2167,6 +2174,7 @@ class QubesHVm(QubesVm):
attrs['config_file_template']['eval'] = 'config_template_hvm'
attrs['drive'] = { 'save': 'str(self.drive)' }
attrs['maxmem'].pop('save')
attrs['timezone'] = { 'default': 'localtime', 'save': 'str(self.timezone)' }
return attrs
@ -2182,7 +2190,6 @@ class QubesHVm(QubesVm):
kwargs["memory"] = default_hvm_memory
super(QubesHVm, self).__init__(**kwargs)
self.config_file_template = config_template_hvm
# HVM doesn't support dynamic memory management
self.maxmem = self.memory
@ -2199,6 +2206,7 @@ class QubesHVm(QubesVm):
attrs.remove('uses_default_kernel')
attrs.remove('kernelopts')
attrs.remove('uses_default_kernelopts')
attrs += [ 'timezone' ]
return attrs
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)
else:
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
def verify_files(self):
@ -2357,11 +2376,6 @@ class QubesHVm(QubesVm):
xc.domain_unpause(self.stubdom_xid)
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):
"""
A collection of Qubes VMs indexed by Qubes id (qid)
@ -2724,7 +2738,7 @@ class QubesVmCollection(dict):
"installed_by_rpm", "internal",
"uses_default_netvm", "label", "memory", "vcpus", "pcidevs",
"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:
kwargs[attribute] = element.get(attribute)
@ -2783,6 +2797,12 @@ class QubesVmCollection(dict):
if "kernelopts" not in kwargs:
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
def set_netvm_dependency(self, element):

View File

@ -300,7 +300,7 @@ def main():
if not options.numeric:
load_services()
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)
if changed:

View File

@ -75,10 +75,15 @@ def do_list(vm):
print fmt.format ("kernelopts", "%s (default)" % vm.kernelopts)
else:
print fmt.format ("kernelopts", vm.kernelopts)
if hasattr(vm, 'debug'):
print fmt.format("debug", "on" if vm.debug else "off")
if hasattr(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):
if len (args) != 1:
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"
return False
if new_memory > vm.maxmem:
print >>sys.stderr, "Memory size must be less or equal to maxmem"
qubes_host = QubesHost()
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
vm.memory = new_memory
@ -127,7 +133,7 @@ def set_maxmem(vms, vm, args):
return False
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
@ -278,7 +284,10 @@ def set_drive(vms, vm, args):
print >> sys.stderr, "Missing new drive content (file/device)!"
return False
vm.drive = args[0]
if args[0] == '' or args[0].lower() == 'none':
vm.drive = None
else:
vm.drive = args[0]
return True
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()))
return True
def set_include_in_backups(vms, vm, args):
def set_debug(vms, vm, args):
if len (args) != 1:
print >> sys.stderr, "Missing value (True/False)!"
print >> sys.stderr, "Missing value (True/False or on/off)!"
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
properties = {
@ -311,6 +337,8 @@ properties = {
"name": set_name,
"drive": set_drive,
"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,
passio = options.passio, localcmd = options.localcmd)
except QubesException as err:
if options.tray:
tray_notify_error(str(err))
print >> sys.stderr, "ERROR: %s" % str(err)
exit(1)

View File

@ -26,17 +26,26 @@ from optparse import OptionParser
import subprocess
import os
import sys
import dbus
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():
usage = "usage: %prog [options] <vm-name>"
parser = OptionParser (usage)
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,
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,
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,
@ -47,12 +56,18 @@ def main():
help="Do actions necessary when preparing DVM image")
parser.add_option ("--custom-config", action="store", dest="custom_config", default=None,
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 ()
if (len (args) != 1):
parser.error ("You must specify VM name!")
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.lock_db_for_reading()
qvm_collection.load()
@ -71,7 +86,7 @@ def main():
options.drive = 'hd:' + options.drive_hd
if options.drive_cdrom:
options.drive = 'cdrom:' + options.drive_hd
options.drive = 'cdrom:' + options.drive_cdrom
if options.drive:
if hasattr(vm, 'drive'):
@ -83,11 +98,23 @@ def main():
if options.custom_config:
vm.conf_file = options.custom_config
if options.debug:
vm.debug = True
try:
vm.verify_files()
xid = vm.start(debug_console=options.debug_console, verbose=options.verbose, preparing_dvm=options.preparing_dvm, start_guid=not options.noguid)
except (IOError, OSError, QubesException) as err:
print >> sys.stderr, "ERROR: {0}".format(err)
xid = vm.start(verbose=options.verbose, preparing_dvm=options.preparing_dvm, start_guid=not options.noguid)
except (IOError, OSError, QubesException, MemoryError) as err:
if options.tray:
tray_notify_error(str(err))
else:
print >> sys.stderr, "ERROR: {0}".format(err)
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()