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)