From 406d233b6b4454e0419c86e2a77adde62d428cd0 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 19 Jul 2012 14:43:24 +0200 Subject: [PATCH 1/8] dom0/core: disable dynamic memory when VM have PCI devices assigned --- dom0/qvm-core/qubes.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index d66867c3..62ec10d6 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -340,6 +340,10 @@ class QubesVm(object): if 'meminfo-writer' not in self.services: self.services['meminfo-writer'] = not (len(self.pcidevs) > 0) + # Additionally force meminfo-writer disabled when VM have PCI devices + if len(self.pcidevs) > 0: + self.services['meminfo-writer'] = False + # Some additional checks for template based VM if self.template is not None: if not self.template.is_template(): From 7071bf62bc9b3d00488f18cc3f3a0eb39fba3477 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 20 Jul 2012 13:06:26 +0200 Subject: [PATCH 2/8] dom0/core: use generic run() to wait for qubes-session Especially use 'ignore_stderr' feature. --- dom0/qvm-core/qubes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 62ec10d6..4ed85159 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1415,7 +1415,7 @@ class QubesVm(object): if verbose: print >> sys.stderr, "--> Waiting for qubes-session..." - subprocess.call([qrexec_client_path, "-d", str(xid), "user:echo $$ >> /tmp/qubes-session-waiter; [ ! -f /tmp/qubes-session-env ] && exec sleep 365d"]) + self.run('echo $$ >> /tmp/qubes-session-waiter; [ ! -f /tmp/qubes-session-env ] && exec sleep 365d', ignore_stderr=True, gui=False, wait=True) retcode = subprocess.call([qubes_clipd_path]) if retcode != 0: From f98bf1d570af917cad8bbbad59f69144e4b5f449 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 18 Jul 2012 12:46:36 +0200 Subject: [PATCH 3/8] dom0: fix dirs permissions after xen upgrade --- dom0/init.d/qubes_core | 20 +------------------- rpm_spec/core-dom0.spec | 3 +++ 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/dom0/init.d/qubes_core b/dom0/init.d/qubes_core index 27399dd9..561ca038 100755 --- a/dom0/init.d/qubes_core +++ b/dom0/init.d/qubes_core @@ -21,25 +21,7 @@ start() { echo -n $"Executing Qubes Core scripts:" modprobe evtchn 2> /dev/null || modprobe xen-evtchn - chgrp qubes /etc/xen - chmod 710 /etc/xen - chgrp qubes /var/run/xenstored/* - chmod 660 /var/run/xenstored/* - chgrp qubes /var/lib/xen - chmod 770 /var/lib/xen - chgrp qubes /var/log/xen - chmod 770 /var/log/xen - chgrp qubes /proc/xen/privcmd - chmod 660 /proc/xen/privcmd - chgrp qubes /dev/xen/evtchn - chmod 660 /dev/xen/evtchn - 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 + /usr/lib/qubes/fix_dir_perms.sh xenstore-write /local/domain/0/name dom0 DOM0_MAXMEM=`/usr/sbin/xl info | grep total_memory | awk '{ print $3 }'` diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index fa40e4c1..6161e21c 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -115,6 +115,7 @@ cp ../misc/block_add_change $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../misc/block_remove $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../misc/block_cleanup $RPM_BUILD_ROOT/usr/lib/qubes/ cp aux-tools/block_cleaner_daemon.py $RPM_BUILD_ROOT/usr/lib/qubes/ +cp aux-tools/fix_dir_perms.sh $RPM_BUILD_ROOT/usr/lib/qubes/ mkdir -p $RPM_BUILD_ROOT/etc/qubes_rpc/policy cp ../qubes_rpc/qubes.Filecopy.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.Filecopy @@ -295,6 +296,7 @@ fi %triggerin -- xen-runtime sed -i 's/\/block /\/block.qubes /' /etc/udev/rules.d/xen-backend.rules +/usr/lib/qubes/fix_dir_perms.sh %triggerin -- xorg-x11-drv-vmmouse mv -f /lib/udev/rules.d/69-xorg-vmmouse.rules /var/lib/qubes/removed-udev-scripts/ 2> /dev/null || : @@ -359,6 +361,7 @@ fi /usr/lib/qubes/block_remove /usr/lib/qubes/block_cleanup /usr/lib/qubes/block_cleaner_daemon.py* +/usr/lib/qubes/fix_dir_perms.sh %attr(4750,root,qubes) /usr/lib/qubes/qfile-dom0-unpacker %attr(770,root,qubes) %dir /var/lib/qubes %attr(770,root,qubes) %dir /var/lib/qubes/vm-templates From d5dbbd41cbf95b8535a66de2ab631f22b53dcd40 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 18 Jul 2012 18:10:08 +0200 Subject: [PATCH 4/8] dom0/qvm-tools: add missing imports --- dom0/qvm-tools/qvm-add-appvm | 1 + dom0/qvm-tools/qvm-add-template | 1 + dom0/qvm-tools/qvm-clone | 1 + dom0/qvm-tools/qvm-firewall | 1 + 4 files changed, 4 insertions(+) diff --git a/dom0/qvm-tools/qvm-add-appvm b/dom0/qvm-tools/qvm-add-appvm index f30c1afd..82f58249 100755 --- a/dom0/qvm-tools/qvm-add-appvm +++ b/dom0/qvm-tools/qvm-add-appvm @@ -24,6 +24,7 @@ from qubes.qubes import QubesVmCollection from qubes.qubes import QubesException from optparse import OptionParser; import sys +import os def main(): usage = "usage: %prog [options] \n\n"\ diff --git a/dom0/qvm-tools/qvm-add-template b/dom0/qvm-tools/qvm-add-template index c1fbe67d..5a407803 100755 --- a/dom0/qvm-tools/qvm-add-template +++ b/dom0/qvm-tools/qvm-add-template @@ -24,6 +24,7 @@ from qubes.qubes import QubesVmCollection from qubes.qubes import QubesException from optparse import OptionParser; import sys +import os def main(): usage = "usage: %prog [options] \n"\ diff --git a/dom0/qvm-tools/qvm-clone b/dom0/qvm-tools/qvm-clone index e50e90b9..02d24fe9 100755 --- a/dom0/qvm-tools/qvm-clone +++ b/dom0/qvm-tools/qvm-clone @@ -25,6 +25,7 @@ from qubes.qubes import QubesAppVm, QubesTemplateVm, QubesHVm from qubes.qubes import QubesException from optparse import OptionParser; import sys +import os def main(): usage = "usage: %prog [options] \n"\ diff --git a/dom0/qvm-tools/qvm-firewall b/dom0/qvm-tools/qvm-firewall index 9d434cda..d1439da5 100755 --- a/dom0/qvm-tools/qvm-firewall +++ b/dom0/qvm-tools/qvm-firewall @@ -25,6 +25,7 @@ from optparse import OptionParser; import subprocess import sys import re +import os services = list() From 273032bfae86685a6aeb97c6b4fc7489ba1d2dff Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 18 Jul 2012 22:22:52 +0200 Subject: [PATCH 5/8] dom0: add missing file --- dom0/aux-tools/fix_dir_perms.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 dom0/aux-tools/fix_dir_perms.sh diff --git a/dom0/aux-tools/fix_dir_perms.sh b/dom0/aux-tools/fix_dir_perms.sh new file mode 100755 index 00000000..82b3468f --- /dev/null +++ b/dom0/aux-tools/fix_dir_perms.sh @@ -0,0 +1,20 @@ +#!/bin/sh +chgrp qubes /etc/xen +chmod 710 /etc/xen +chgrp qubes /var/run/xenstored/* +chmod 660 /var/run/xenstored/* +chgrp qubes /var/lib/xen +chmod 770 /var/lib/xen +chgrp qubes /var/log/xen +chmod 770 /var/log/xen +chgrp qubes /proc/xen/privcmd +chmod 660 /proc/xen/privcmd +chgrp qubes /dev/xen/evtchn +chmod 660 /dev/xen/evtchn +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 From c2d20e59d04dbd5cb11bf7412368a733cb34a363 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 20 Jul 2012 16:32:17 +0200 Subject: [PATCH 6/8] dom0/qmemman: fork into background after daemon initialization (#635) Parse config and setup socket before fork. --- dom0/init.d/qubes_core | 2 +- dom0/qmemman/qmemman_server.py | 37 ++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/dom0/init.d/qubes_core b/dom0/init.d/qubes_core index 561ca038..c932b19b 100755 --- a/dom0/init.d/qubes_core +++ b/dom0/init.d/qubes_core @@ -30,7 +30,7 @@ start() xl sched-credit -d 0 -w 512 cp /var/lib/qubes/qubes.xml /var/lib/qubes/backup/qubes-$(date +%F-%T).xml - /usr/lib/qubes/qmemman_daemon.py >/var/log/qubes/qmemman.log 2>/var/log/qubes/qmemman.errs & + /usr/lib/qubes/qmemman_daemon.py MEM_CHANGE_THRESHOLD_KB=30000 MEMINFO_DELAY_USEC=100000 /usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC & diff --git a/dom0/qmemman/qmemman_server.py b/dom0/qmemman/qmemman_server.py index 515b5fdd..a744340b 100755 --- a/dom0/qmemman/qmemman_server.py +++ b/dom0/qmemman/qmemman_server.py @@ -12,6 +12,8 @@ from optparse import OptionParser from qubesutils import parse_size config_path = '/etc/qubes/qmemman.conf' +SOCK_PATH='/var/run/qubes/qmemman.sock' +LOG_PATH='/var/log/qubes/qmemman.log' system_state = SystemState() global_lock = thread.allocate_lock() @@ -105,15 +107,7 @@ class QMemmanReqHandler(SocketServer.BaseRequestHandler): self.request.send(resp) -def start_server(): - SOCK_PATH='/var/run/qubes/qmemman.sock' - try: - os.unlink(SOCK_PATH) - except: - pass - os.umask(0) - server = SocketServer.UnixStreamServer(SOCK_PATH, QMemmanReqHandler) - os.umask(077) +def start_server(server): server.serve_forever() class QMemmanServer: @@ -124,6 +118,19 @@ class QMemmanServer: parser.add_option("-c", "--config", action="store", dest="config", default=config_path) (options, args) = parser.parse_args() + logfd = os.open(LOG_PATH, os.O_WRONLY|os.O_APPEND|os.O_CREAT, 0644) + if logfd < 0: + print sys.stderr, "ERROR: Failed to open log file (%s)" % LOG_PATH + exit(1) + # reinitialize python stdout/err + sys.stdout.flush() + sys.stderr.flush() + os.dup2(logfd, 1) + os.dup2(logfd, 2) + os.close(logfd) + devnull = os.open('/dev/null', os.O_RDONLY) + os.dup2(devnull, 0) + config = SafeConfigParser({ 'vm-min-mem': str(qmemman_algo.MIN_PREFMEM), 'dom0-mem-boost': str(qmemman_algo.DOM0_MEM_BOOST), @@ -137,5 +144,13 @@ class QMemmanServer: print "values: %s, %s, %s" % (str(qmemman_algo.MIN_PREFMEM), str(qmemman_algo.DOM0_MEM_BOOST), str(qmemman_algo.CACHE_FACTOR)) - thread.start_new_thread(start_server, tuple([])) - XS_Watcher().watch_loop() + try: + os.unlink(SOCK_PATH) + except: + pass + os.umask(0) + server = SocketServer.UnixStreamServer(SOCK_PATH, QMemmanReqHandler) + os.umask(077) + if os.fork() == 0: + thread.start_new_thread(start_server, tuple([server])) + XS_Watcher().watch_loop() From 59a1fb96dbef9a91638d13c4eb0f93270c35535f Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 20 Jul 2012 16:41:26 +0200 Subject: [PATCH 7/8] dom0/meminfo-writer: fork into background after first info sent to qmemman (#635) --- dom0/init.d/qubes_core | 2 +- misc/meminfo-writer.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dom0/init.d/qubes_core b/dom0/init.d/qubes_core index c932b19b..3a6b4ed9 100755 --- a/dom0/init.d/qubes_core +++ b/dom0/init.d/qubes_core @@ -33,7 +33,7 @@ start() /usr/lib/qubes/qmemman_daemon.py MEM_CHANGE_THRESHOLD_KB=30000 MEMINFO_DELAY_USEC=100000 - /usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC & + /usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC /usr/lib/qubes/block_cleaner_daemon.py > /var/log/qubes/block_cleaner.log 2>&1 & diff --git a/misc/meminfo-writer.c b/misc/meminfo-writer.c index c9e10594..f3563b14 100644 --- a/misc/meminfo-writer.c +++ b/misc/meminfo-writer.c @@ -154,6 +154,17 @@ int main(int argc, char **argv) perror("xs_domain_open"); exit(1); } + if (argc == 3) { + /* if not waiting for signal, fork after first info written to xenstore */ + n = pread(fd, buf, sizeof(buf), 0); + buf[n] = 0; + meminfo_data = parse(buf); + if (meminfo_data) + send_to_qmemman(xs, meminfo_data); + if (fork() > 0) + exit(0); + } + for (;;) { n = pread(fd, buf, sizeof(buf), 0); buf[n] = 0; From abefe78197269bcf84829e27fae8d8762e46a5ff Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 20 Jul 2012 16:49:19 +0200 Subject: [PATCH 8/8] dom0/core: improve diagnostics of qmemman errors --- dom0/qvm-core/qubes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 4ed85159..5a3246d5 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1458,7 +1458,11 @@ class QubesVm(object): mem_required = int(self.memory) * 1024 * 1024 qmemman_client = QMemmanClient() - if not qmemman_client.request_memory(mem_required): + try: + got_memory = qmemman_client.request_memory(mem_required) + except IOError as e: + raise IOError("ERROR: Failed to connect to qmemman: %s" % str(e)) + if not got_memory: qmemman_client.close() raise MemoryError ("ERROR: insufficient memory to start VM '%s'" % self.name)