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/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/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index cfd8c02d..59f3a416 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-grow-private b/dom0/qvm-tools/qvm-grow-private index e14802b6..57c61060 100755 --- a/dom0/qvm-tools/qvm-grow-private +++ b/dom0/qvm-tools/qvm-grow-private @@ -98,8 +98,8 @@ def main(): # resize loop device retcode = subprocess.check_call(["losetup", "--set-capacity", loop_dev]) - retcode = subprocess.check_call([qvm_run_path, "-uroot", vmname, - "resize2fs /dev/xvdb" ]) + 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]) 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) diff --git a/rpm_spec/core-netvm.spec b/rpm_spec/core-netvm.spec index 9ab815f9..a4c966b9 100644 --- a/rpm_spec/core-netvm.spec +++ b/rpm_spec/core-netvm.spec @@ -79,6 +79,9 @@ fi 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