Commit patches by Serge Hallyn from 6-Apr and 7-Apr

This commit is contained in:
Dan Smith 2009-04-14 17:51:12 +00:00
parent 4fb341d741
commit 06e43a8f2c
3 changed files with 105 additions and 25 deletions

View File

@ -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

View 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)

View File

@ -35,12 +35,12 @@
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);
}