[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH] qemu: patch to support security model for filesystem type



On 9/24/2010 6:23 AM, Harsh Prateek Bora wrote:
This patch introduces a new attribute security_model to<filesystem>
tag, which can have any of the following three values: passthrough,
mapped or none. This patch is based on Daniel's patch to support 9pfs
qemu commandline options.

Harsh, looks like this patch contains both your changes, and Dan's changes.
Please post a patch with 'only your changes' which applies on top of Dan's patch.

Thanks,
JV

Usage:
	<filesystem type='mount' security_model='passthrough'>
	<source dir='/export/to/guest'/>
	<target dir='mount_tag'/>
	</filesystem>

---
  docs/schemas/domain.rng |    7 +++
  src/conf/domain_conf.c  |   30 +++++++++++++-
  src/conf/domain_conf.h  |   10 +++++
  src/qemu/qemu_conf.c    |  103 +++++++++++++++++++++++++++++++++++++++++++++++
  src/qemu/qemu_conf.h    |    5 ++
  5 files changed, 153 insertions(+), 2 deletions(-)

diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index ccb8cf3..43a292d 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -761,6 +761,13 @@
        </choice>
        <optional>
          <ref name="address"/>
+<attribute name="security_model">
+<choice>
+<value>passthrough</value>
+<value>mapped</value>
+<value>none</value>
+</choice>
+</attribute>
        </optional>
      </element>
    </define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e05d5d7..a9881d1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -161,6 +161,12 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
                "file",
                "template")

+VIR_ENUM_IMPL(virDomainFSSecurityModel, VIR_DOMAIN_FS_SECURITY_LAST,
+              "passthrough",
+              "mapped",
+              "none")
+
+
  VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
                "user",
                "ethernet",
@@ -1847,6 +1853,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
      char *type = NULL;
      char *source = NULL;
      char *target = NULL;
+    char *security_model;

      if (VIR_ALLOC(def)<  0) {
          virReportOOMError();
@@ -1864,6 +1871,17 @@ virDomainFSDefParseXML(xmlNodePtr node,
          def->type = VIR_DOMAIN_FS_TYPE_MOUNT;
      }

+    security_model = virXMLPropString(node, "security_model");
+    if (security_model) {
+        if ((def->security_model = virDomainFSSecurityModelTypeFromString(security_model))<  0) {
+            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                                 _("unknown security model '%s'"), security_model);
+            goto error;
+        }
+    } else {
+        def->security_model = VIR_DOMAIN_FS_SECURITY_PASSTHROUGH;
+    }
+
      cur = node->children;
      while (cur != NULL) {
          if (cur->type == XML_ELEMENT_NODE) {
@@ -5602,6 +5620,7 @@ virDomainFSDefFormat(virBufferPtr buf,
                       int flags)
  {
      const char *type = virDomainFSTypeToString(def->type);
+    const char *sec_model = virDomainFSSecurityModelTypeToString(def->security_model);

      if (!type) {
          virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf,
          return -1;
      }

+   if (!sec_model) {
+        virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                             _("unexpected security model %d"), def->security_model);
+        return -1;
+    }
+
+
      virBufferVSprintf(buf,
-                      "<filesystem type='%s'>\n",
-                      type);
+                      "<filesystem type='%s' security_model='%s'>\n",
+                      type, sec_model);

      if (def->src) {
          switch (def->type) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7195c04..6adf027 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -236,10 +236,20 @@ enum virDomainFSType {
      VIR_DOMAIN_FS_TYPE_LAST
  };

+/* Filesystem mount security model  */
+enum virDomainFSSecurityModel {
+    VIR_DOMAIN_FS_SECURITY_PASSTHROUGH,
+    VIR_DOMAIN_FS_SECURITY_MAPPED,
+    VIR_DOMAIN_FS_SECURITY_NONE,
+
+    VIR_DOMAIN_FS_SECURITY_LAST
+};
+
  typedef struct _virDomainFSDef virDomainFSDef;
  typedef virDomainFSDef *virDomainFSDefPtr;
  struct _virDomainFSDef {
      int type;
+    int security_model;
      char *src;
      char *dst;
      unsigned int readonly : 1;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 7a37c70..a637dee 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1212,6 +1212,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
          flags |= QEMUD_CMD_FLAG_TDF;
      if (strstr(help, ",menu=on"))
          flags |= QEMUD_CMD_FLAG_BOOT_MENU;
+    if (strstr(help, "-fsdev"))
+        flags |= QEMUD_CMD_FLAG_FSDEV;

      /* Keep disabled till we're actually ready to turn on netdev mode
       * The plan is todo it in 0.13.0 QEMU, but lets wait&  see... */
@@ -2008,6 +2010,11 @@ qemuAssignDeviceAliases(virDomainDefPtr def, unsigned long long qemuCmdFlags)
      if (!(qemuCmdFlags&  QEMUD_CMD_FLAG_DEVICE))
          return 0;

+    for (i=0; i<  def->nfss ; i++) {
+        if (virAsprintf(&def->fss[i]->info.alias, "fs%d", i)<  0)
+            goto no_memory;
+    }
+
      for (i = 0; i<  def->nsounds ; i++) {
          if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i)<  0)
              goto no_memory;
@@ -2371,6 +2378,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
                  goto error;
          }
      }
+    for (i = 0; i<  def->nfss ; i++) {
+        if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+
+        /* Only support VirtIO-9p-pci so far. If that changes,
+         * we might need to skip devices here */
+        if (qemuDomainPCIAddressSetNextAddr(addrs,&def->fss[i]->info)<  0)
+            goto error;
+    }

      /* Network interfaces */
      for (i = 0; i<  def->nnets ; i++) {
@@ -2761,6 +2777,70 @@ error:
  }


+char *qemuBuildFSStr(virDomainFSDefPtr fs,
+                     unsigned long long qemuCmdFlags ATTRIBUTE_UNUSED)
+{
+    virBuffer opt = VIR_BUFFER_INITIALIZER;
+
+    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("only supports mount filesystem type"));
+        goto error;
+    }
+
+    virBufferAddLit(&opt, "local");
+    if (fs->security_model == VIR_DOMAIN_FS_SECURITY_PASSTHROUGH)
+        virBufferAddLit(&opt, ",security_model=passthrough");
+    else if (fs->security_model == VIR_DOMAIN_FS_SECURITY_MAPPED)
+        virBufferAddLit(&opt, ",security_model=mapped");
+    else if (fs->security_model == VIR_DOMAIN_FS_SECURITY_NONE)
+        virBufferAddLit(&opt, ",security_model=none");
+    virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
+    virBufferVSprintf(&opt, ",path=%s", fs->src);
+
+    if (virBufferError(&opt)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&opt);
+
+error:
+    virBufferFreeAndReset(&opt);
+    return NULL;
+}
+
+
+char *
+qemuBuildFSDevStr(virDomainFSDefPtr fs)
+{
+    virBuffer opt = VIR_BUFFER_INITIALIZER;
+
+    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("can only passthrough directories"));
+        goto error;
+    }
+
+    virBufferAddLit(&opt, "virtio-9p-pci");
+    virBufferVSprintf(&opt, ",id=%s", fs->info.alias);
+    virBufferVSprintf(&opt, ",fsdev=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
+    virBufferVSprintf(&opt, ",mount_tag=%s", fs->dst);
+    qemuBuildDeviceAddressStr(&opt,&fs->info);
+
+    if (virBufferError(&opt)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&opt);
+
+error:
+    virBufferFreeAndReset(&opt);
+    return NULL;
+}
+
+
  char *
  qemuBuildControllerDevStr(virDomainControllerDefPtr def)
  {
@@ -4377,6 +4457,29 @@ int qemudBuildCommandLine(virConnectPtr conn,
          }
      }

+    if (qemuCmdFlags&  QEMUD_CMD_FLAG_FSDEV) {
+        for (i = 0 ; i<  def->nfss ; i++) {
+            char *optstr;
+            virDomainFSDefPtr fs = def->fss[i];
+
+            ADD_ARG_LIT("-fsdev");
+            if (!(optstr = qemuBuildFSStr(fs, qemuCmdFlags)))
+                goto error;
+            ADD_ARG(optstr);
+
+            ADD_ARG_LIT("-device");
+            if (!(optstr = qemuBuildFSDevStr(fs)))
+                goto error;
+            ADD_ARG(optstr);
+        }
+    } else {
+        if (def->nfss) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("filesystem passthrough not supported by this QEMU"));
+            goto error;
+        }
+    }
+
      if (!def->nnets) {
          /* If we have -device, then we set -nodefault already */
          if (!(qemuCmdFlags&  QEMUD_CMD_FLAG_DEVICE)) {
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 2c9e608..7005466 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -93,6 +93,7 @@ enum qemud_cmd_flags {
      QEMUD_CMD_FLAG_NODEFCONFIG   = (1LL<<  37), /* -nodefconfig */
      QEMUD_CMD_FLAG_BOOT_MENU     = (1LL<<  38), /* -boot menu=on support */
      QEMUD_CMD_FLAG_ENABLE_KQEMU  = (1LL<<  39), /* -enable-kqemu flag */
+    QEMUD_CMD_FLAG_FSDEV         = (1LL<<  40)  /* -fstype filesystem passthrough */
  };

  /* Main driver state */
@@ -188,6 +189,7 @@ struct _qemuDomainCmdlineDef {

  # define QEMU_DRIVE_HOST_PREFIX "drive-"
  # define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial"
+# define QEMU_FSDEV_HOST_PREFIX "fsdev-"

  # define qemuReportError(code, ...)                                      \
      virReportErrorHelper(NULL, VIR_FROM_QEMU, code, __FILE__,           \
@@ -248,9 +250,12 @@ char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
  char *qemuBuildDriveStr(virDomainDiskDefPtr disk,
                          int bootable,
                          unsigned long long qemuCmdFlags);
+char *qemuBuildFSStr(virDomainFSDefPtr fs,
+                     unsigned long long qemuCmdFlags);

  /* Current, best practice */
  char * qemuBuildDriveDevStr(virDomainDiskDefPtr disk);
+char * qemuBuildFSDevStr(virDomainFSDefPtr fs);
  /* Current, best practice */
  char * qemuBuildControllerDevStr(virDomainControllerDefPtr def);




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]