ソースを参照

Use QubesDB instead of Xenstore.

Mostly done. Things still using xenstore/not working at all:
 - DispVM
 - qubesutils.py (especially qvm-block and qvm-usb code)
 - external IP change notification for ProxyVM (should be done via RPC
   service)
Marek Marczykowski 11 年 前
コミット
f159f3e168

+ 44 - 53
core-modules/000QubesVm.py

@@ -39,6 +39,7 @@ from qubes import qmemman_algo
 import libvirt
 import warnings
 
+from qubes.qdb import QubesDB
 from qubes.qubes import dry_run,vmm
 from qubes.qubes import register_qubes_vm_class
 from qubes.qubes import QubesVmCollection,QubesException,QubesHost,QubesVmLabels
@@ -292,6 +293,7 @@ class QubesVm(object):
         self.__qid = self._qid
 
         self._libvirt_domain = None
+        self._qdb_connection = None
 
         assert self.__qid < qubes_max_qid, "VM id out of bounds!"
         assert self.name is not None
@@ -549,6 +551,8 @@ class QubesVm(object):
         self.pre_rename(name)
         self.libvirt_domain.undefine()
         self._libvirt_domain = None
+        self._qdb_connection.close()
+        self._qdb_connection = None
 
         new_conf = os.path.join(self.dir_path, name + '.conf')
         if os.path.exists(self.conf_file):
@@ -641,6 +645,13 @@ class QubesVm(object):
     def is_disposablevm(self):
         return False
 
+    @property
+    def qdb(self):
+        if self._qdb_connection is None:
+            if self.is_running():
+                self._qdb_connection = QubesDB(self.name)
+        return self._qdb_connection
+
     @property
     def xid(self):
         if self.libvirt_domain is None:
@@ -926,74 +937,41 @@ class QubesVm(object):
         if dry_run:
             return
 
-        if xid is None:
-            xid = self.xid
-
-        assert xid >= 0, "Invalid XID value"
-
-        domain_path = vmm.xs.get_domain_path(xid)
-
-        # Set Xen Store entires with VM networking info:
-
-        vmm.xs.write('', "{0}/qubes-vm-type".format(domain_path),
-                self.type)
-        vmm.xs.write('', "{0}/qubes-vm-updateable".format(domain_path),
-                str(self.updateable))
+        self.qdb.write("/name", self.name)
+        self.qdb.write("/qubes-vm-type", self.type)
+        self.qdb.write("/qubes-vm-updateable", str(self.updateable))
 
         if self.is_netvm():
-            vmm.xs.write('',
-                    "{0}/qubes-netvm-gateway".format(domain_path),
-                    self.gateway)
-            vmm.xs.write('',
-                    "{0}/qubes-netvm-secondary-dns".format(domain_path),
-                    self.secondary_dns)
-            vmm.xs.write('',
-                    "{0}/qubes-netvm-netmask".format(domain_path),
-                    self.netmask)
-            vmm.xs.write('',
-                    "{0}/qubes-netvm-network".format(domain_path),
-                    self.network)
+            self.qdb.write("/qubes-netvm-gateway", self.gateway)
+            self.qdb.write("/qubes-netvm-secondary-dns", self.secondary_dns)
+            self.qdb.write("/qubes-netvm-netmask", self.netmask)
+            self.qdb.write("/qubes-netvm-network", self.network)
 
         if self.netvm is not None:
-            vmm.xs.write('', "{0}/qubes-ip".format(domain_path), self.ip)
-            vmm.xs.write('', "{0}/qubes-netmask".format(domain_path),
-                    self.netvm.netmask)
-            vmm.xs.write('', "{0}/qubes-gateway".format(domain_path),
-                    self.netvm.gateway)
-            vmm.xs.write('',
-                    "{0}/qubes-secondary-dns".format(domain_path),
-                    self.netvm.secondary_dns)
+            self.qdb.write("/qubes-ip", self.ip)
+            self.qdb.write("/qubes-netmask", self.netvm.netmask)
+            self.qdb.write("/qubes-gateway", self.netvm.gateway)
+            self.qdb.write("/qubes-secondary-dns", self.netvm.secondary_dns)
 
         tzname = self.get_timezone()
         if tzname:
-             vmm.xs.write('',
-                     "{0}/qubes-timezone".format(domain_path),
-                     tzname)
+             self.qdb.write("/qubes-timezone", tzname)
 
         for srv in self.services.keys():
             # convert True/False to "1"/"0"
-            vmm.xs.write('', "{0}/qubes-service/{1}".format(domain_path, srv),
+            self.qdb.write("/qubes-service/{0}".format(srv),
                     str(int(self.services[srv])))
 
-        vmm.xs.write('',
-                "{0}/qubes-block-devices".format(domain_path),
-                '')
+        self.qdb.write("/qubes-block-devices", '')
 
-        vmm.xs.write('',
-                "{0}/qubes-usb-devices".format(domain_path),
-                '')
+        self.qdb.write("/qubes-usb-devices", '')
 
-        vmm.xs.write('', "{0}/qubes-debug-mode".format(domain_path),
-                str(int(self.debug)))
+        self.qdb.write("/qubes-debug-mode", str(int(self.debug)))
 
         # Fix permissions
-        vmm.xs.set_permissions('', '{0}/device'.format(domain_path),
-                [{ 'dom': xid }])
-        vmm.xs.set_permissions('', '{0}/memory'.format(domain_path),
-                [{ 'dom': xid }])
-        vmm.xs.set_permissions('', '{0}/qubes-block-devices'.format(domain_path),
-                [{ 'dom': xid }])
-        vmm.xs.set_permissions('', '{0}/qubes-usb-devices'.format(domain_path),
+        # TODO: Currently whole qmemman is quite Xen-specific, so stay with
+        # xenstore for it until decided otherwise
+        vmm.xs.set_permissions('', '/local/domain/{0}/memory'.format(self.xid),
                 [{ 'dom': xid }])
 
         # fire hooks
@@ -1712,6 +1690,15 @@ class QubesVm(object):
         if (retcode != 0) :
             raise OSError ("Cannot execute qrexec-daemon!")
 
+    def start_qubesdb(self):
+        retcode = subprocess.call ([
+            system_path["qubesdb_daemon_path"],
+            str(self.xid),
+            self.name])
+        if retcode != 0:
+            self.force_shutdown()
+            raise OSError("ERROR: Cannot execute qubesdb-daemon!")
+
     def start(self, verbose = False, preparing_dvm = False, start_guid = True,
             notify_function = None, mem_required = None):
         if dry_run:
@@ -1754,12 +1741,16 @@ class QubesVm(object):
 
         self.libvirt_domain.createWithFlags(libvirt.VIR_DOMAIN_START_PAUSED)
 
+        if verbose:
+            print >> sys.stderr, "--> Starting Qubes DB..."
+        self.start_qubesdb()
+
         xid = self.xid
 
         if preparing_dvm:
             self.services['qubes-dvm'] = True
         if verbose:
-            print >> sys.stderr, "--> Setting Xen Store info for the VM..."
+            print >> sys.stderr, "--> Setting Qubes DB info for the VM..."
         self.create_xenstore_entries(xid)
 
         qvm_collection = QubesVmCollection()

+ 3 - 28
core-modules/005QubesNetVm.py

@@ -106,35 +106,10 @@ class QubesNetVm(QubesVm):
         assert lo >= 1 and lo <= 254, "Wrong IP address for VM"
         return self.dispnetprefix  + "{0}".format(lo)
 
-    def create_xenstore_entries(self, xid = None):
-        if dry_run:
-            return
-
-        if xid is None:
-            xid = self.xid
-
-
-        super(QubesNetVm, self).create_xenstore_entries(xid)
-        vmm.xs.write('', "/local/domain/{0}/qubes-netvm-external-ip".format(xid), '')
-        self.update_external_ip_permissions(xid)
-
     def update_external_ip_permissions(self, xid = -1):
-        if xid < 0:
-            xid = self.get_xid()
-        if xid < 0:
-            return
-
-        perms = [ { 'dom': xid } ]
-
-        for xid in self.__external_ip_allowed_xids:
-            perms.append({ 'dom': xid, 'read': True })
-
-        try:
-            vmm.xs.set_permissions('', '/local/domain/{0}/qubes-netvm-external-ip'.format(xid),
-                    perms)
-        except xen.lowlevel.xs.Error as e:
-            print >>sys.stderr, "WARNING: failed to update external IP " \
-                                "permissions: %s" % (str(e))
+        # TODO: VMs in __external_ip_allowed_xids should be notified via RPC
+        # service on exteran IP change
+        pass
 
     def start(self, **kwargs):
         if dry_run:

+ 18 - 20
core-modules/006QubesProxyVm.py

@@ -99,9 +99,7 @@ class QubesProxyVm(QubesNetVm):
 
 
         super(QubesProxyVm, self).create_xenstore_entries(xid)
-        vmm.xs.write('', "/local/domain/{0}/qubes-iptables-error".format(xid), '')
-        vmm.xs.set_permissions('', "/local/domain/{0}/qubes-iptables-error".format(xid),
-                [{ 'dom': xid, 'write': True }])
+        self.qdb.write("/qubes-iptables-error", '')
         self.write_iptables_xenstore_entry()
 
     def write_netvm_domid_entry(self, xid = -1):
@@ -112,14 +110,14 @@ class QubesProxyVm(QubesNetVm):
             xid = self.get_xid()
 
         if self.netvm is None:
-            vmm.xs.write('', "/local/domain/{0}/qubes-netvm-domid".format(xid), '')
+            self.qdb.write("/qubes-netvm-domid", '')
         else:
-            vmm.xs.write('', "/local/domain/{0}/qubes-netvm-domid".format(xid),
+            self.qdb.write("/qubes-netvm-domid",
                     "{0}".format(self.netvm.get_xid()))
 
     def write_iptables_xenstore_entry(self):
-        vmm.xs.rm('', "/local/domain/{0}/qubes-iptables-domainrules".format(self.get_xid()))
-        iptables =  "# Generated by Qubes Core on {0}\n".format(datetime.now().ctime())
+        self.qdb.rm("/qubes-iptables-domainrules/")
+        iptables =  "# Generated by Qubes Core on \n".format(datetime.now().ctime())
         iptables += "*filter\n"
         iptables += ":INPUT DROP [0:0]\n"
         iptables += ":FORWARD DROP [0:0]\n"
@@ -140,7 +138,7 @@ class QubesProxyVm(QubesNetVm):
         # Deny inter-VMs networking
         iptables += "-A FORWARD -i vif+ -o vif+ -j DROP\n"
         iptables += "COMMIT\n"
-        vmm.xs.write('', "/local/domain/{0}/qubes-iptables-header".format(self.get_xid()), iptables)
+        self.qdb.write("/qubes-iptables-header", iptables)
 
         vms = [vm for vm in self.connected_vms.values()]
         for vm in vms:
@@ -168,18 +166,18 @@ class QubesProxyVm(QubesNetVm):
                 rules_action = accept_action
 
             for rule in conf["rules"]:
-                iptables += "-A FORWARD -s {0} -d {1}".format(ip, rule["address"])
+                iptables += "-A FORWARD -s  -d {1}".format(ip, rule["address"])
                 if rule["netmask"] != 32:
-                    iptables += "/{0}".format(rule["netmask"])
+                    iptables += "/".format(rule["netmask"])
 
                 if rule["proto"] is not None and rule["proto"] != "any":
-                    iptables += " -p {0}".format(rule["proto"])
+                    iptables += " -p ".format(rule["proto"])
                     if rule["portBegin"] is not None and rule["portBegin"] > 0:
-                        iptables += " --dport {0}".format(rule["portBegin"])
+                        iptables += " --dport ".format(rule["portBegin"])
                         if rule["portEnd"] is not None and rule["portEnd"] > rule["portBegin"]:
-                            iptables += ":{0}".format(rule["portEnd"])
+                            iptables += ":".format(rule["portEnd"])
 
-                iptables += " -j {0}\n".format(rules_action)
+                iptables += " -j \n".format(rules_action)
 
             if conf["allowDns"] and self.netvm is not None:
                 # PREROUTING does DNAT to NetVM DNSes, so we need self.netvm.
@@ -193,20 +191,20 @@ class QubesProxyVm(QubesNetVm):
                 iptables += "-A FORWARD -s {0} -p tcp -d {1} --dport 53 -j " \
                             "ACCEPT\n".format(ip,self.netvm.secondary_dns)
             if conf["allowIcmp"]:
-                iptables += "-A FORWARD -s {0} -p icmp -j ACCEPT\n".format(ip)
+                iptables += "-A FORWARD -s  -p icmp -j ACCEPT\n".format(ip)
             if conf["allowYumProxy"]:
-                iptables += "-A FORWARD -s {0} -p tcp -d {1} --dport {2} -j ACCEPT\n".format(ip, yum_proxy_ip, yum_proxy_port)
+                iptables += "-A FORWARD -s  -p tcp -d {1} --dport {2} -j ACCEPT\n".format(ip, yum_proxy_ip, yum_proxy_port)
             else:
-                iptables += "-A FORWARD -s {0} -p tcp -d {1} --dport {2} -j DROP\n".format(ip, yum_proxy_ip, yum_proxy_port)
+                iptables += "-A FORWARD -s  -p tcp -d {1} --dport {2} -j DROP\n".format(ip, yum_proxy_ip, yum_proxy_port)
 
-            iptables += "-A FORWARD -s {0} -j {1}\n".format(ip, default_action)
+            iptables += "-A FORWARD -s  -j {1}\n".format(ip, default_action)
             iptables += "COMMIT\n"
-            vmm.xs.write('', "/local/domain/"+str(self.get_xid())+"/qubes-iptables-domainrules/"+str(xid), iptables)
+            self.qdb.write("/qubes-iptables-domainrules/"+str(xid), iptables)
         # no need for ending -A FORWARD -j DROP, cause default action is DROP
 
         self.write_netvm_domid_entry()
 
         self.rules_applied = None
-        vmm.xs.write('', "/local/domain/{0}/qubes-iptables".format(self.get_xid()), 'reload')
+        self.qdb.write("/qubes-iptables", 'reload')
 
 register_qubes_vm_class(QubesProxyVm)

+ 1 - 0
core-modules/01QubesDisposableVm.py

@@ -110,6 +110,7 @@ class QubesDisposableVm(QubesVm):
     def create_xenstore_entries(self, xid):
         super(QubesDisposableVm, self).create_xenstore_entries(xid)
 
+        # TODO!
         domain_path = vmm.xs.get_domain_path(xid)
 
         vmm.xs.write('', "{0}/qubes-restore-complete".format(domain_path),

+ 1 - 0
core/qubes.py

@@ -49,6 +49,7 @@ system_path = {
     'qubes_guid_path': '/usr/bin/qubes-guid',
     'qrexec_daemon_path': '/usr/lib/qubes/qrexec-daemon',
     'qrexec_client_path': '/usr/lib/qubes/qrexec-client',
+    'qubesdb_daemon_path': '/usr/sbin/qubesdb-daemon',
 
     'qubes_base_dir': qubes_base_dir,
 

+ 1 - 0
linux/systemd/qubes-core.service

@@ -1,5 +1,6 @@
 [Unit]
 Description=Qubes Dom0 startup setup
+After=qubes-db-dom0.service
 # Cover legacy init.d script
 
 [Service]

+ 1 - 0
rpm_spec/core-dom0.spec

@@ -48,6 +48,7 @@ Requires(preun): systemd-units
 Requires(postun): systemd-units
 Requires:	python, pciutils, python-inotify, python-daemon
 Requires:       qubes-core-dom0-linux >= 2.0.24
+Requires:       qubes-db-dom0
 Requires:       python-lxml
 Requires:       python-psutil
 # TODO: R: qubes-gui-dom0 >= 2.1.11