From 212fd13957fff8eac1d39dc610cbda4575e58826 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 30 Mar 2011 22:29:57 +0200 Subject: [PATCH 1/4] Stop only NM on suspend. (#146) Also remove ip_forward setting from sysctl, so NM will not reset it on restart --- dom0/pm-utils/01qubes-suspend-netvm | 27 +++++++++++++++++---------- rpm_spec/core-netvm.spec | 3 +++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/dom0/pm-utils/01qubes-suspend-netvm b/dom0/pm-utils/01qubes-suspend-netvm index a0e2f447..cf635ae6 100755 --- a/dom0/pm-utils/01qubes-suspend-netvm +++ b/dom0/pm-utils/01qubes-suspend-netvm @@ -2,24 +2,31 @@ . "${PM_FUNCTIONS}" +get_running_netvms() { + # Actually get running VMs with PCI devices attached + RUNNING_VMS=`xm list --state=Running | tail -n +3 | cut -f 1 -d " "` + RUNNING_NETVMS="" + for VM in $RUNNING_VMS; do + if [ -n "`xm pci-list $VM`" ]; then + echo "$VM" + fi + done +} + suspend_net() { - NETVM=$(qvm-get-default-netvm) - if [ "X"$NETVM = "X""dom0" -o "X"$NETVM = "X" -o "X"$NETVM = "X""none"] ; then - exit 0 - fi - qvm-run -u root --pass_io $NETVM "source /usr/lib64/pm-utils/pm-functions; run_hooks sleep suspend suspend" + for VM in `get_running_netvms`; do + qvm-run -u root --pass_io $VM "service NetworkManager stop" + done # Ignore exit status from netvm... return 0 } resume_net() { - NETVM=$(qvm-get-default-netvm) - if [ "X"$NETVM = "X""dom0" -o "X"$NETVM = "X" -o "X"$NETVM = "X""none"] ; then - exit 0 - fi - qvm-run -u root --pass_io $NETVM "source /usr/lib64/pm-utils/pm-functions; run_hooks sleep resume suspend reverse" + for VM in `get_running_netvms`; do + qvm-run -u root --pass_io $VM "service NetworkManager start" + done # Ignore exit status from netvm... return 0 } diff --git a/rpm_spec/core-netvm.spec b/rpm_spec/core-netvm.spec index b4f1eb34..d09139b0 100644 --- a/rpm_spec/core-netvm.spec +++ b/rpm_spec/core-netvm.spec @@ -73,6 +73,9 @@ cp ../common/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts chkconfig --add qubes_core_netvm || echo "WARNING: Cannot add service qubes_core!" chkconfig qubes_core_netvm on || echo "WARNING: Cannot enable service qubes_core!" +# Remove ip_forward setting from sysctl, so NM will not reset it +sed 's/^net.ipv4.ip_forward.*/#\0/' -i /etc/sysctl.conf + %preun if [ "$1" = 0 ] ; then # no more packages left From 01ef2aff9ed26389e88f9c1a86a74c7c38bfd5ee Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 31 Mar 2011 00:44:58 +0200 Subject: [PATCH 2/4] Wait for device size change, before resize2fs (#5) --- dom0/qvm-tools/qvm-grow-private | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom0/qvm-tools/qvm-grow-private b/dom0/qvm-tools/qvm-grow-private index e14802b6..7ca50d2e 100755 --- a/dom0/qvm-tools/qvm-grow-private +++ b/dom0/qvm-tools/qvm-grow-private @@ -99,7 +99,7 @@ def main(): retcode = subprocess.check_call(["losetup", "--set-capacity", loop_dev]) retcode = subprocess.check_call([qvm_run_path, "-uroot", vmname, - "resize2fs /dev/xvdb" ]) + "while [ \"`blockdev --getsize64 /dev/xvdb`\" -lt {0} ]; do sleep 0.2; done; resize2fs /dev/xvdb".format(size_bytes) ]) else: retcode = subprocess.check_call(["resize2fs", "-f", vm.private_img]) From 6273c42faff0cd749dee49a6bbce5cea5eb5fcf4 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 31 Mar 2011 01:58:45 +0200 Subject: [PATCH 3/4] Recursive stop VMs, when stopping NetVM (#172) Dependency resolving in qvm-core, recursive stopping only in qvm-run for now. --- dom0/init.d/qubes_netvm | 17 +++++++++++++++-- dom0/qvm-core/qubes.py | 19 +++++++++++++++++++ dom0/qvm-tools/qvm-run | 5 +++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/dom0/init.d/qubes_netvm b/dom0/init.d/qubes_netvm index bfc0f0c6..2d27fdd8 100755 --- a/dom0/init.d/qubes_netvm +++ b/dom0/init.d/qubes_netvm @@ -20,6 +20,17 @@ NETVM=$(qvm-get-default-netvm) +get_running_netvms() { + # Actually get running VMs with PCI devices attached + RUNNING_VMS=`xm list --state=Running | tail -n +3 | cut -f 1 -d " "` + RUNNING_NETVMS="" + for VM in $RUNNING_VMS; do + if [ -n "`xm pci-list $VM`" ]; then + echo "$VM" + fi + done +} + start() { if [ x$NETVM = x ] ; then @@ -59,8 +70,10 @@ stop() echo -n $"Stopping Qubes networking in Dom0:" else - echo -n $"Stopping default NetVM:" - qvm-run -q --shutdown --wait $NETVM + echo -n $"Stopping NetVMs:" + for VM in `get_running_netvms`; do + qvm-run -q --shutdown --wait $VM + done fi rm -f /var/lock/subsys/qubes_netvm diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 11fc1870..8ce6897b 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1773,6 +1773,25 @@ class QubesVmCollection(dict): if (vm.is_appvm() and vm.template_vm.qid == template_qid)]) return vms + def get_vms_connected_to(self, netvm_qid): + new_vms = [ netvm_qid ] + dependend_vms_qid = [] + + # Dependency resolving only makes sense on NetVM (or derivative) + if not self[netvm_qid].is_netvm(): + return set([]) + + while len(new_vms) > 0: + cur_vm = new_vms.pop() + for vm in self.values(): + if vm.netvm_vm and vm.netvm_vm.qid == cur_vm and vm.qid not in dependend_vms_qid: + dependend_vms_qid.append(vm.qid) + if vm.is_netvm(): + new_vms.append(vm.qid) + + vms = [vm for vm in self.values() if vm.qid in dependend_vms_qid] + return vms + def verify_new_vm(self, new_vm): # Verify that qid is unique diff --git a/dom0/qvm-tools/qvm-run b/dom0/qvm-tools/qvm-run index 3f801e2c..fe2ca357 100755 --- a/dom0/qvm-tools/qvm-run +++ b/dom0/qvm-tools/qvm-run @@ -219,6 +219,11 @@ def main(): print "A VM with the name '{0}' does not exist in the system!".format(vmname) exit(1) vms_list.append(vm) + + # If stopping NetVM - stop connected VMs too + if options.shutdown and vm.is_netvm(): + vms_list += [vm for vm in qvm_collection.get_vms_connected_to(vm.qid) if vm.is_running()] + vms_list.reverse() if takes_cmd_argument: cmd = "{user}:{cmd}".format(user=options.user, cmd=cmdstr) From ece8cfa9f0292197a6fb0c280439c24852665bd6 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 31 Mar 2011 02:40:45 +0200 Subject: [PATCH 4/4] Show output from resize2fs, when running it in AppVM (#5) --- dom0/qvm-tools/qvm-grow-private | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom0/qvm-tools/qvm-grow-private b/dom0/qvm-tools/qvm-grow-private index 7ca50d2e..57c61060 100755 --- a/dom0/qvm-tools/qvm-grow-private +++ b/dom0/qvm-tools/qvm-grow-private @@ -98,7 +98,7 @@ def main(): # resize loop device retcode = subprocess.check_call(["losetup", "--set-capacity", loop_dev]) - retcode = subprocess.check_call([qvm_run_path, "-uroot", vmname, + retcode = subprocess.check_call([qvm_run_path, "-uroot", "--pass_io", vmname, "while [ \"`blockdev --getsize64 /dev/xvdb`\" -lt {0} ]; do sleep 0.2; done; resize2fs /dev/xvdb".format(size_bytes) ]) else: retcode = subprocess.check_call(["resize2fs", "-f", vm.private_img])