]> xenbits.xensource.com Git - libvirt.git/commitdiff
Commit patches by Serge Hallyn from 6-Apr and 7-Apr
authorDan Smith <danms@us.ibm.com>
Tue, 14 Apr 2009 17:51:12 +0000 (17:51 +0000)
committerDan Smith <danms@us.ibm.com>
Tue, 14 Apr 2009 17:51:12 +0000 (17:51 +0000)
ChangeLog
src/lxc_container.c
src/veth.c

index bf7b7f3632f81b92c4b7cceb03e77f15b8a01c31..36b4c868cee0dd23e4fb17fb5879301cc57ed0a5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue Apr 14 10:46:44 PDT 2009 Dan Smith <danms@us.ibm.com>
+
+       * src/veth.c: Fix veth off-by-one error
+         patch by Serge Hallyn
+       * src/lxc_container.c: Stop rootless containers from messing with
+         system mounts.  Also, make pivot_root code more robust.
+         patch by Serge Hallyn
+
 Tue Apr 14 14:46:29 CEST 2009 Daniel Veillard <veillard@redhat.com>
 
        * libvirt.spec.in: fix build on RHEL and Centos 5.x
index 3f17b8dfe88694b26b310db54c8943659ed2a878..ff115d1889a33dcee53b3488a28fd1e4b279a2d2 100644 (file)
@@ -264,50 +264,117 @@ static int lxcContainerChildMountSort(const void *a, const void *b)
   return strcmp(*sb, *sa);
 }
 
+#ifndef MS_REC
+#define MS_REC          16384
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH      0x00000002
+#endif
+
+#ifndef MS_PRIVATE
+#define MS_PRIVATE              (1<<18)
+#endif
+
+#ifndef MS_SLAVE
+#define MS_SLAVE               (1<<19)
+#endif
+
 static int lxcContainerPivotRoot(virDomainFSDefPtr root)
 {
     int rc;
-    char *oldroot;
+    char *oldroot = NULL, *newroot = NULL;
 
-    /* First step is to ensure the new root itself is
-       a mount point */
-    if (mount(root->src, root->src, NULL, MS_BIND, NULL) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("failed to bind new root %s"),
-                             root->src);
-        return -1;
+    /* root->parent must be private, so make / private. */
+    if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to make root private"));
+        goto err;
     }
 
     if (virAsprintf(&oldroot, "%s/.oldroot", root->src) < 0) {
         virReportOOMError(NULL);
-        return -1;
+        goto err;
     }
 
     if ((rc = virFileMakePath(oldroot)) < 0) {
         virReportSystemError(NULL, rc,
                              _("failed to create %s"),
                              oldroot);
-        VIR_FREE(oldroot);
-        return -1;
+        goto err;
+    }
+
+    /* Create a tmpfs root since old and new roots must be
+     * on separate filesystems */
+    if (mount("", oldroot, "tmpfs", 0, NULL) < 0) {
+        virReportSystemError(NULL, errno,
+                             _("failed to mount empty tmpfs at %s"),
+                             oldroot);
+        goto err;
+    }
+       
+    /* Create a directory called 'new' in tmpfs */
+    if (virAsprintf(&newroot, "%s/new", oldroot) < 0) {
+        virReportOOMError(NULL);
+        goto err;
+    }
+
+    if ((rc = virFileMakePath(newroot)) < 0) {
+        virReportSystemError(NULL, rc,
+                             _("failed to create %s"),
+                             newroot);
+        goto err;
+    }
+
+    /* ... and mount our root onto it */
+    if (mount(root->src, newroot, NULL, MS_BIND|MS_REC, NULL) < 0) {
+        virReportSystemError(NULL, errno,
+                             _("failed to bind new root %s into tmpfs"),
+                             root->src);
+        goto err;
+    }
+
+    /* Now we chroot into the tmpfs, then pivot into the
+     * root->src bind-mounted onto '/new' */
+    if (chroot(oldroot) < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to chroot into tmpfs"));
+        goto err;
+    }
+
+    if (chdir("/new") < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to chdir into /new on tmpfs"));
+        goto err;
     }
 
     /* The old root directory will live at /.oldroot after
      * this and will soon be unmounted completely */
-    if (pivot_root(root->src, oldroot) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("failed to pivot root %s to %s"),
-                             oldroot, root->src);
-        VIR_FREE(oldroot);
-        return -1;
+    if (pivot_root(".", ".oldroot") < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to pivot root"));
+        goto err;
     }
-    VIR_FREE(oldroot);
 
     /* CWD is undefined after pivot_root, so go to / */
-    if (chdir("/") < 0) {
-        return -1;
+    if (chdir("/") < 0)
+        goto err;
+
+    if (umount2(".oldroot", MNT_DETACH) < 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to lazily unmount old root"));
+        goto err;
     }
 
+    VIR_FREE(oldroot);
+    VIR_FREE(newroot);
+
     return 0;
+
+err:
+    if (oldroot) VIR_FREE(oldroot);
+    if (newroot) VIR_FREE(newroot);
+    return -1;
 }
 
 static int lxcContainerPopulateDevices(void)
@@ -349,10 +416,9 @@ static int lxcContainerPopulateDevices(void)
                              _("cannot create /dev/pts"));
         return -1;
     }
-    if (mount("/.oldroot/dev/pts", "/dev/pts", NULL,
-              MS_MOVE, NULL) < 0) {
+    if (mount("devpts", "/dev/pts", "devpts", 0, NULL) < 0) {
         virReportSystemError(NULL, errno, "%s",
-                             _("failed to move /dev/pts into container"));
+                             _("failed to mount /dev/pts in container"));
         return -1;
     }
 
@@ -496,6 +562,11 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
 {
     int i;
 
+    if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
+        virReportSystemError(NULL, 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)
index 93173e4c7326815d1c19c3a6b27559f3b763b040..90c1dcb0ee907fd4f589ca0fabb99fad1ceb1ea8 100644 (file)
 static int getFreeVethName(char *veth, int maxLen, int startDev)
 {
     int rc = -1;
-    int devNum = startDev;
+    int devNum = startDev-1;
     char path[PATH_MAX];
 
     do {
-        snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);
         ++devNum;
+        snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum);
     } while (virFileExists(path));
 
     snprintf(veth, maxLen, "veth%d", devNum);
@@ -97,6 +97,7 @@ int vethCreate(char* veth1, int veth1MaxLen,
 
     while ((1 > strlen(veth2)) || STREQ(veth1, veth2)) {
         vethDev = getFreeVethName(veth2, veth2MaxLen, vethDev);
+        ++vethDev;
         DEBUG("assigned veth2: %s", veth2);
     }