[libvirt] [PATCH 1/3] Pull code for doing a bind mount into separate method

Daniel P. Berrange berrange at redhat.com
Fri Jul 22 13:41:59 UTC 2011


From: "Daniel P. Berrange" <berrange at redhat.com>

The bind mount setup is about to get more complicated.
To avoid having to deal with several copies, pull it
out into a separate lxcContainerMountFSBind method.

Also pull out the iteration over container filesystems,
so that it will be easier to drop in support for non-bind
mount filesystems

* src/lxc/lxc_container.c: Pull bind mount code out into
  lxcContainerMountFSBind
---
 src/libvirt_private.syms |    2 +
 src/lxc/lxc_container.c  |  118 ++++++++++++++++++++++++++++-----------------
 2 files changed, 75 insertions(+), 45 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index acf7bb1..cac4995 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -290,6 +290,8 @@ virDomainDiskRemoveByName;
 virDomainDiskTypeFromString;
 virDomainDiskTypeToString;
 virDomainFSDefFree;
+virDomainFSTypeFromString;
+virDomainFSTypeToString;
 virDomainFindByID;
 virDomainFindByName;
 virDomainFindByUUID;
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 432b7f8..c5ef609 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -176,6 +176,7 @@ static int lxcContainerSetStdio(int control, int ttyfd, int handshakefd)
     rc = 0;
 
 cleanup:
+    VIR_DEBUG("rc=%d", rc);
     return rc;
 }
 
@@ -513,41 +514,77 @@ static int lxcContainerPopulateDevices(void)
 }
 
 
-static int lxcContainerMountNewFS(virDomainDefPtr vmDef)
+static int lxcContainerMountFSBind(virDomainFSDefPtr fs,
+                                   const char *srcprefix)
 {
-    int i;
+    char *src = NULL;
+    int ret = -1;
+
+    if (virAsprintf(&src, "%s%s", srcprefix, fs->src) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (virFileMakePath(fs->dst) < 0) {
+        virReportSystemError(errno,
+                             _("Failed to create %s"),
+                             fs->dst);
+        goto cleanup;
+    }
+
+    if (mount(src, fs->dst, NULL, MS_BIND, NULL) < 0) {
+        virReportSystemError(errno,
+                             _("Failed to bind mount directory %s to %s"),
+                             src, fs->dst);
+        goto cleanup;
+    }
+
+    ret = 0;
+
+    VIR_DEBUG("Done mounting filesystem ret=%d tryProc=%d", ret, tryProc);
+
+cleanup:
+    VIR_FREE(src);
+    return ret;
+}
+
+
+static int lxcContainerMountFS(virDomainFSDefPtr fs,
+                               const char *srcprefix)
+{
+    switch (fs->type) {
+    case VIR_DOMAIN_FS_TYPE_MOUNT:
+        if (lxcContainerMountFSBind(fs, srcprefix) < 0)
+            return -1;
+        break;
+    default:
+        lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
+                 _("Cannot mount filesystem type %s"),
+                 virDomainFSTypeToString(fs->type));
+        break;
+    }
+    return 0;
+}
+
+
+static int lxcContainerMountAllFS(virDomainDefPtr vmDef,
+                                  const char *dstprefix,
+                                  bool skipRoot)
+{
+    size_t i;
+    VIR_DEBUG("Mounting %s %d", dstprefix, skipRoot);
 
     /* Pull in rest of container's mounts */
     for (i = 0 ; i < vmDef->nfss ; i++) {
-        char *src;
-        if (STREQ(vmDef->fss[i]->dst, "/"))
-            continue;
-        /* XXX fix */
-        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+        if (skipRoot &&
+            STREQ(vmDef->fss[i]->dst, "/"))
             continue;
 
-        if (virAsprintf(&src, "/.oldroot/%s", vmDef->fss[i]->src) < 0) {
-            virReportOOMError();
-            return -1;
-        }
-
-        if (virFileMakePath(vmDef->fss[i]->dst) < 0) {
-            virReportSystemError(errno,
-                                 _("Failed to create %s"),
-                                 vmDef->fss[i]->dst);
-            VIR_FREE(src);
-            return -1;
-        }
-        if (mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
-            virReportSystemError(errno,
-                                 _("Failed to mount %s at %s"),
-                                 src, vmDef->fss[i]->dst);
-            VIR_FREE(src);
+        if (lxcContainerMountFS(vmDef->fss[i], dstprefix) < 0)
             return -1;
-        }
-        VIR_FREE(src);
     }
 
+    VIR_DEBUG("Mounted all filesystems");
     return 0;
 }
 
@@ -624,7 +661,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
         return -1;
 
     /* Sets up any non-root mounts from guest config */
-    if (lxcContainerMountNewFS(vmDef) < 0)
+    if (lxcContainerMountAllFS(vmDef, "/.oldroot", true) < 0)
         return -1;
 
     /* Gets rid of all remaining mounts from host OS, including /.oldroot itself */
@@ -634,34 +671,25 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
     return 0;
 }
 
+
 /* Nothing mapped to /, we're using the main root,
    but with extra stuff mapped in */
 static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
 {
-    int i;
-
+    VIR_DEBUG("def=%p", vmDef);
+    /*
+     * This makes sure that any new filesystems in the
+     * host OS propagate to the container, but any
+     * changes in the container are private
+     */
     if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
         virReportSystemError(errno, "%s",
                              _("Failed to make / slave"));
         return -1;
     }
-    for (i = 0 ; i < vmDef->nfss ; i++) {
-        /* XXX fix to support other mount types */
-        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
-            continue;
 
-        if (mount(vmDef->fss[i]->src,
-                  vmDef->fss[i]->dst,
-                  NULL,
-                  MS_BIND,
-                  NULL) < 0) {
-            virReportSystemError(errno,
-                                 _("Failed to mount %s at %s"),
-                                 vmDef->fss[i]->src,
-                                 vmDef->fss[i]->dst);
-            return -1;
-        }
-    }
+    if (lxcContainerMountAllFS(vmDef, "", false) < 0)
+        return -1;
 
     /* mount /proc */
     if (mount("lxcproc", "/proc", "proc", 0, NULL) < 0) {
-- 
1.7.6




More information about the libvir-list mailing list