mirror of https://gitee.com/openkylin/libvirt.git
Commit patches by Serge Hallyn from 6-Apr and 7-Apr
This commit is contained in:
parent
4fb341d741
commit
06e43a8f2c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue