Browse Source

dispvm: use try/finally to make sure that qubes.xml is unlocked

Even in case of some exception (in which case theoretically it should be
unlocked at qfile-daemon-dvm exit, but the script may wait for
something).

QubesOS/qubes-issues#1636
Marek Marczykowski-Górecki 8 years ago
parent
commit
5546d679c0
1 changed files with 59 additions and 60 deletions
  1. 59 60
      dispvm/qfile-daemon-dvm

+ 59 - 60
dispvm/qfile-daemon-dvm

@@ -51,68 +51,67 @@ class QfileDaemonDvm:
 
         qvm_collection = QubesVmCollection()
         qvm_collection.lock_db_for_writing()
+        try:
 
-        tar_process = subprocess.Popen(
-            ['bsdtar', '-C', current_savefile_vmdir,
-             '-xSUf', os.path.join(current_savefile_vmdir, 'saved-cows.tar')])
-
-        qvm_collection.load()
-        print >>sys.stderr, "time=%s, collection loaded" % (str(time.time()))
-
-        vm = qvm_collection.get_vm_by_name(self.name)
-        if vm is None:
-            sys.stderr.write('Domain ' + self.name + ' does not exist ?')
+            tar_process = subprocess.Popen(
+                ['bsdtar', '-C', current_savefile_vmdir,
+                 '-xSUf', os.path.join(current_savefile_vmdir, 'saved-cows.tar')])
+
+            qvm_collection.load()
+            print >>sys.stderr, "time=%s, collection loaded" % (str(time.time()))
+
+            vm = qvm_collection.get_vm_by_name(self.name)
+            if vm is None:
+                sys.stderr.write('Domain ' + self.name + ' does not exist ?')
+                return None
+            label = vm.label
+            if len(sys.argv) > 4 and len(sys.argv[4]) > 0:
+                assert sys.argv[4] in QubesDispVmLabels.keys(), "Invalid label"
+                label = QubesDispVmLabels[sys.argv[4]]
+            disp_templ = self.get_disp_templ()
+            vm_disptempl = qvm_collection.get_vm_by_name(disp_templ)
+            if vm_disptempl is None:
+                sys.stderr.write('Domain ' + disp_templ + ' does not exist ?')
+                return None
+            dispvm = qvm_collection.add_new_vm('QubesDisposableVm',
+                                               disp_template=vm_disptempl,
+                                               label=label)
+            print >>sys.stderr, "time=%s, VM created" % (str(time.time()))
+            # By default inherit firewall rules from calling VM
+            disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % dispvm.name
+            dispvm.firewall_conf = disp_firewall_conf
+            if os.path.exists(vm.firewall_conf):
+                shutil.copy(vm.firewall_conf, disp_firewall_conf)
+            elif vm.qid == 0 and os.path.exists(vm_disptempl.firewall_conf):
+                # for DispVM called from dom0, copy use rules from DispVM template
+                shutil.copy(vm_disptempl.firewall_conf, disp_firewall_conf)
+            if len(sys.argv) > 5 and len(sys.argv[5]) > 0:
+                assert os.path.exists(sys.argv[5]), "Invalid firewall.conf location"
+                dispvm.firewall_conf = sys.argv[5]
+            if vm.qid != 0:
+                dispvm.uses_default_netvm = False
+                # netvm can be changed before restore,
+                # but cannot be enabled/disabled
+                if (dispvm.netvm is None) == (vm.dispvm_netvm is None):
+                    dispvm.netvm = vm.dispvm_netvm
+            # Wait for tar to finish
+            if tar_process.wait() != 0:
+                sys.stderr.write('Failed to unpack saved-cows.tar')
+                return None
+            print >>sys.stderr, "time=%s, VM starting" % (str(time.time()))
+            try:
+                dispvm.start()
+            except (MemoryError, QubesException) as e:
+                tray_notify_error(str(e))
+                raise
+            if vm.qid != 0:
+                # if need to enable/disable netvm, do it while DispVM is alive
+                if (dispvm.netvm is None) != (vm.dispvm_netvm is None):
+                    dispvm.netvm = vm.dispvm_netvm
+            print >>sys.stderr, "time=%s, VM started" % (str(time.time()))
+            qvm_collection.save()
+        finally:
             qvm_collection.unlock_db()
-            return None
-        label = vm.label
-        if len(sys.argv) > 4 and len(sys.argv[4]) > 0:
-            assert sys.argv[4] in QubesDispVmLabels.keys(), "Invalid label"
-            label = QubesDispVmLabels[sys.argv[4]]
-        disp_templ = self.get_disp_templ()
-        vm_disptempl = qvm_collection.get_vm_by_name(disp_templ)
-        if vm_disptempl is None:
-            sys.stderr.write('Domain ' + disp_templ + ' does not exist ?')
-            qvm_collection.unlock_db()
-            return None
-        dispvm = qvm_collection.add_new_vm('QubesDisposableVm',
-                                           disp_template=vm_disptempl,
-                                           label=label)
-        print >>sys.stderr, "time=%s, VM created" % (str(time.time()))
-        # By default inherit firewall rules from calling VM
-        disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % dispvm.name
-        dispvm.firewall_conf = disp_firewall_conf
-        if os.path.exists(vm.firewall_conf):
-            shutil.copy(vm.firewall_conf, disp_firewall_conf)
-        elif vm.qid == 0 and os.path.exists(vm_disptempl.firewall_conf):
-            # for DispVM called from dom0, copy use rules from DispVM template
-            shutil.copy(vm_disptempl.firewall_conf, disp_firewall_conf)
-        if len(sys.argv) > 5 and len(sys.argv[5]) > 0:
-            assert os.path.exists(sys.argv[5]), "Invalid firewall.conf location"
-            dispvm.firewall_conf = sys.argv[5]
-        if vm.qid != 0:
-            dispvm.uses_default_netvm = False
-            # netvm can be changed before restore,
-            # but cannot be enabled/disabled
-            if (dispvm.netvm is None) == (vm.dispvm_netvm is None):
-                dispvm.netvm = vm.dispvm_netvm
-        # Wait for tar to finish
-        if tar_process.wait() != 0:
-            sys.stderr.write('Failed to unpack saved-cows.tar')
-            qvm_collection.unlock_db()
-            return None
-        print >>sys.stderr, "time=%s, VM starting" % (str(time.time()))
-        try:
-            dispvm.start()
-        except (MemoryError, QubesException) as e:
-            tray_notify_error(str(e))
-            raise
-        if vm.qid != 0:
-            # if need to enable/disable netvm, do it while DispVM is alive
-            if (dispvm.netvm is None) != (vm.dispvm_netvm is None):
-                dispvm.netvm = vm.dispvm_netvm
-        print >>sys.stderr, "time=%s, VM started" % (str(time.time()))
-        qvm_collection.save()
-        qvm_collection.unlock_db()
         # Reload firewall rules
         print >>sys.stderr, "time=%s, reloading firewall" % (str(time.time()))
         for vm in qvm_collection.values():