From a96d49a40afdc9777a85322765bf0f3da4a8e3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:33:04 +0200 Subject: [PATCH 001/225] core: properly redirect qrexec output to /dev/null when necessary /dev/null was opened in read-only mode ("rw" is invalid value), so qrexec couldn't write there. --- core-modules/000QubesVm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-modules/000QubesVm.py b/core-modules/000QubesVm.py index 18f8813b..c793d932 100644 --- a/core-modules/000QubesVm.py +++ b/core-modules/000QubesVm.py @@ -1527,7 +1527,7 @@ class QubesVm(object): call_kwargs = {} if ignore_stderr or not passio: - null = open("/dev/null", "rw") + null = open("/dev/null", "w+") call_kwargs['stderr'] = null if not passio: call_kwargs['stdin'] = null From 522bfc427ada22498539baa579d85992c6346f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:35:09 +0200 Subject: [PATCH 002/225] core: fix template-based HVM disk handling We use only one device-mapper layer for HVMs, and this isn't the same as for PV - it is that one, which PV does in initramfs. Device-mapper layers summary for template-based VMs: PV: root.img+root-cow.img (dom0) -> xvda, xvda+volatile.img (VM) HVM: root.img+volatile.img (dom0) --- core-modules/01QubesHVm.py | 43 ++---------------------------------- core/storage/xen.py | 45 +++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/core-modules/01QubesHVm.py b/core-modules/01QubesHVm.py index 08fd0118..12e87df6 100644 --- a/core-modules/01QubesHVm.py +++ b/core-modules/01QubesHVm.py @@ -96,7 +96,7 @@ class QubesHVm(QubesVm): (not 'xml_element' in kwargs or kwargs['xml_element'].get('guiagent_installed') is None): self.services['meminfo-writer'] = False - self.storage.volatile_img = None + self.storage.rootcow_img = None @property def type(self): @@ -233,9 +233,7 @@ class QubesHVm(QubesVm): if self.is_running(): raise NotImplementedError("Online resize of HVM's private.img not implemented, shutdown the VM first") - f_private = open (self.private_img, "a+b") - f_private.truncate (size) - f_private.close () + self.storage.resize_private_img(size) def resize_root_img(self, size): if self.template: @@ -255,14 +253,6 @@ class QubesHVm(QubesVm): f_root.truncate (size) f_root.close () - def get_rootdev(self, source_template=None): - if self.template: - return "'script:snapshot:{template_root}:{volatile},xvda,w',".format( - template_root=self.template.root_img, - volatile=self.volatile_img) - else: - return "'script:file:{root_img},xvda,w',".format(root_img=self.root_img) - def get_config_params(self): params = super(QubesHVm, self).get_config_params() @@ -295,34 +285,6 @@ class QubesHVm(QubesVm): return True - def reset_volatile_storage(self, **kwargs): - assert not self.is_running(), "Attempt to clean volatile image of running VM!" - - source_template = kwargs.get("source_template", self.template) - - if source_template is None: - # Nothing to do on non-template based VM - return - - if os.path.exists (self.volatile_img): - if self.debug: - if os.path.getmtime(self.template.root_img) > os.path.getmtime(self.volatile_img): - if kwargs.get("verbose", False): - print >>sys.stderr, "--> WARNING: template have changed, resetting root.img" - else: - if kwargs.get("verbose", False): - print >>sys.stderr, "--> Debug mode: not resetting root.img" - print >>sys.stderr, "--> Debug mode: if you want to force root.img reset, either update template VM, or remove volatile.img file" - return - os.remove (self.volatile_img) - - f_volatile = open (self.volatile_img, "w") - f_root = open (self.template.root_img, "r") - f_root.seek(0, os.SEEK_END) - f_volatile.truncate (f_root.tell()) # make empty sparse file of the same size as root.img - f_volatile.close () - f_root.close() - @property def vif(self): if self.xid < 0: @@ -463,7 +425,6 @@ class QubesHVm(QubesVm): guid_pid = open(guid_pidfile).read().strip() os.kill(int(guid_pid), 15) - def suspend(self): if dry_run: return diff --git a/core/storage/xen.py b/core/storage/xen.py index e026b6b3..5daa3bbd 100644 --- a/core/storage/xen.py +++ b/core/storage/xen.py @@ -76,7 +76,18 @@ class QubesXenVmStorage(QubesVmStorage): "{dir}/root.img:{dir}/root-cow.img".format( dir=self.vmdir), "block-origin", self.root_dev, True) + elif self.vm.template and not self.vm.template.storage.rootcow_img: + # HVM template-based VM - template doesn't have own + # root-cow.img, only one device-mapper layer + return self._format_disk_dev( + "{tpldir}/root.img:{vmdir}/volatile.img".format( + tpldir=self.vm.template.dir_path, + vmdir=self.vmdir), + "block-snapshot", self.root_dev, True) elif self.vm.template: + # any other template-based VM - two device-mapper layers: one + # in dom0 (here) from root+root-cow, and another one from + # this+volatile.img return self._format_disk_dev( "{dir}/root.img:{dir}/root-cow.img".format( dir=self.vm.template.dir_path), @@ -170,7 +181,8 @@ class QubesXenVmStorage(QubesVmStorage): def commit_template_changes(self): assert self.vm.is_template() - # TODO: move rootcow_img to this class; the same for vm.is_outdated() + if not self.rootcow_img: + return if os.path.exists (self.rootcow_img): os.rename (self.rootcow_img, self.rootcow_img + '.old') @@ -183,3 +195,34 @@ class QubesXenVmStorage(QubesVmStorage): f_root.close() os.umask(old_umask) + def reset_volatile_storage(self, verbose = False, source_template = None): + if source_template is None: + source_template = self.vm.template + + if source_template is not None: + # template-based VM with only one device-mapper layer - + # volatile.img used as upper layer on root.img, no root-cow.img + # intermediate layer + if not source_template.storage.rootcow_img: + if os.path.exists(self.volatile_img): + if self.vm.debug: + if os.path.getmtime(source_template.storage.root_img)\ + > os.path.getmtime(self.volatile_img): + if verbose: + print >>sys.stderr, "--> WARNING: template have changed, resetting root.img" + else: + if verbose: + print >>sys.stderr, "--> Debug mode: not resetting root.img" + print >>sys.stderr, "--> Debug mode: if you want to force root.img reset, either update template VM, or remove volatile.img file" + return + os.remove(self.volatile_img) + + f_volatile = open(self.volatile_img, "w") + f_root = open(source_template.storage.root_img, "r") + f_root.seek(0, os.SEEK_END) + f_volatile.truncate(f_root.tell()) # make empty sparse file of the same size as root.img + f_volatile.close() + f_root.close() + return + super(QubesXenVmStorage, self).reset_volatile_storage( + verbose=verbose, source_template=source_template) From 402d1b9a3dc9f2ace54db3aa2ecdf3c81b7f0d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:40:48 +0200 Subject: [PATCH 003/225] indentation fix --- core-modules/01QubesHVm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-modules/01QubesHVm.py b/core-modules/01QubesHVm.py index 12e87df6..16e33376 100644 --- a/core-modules/01QubesHVm.py +++ b/core-modules/01QubesHVm.py @@ -262,8 +262,8 @@ class QubesHVm(QubesVm): params['volatiledev'] = '' if self.timezone.lower() == 'localtime': - params['time_basis'] = 'localtime' - params['timeoffset'] = '0' + params['time_basis'] = 'localtime' + params['timeoffset'] = '0' elif self.timezone.isdigit(): params['time_basis'] = 'UTC' params['timeoffset'] = self.timezone From d9c299074701f93766da5cd4ee1b64064d53203b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:41:09 +0200 Subject: [PATCH 004/225] core: fix creation of private.img at VM startup This code is used when VM is migrated from older system, where HVM didn't have private.img. --- core/storage/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/storage/__init__.py b/core/storage/__init__.py index a67a921d..41f3e73f 100644 --- a/core/storage/__init__.py +++ b/core/storage/__init__.py @@ -198,4 +198,4 @@ class QubesVmStorage(object): if self.private_img and not os.path.exists (self.private_img): print >>sys.stderr, "WARNING: Creating empty VM private image file: {0}".\ format(self.private_img) - self.storage.create_on_disk_private_img(verbose=False) + self.create_on_disk_private_img(verbose=False) From 310ba9f1dfd0e70eeda01e6dcf740403bd722a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:42:44 +0200 Subject: [PATCH 005/225] block: do not treat disks of not running VMs as used There are legitimate use cases when one want to attach disk of one VM to some other. Do not try to detach the disk from powered down VM in such case. --- core/qubesutils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/qubesutils.py b/core/qubesutils.py index 130faf8a..aba05a3c 100644 --- a/core/qubesutils.py +++ b/core/qubesutils.py @@ -337,6 +337,8 @@ def block_check_attached(qvmc, device): if vm.qid == 0: # Connecting devices to dom0 not supported continue + if not vm.is_running(): + continue try: libvirt_domain = vm.libvirt_domain if libvirt_domain: From 677a79b213ddd39729e0a282fcbff7f5cb157269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 1 Jul 2015 04:44:41 +0200 Subject: [PATCH 006/225] hvm: change default graphics to std vga ('xen') The resulting qemu option is -std-vga. This apparently this is much better handled by many OSes. --- vm-config/xen-vm-template-hvm.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm-config/xen-vm-template-hvm.xml b/vm-config/xen-vm-template-hvm.xml index ba2dc862..13431b33 100644 --- a/vm-config/xen-vm-template-hvm.xml +++ b/vm-config/xen-vm-template-hvm.xml @@ -29,7 +29,9 @@ {netdev} {pcidevs} -