mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-08-23 23:48:14 +00:00
Merge pull request #66 from laijs/setup-rootfs-before-chroot
Setup mounts&rootfs before chroot
This commit is contained in:
+53
-93
@@ -56,19 +56,21 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
|
||||
for (i = 0; i < container->vols_num; i++) {
|
||||
char volume[512];
|
||||
char mountpoint[512];
|
||||
vol = &container->vols[i];
|
||||
|
||||
if (vol->scsiaddr)
|
||||
hyper_find_sd("/.oldroot", vol->scsiaddr, &vol->device);
|
||||
hyper_find_sd(vol->scsiaddr, &vol->device);
|
||||
|
||||
sprintf(dev, "/dev/%s", vol->device);
|
||||
sprintf(path, "/tmp/%s", vol->mountpoint);
|
||||
sprintf(volume, "/%s/_data", path);
|
||||
sprintf(mountpoint, "./%s", vol->mountpoint);
|
||||
|
||||
fprintf(stdout, "mount %s to %s, tmp path %s\n",
|
||||
dev, vol->mountpoint, path);
|
||||
|
||||
if (hyper_mkdir(path) < 0 || hyper_mkdir(vol->mountpoint) < 0) {
|
||||
if (hyper_mkdir(path) < 0 || hyper_mkdir(mountpoint) < 0) {
|
||||
perror("create volume dir failed");
|
||||
return -1;
|
||||
}
|
||||
@@ -80,8 +82,8 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
|
||||
if (vol->docker) {
|
||||
if (container->initialize &&
|
||||
(container_populate_volume(vol->mountpoint, volume) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", vol->mountpoint);
|
||||
(container_populate_volume(mountpoint, volume) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
|
||||
return -1;
|
||||
}
|
||||
} else if (hyper_mkdir(volume) < 0) {
|
||||
@@ -89,13 +91,13 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount(volume, vol->mountpoint, NULL, MS_BIND, NULL) < 0) {
|
||||
if (mount(volume, mountpoint, NULL, MS_BIND, NULL) < 0) {
|
||||
perror("mount volume device faled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vol->readonly &&
|
||||
mount(volume, vol->mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) {
|
||||
mount(volume, mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) {
|
||||
perror("mount fsmap faled");
|
||||
return -1;
|
||||
}
|
||||
@@ -107,24 +109,26 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
struct stat st;
|
||||
char src[512];
|
||||
struct fsmap *map = &container->maps[i];
|
||||
char mountpoint[512];
|
||||
|
||||
sprintf(src, "/.oldroot/tmp/hyper/shared/%s", map->source);
|
||||
fprintf(stdout, "mount %s to %s\n", src, map->path);
|
||||
sprintf(src, "/tmp/hyper/shared/%s", map->source);
|
||||
sprintf(mountpoint, "./%s", map->path);
|
||||
fprintf(stdout, "mount %s to %s\n", src, mountpoint);
|
||||
|
||||
stat(src, &st);
|
||||
if (st.st_mode & S_IFDIR) {
|
||||
if (hyper_mkdir(map->path) < 0) {
|
||||
if (hyper_mkdir(mountpoint) < 0) {
|
||||
perror("create map dir failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map->docker && container->initialize &&
|
||||
(container_populate_volume(map->path, src) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", map->path);
|
||||
(container_populate_volume(mountpoint, src) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
int fd = open(map->path, O_CREAT|O_WRONLY, 0755);
|
||||
int fd = open(mountpoint, O_CREAT|O_WRONLY, 0755);
|
||||
if (fd < 0) {
|
||||
perror("create map file failed");
|
||||
continue;
|
||||
@@ -132,7 +136,7 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (mount(src, map->path, NULL, MS_BIND, NULL) < 0) {
|
||||
if (mount(src, mountpoint, NULL, MS_BIND, NULL) < 0) {
|
||||
perror("mount fsmap faled");
|
||||
continue;
|
||||
}
|
||||
@@ -140,90 +144,57 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
if (map->readonly == 0)
|
||||
continue;
|
||||
|
||||
if (mount(src, map->path, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
|
||||
if (mount(src, mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
|
||||
perror("mount fsmap faled");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void container_unmount_oldroot(char *path)
|
||||
{
|
||||
FILE *mtab;
|
||||
struct mntent *mnt;
|
||||
char *mntlist[128];
|
||||
int i;
|
||||
int n = 0;
|
||||
char *filesys;
|
||||
|
||||
mtab = setmntent("/proc/mounts", "r");
|
||||
if (mtab == NULL) {
|
||||
fprintf(stderr, "cannot open /proc/mount");
|
||||
return;
|
||||
}
|
||||
|
||||
while (n < 128 && (mnt = getmntent(mtab))) {
|
||||
if (strncmp(mnt->mnt_dir, path, strlen(path)))
|
||||
continue;
|
||||
mntlist[n++] = strdup(mnt->mnt_dir);
|
||||
}
|
||||
|
||||
endmntent(mtab);
|
||||
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
filesys = mntlist[i];
|
||||
fprintf(stdout, "umount %s\n", filesys);
|
||||
if (umount(mntlist[i]) < 0 && umount2(mntlist[i],
|
||||
MNT_DETACH) < 0) {
|
||||
fprintf(stdout, "umount %s: %s failed\n",
|
||||
filesys, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int container_setup_mount(struct hyper_container *container)
|
||||
{
|
||||
char src[512];
|
||||
|
||||
hyper_mkdir("/proc");
|
||||
hyper_mkdir("/sys");
|
||||
hyper_mkdir("/dev");
|
||||
// current dir is container rootfs, the operations on "./PATH" are the operations on container's "/PATH"
|
||||
hyper_mkdir("./proc");
|
||||
hyper_mkdir("./sys");
|
||||
hyper_mkdir("./dev");
|
||||
|
||||
if (mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
|
||||
mount("sysfs", "/sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
|
||||
mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID, NULL) < 0) {
|
||||
if (mount("proc", "./proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
|
||||
mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
|
||||
mount("devtmpfs", "./dev", "devtmpfs", MS_NOSUID, NULL) < 0) {
|
||||
perror("mount basic filesystem for container failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hyper_mkdir("/dev/shm") < 0) {
|
||||
if (hyper_mkdir("./dev/shm") < 0) {
|
||||
fprintf(stderr, "create /dev/shm failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount("tmpfs", "/dev/shm/", "tmpfs", MS_NOSUID| MS_NODEV, NULL) < 0) {
|
||||
if (mount("tmpfs", "./dev/shm/", "tmpfs", MS_NOSUID| MS_NODEV, NULL) < 0) {
|
||||
perror("mount shm failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hyper_mkdir("/dev/pts") < 0) {
|
||||
if (hyper_mkdir("./dev/pts") < 0) {
|
||||
fprintf(stderr, "create /dev/pts failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sprintf(src, "/.oldroot/tmp/hyper/%s/devpts", container->id) < 0) {
|
||||
if (sprintf(src, "/tmp/hyper/%s/devpts", container->id) < 0) {
|
||||
fprintf(stderr, "get container devpts failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount(src, "/dev/pts/", NULL, MS_BIND, NULL) < 0) {
|
||||
if (mount(src, "./dev/pts/", NULL, MS_BIND, NULL) < 0) {
|
||||
perror("move pts to /dev/pts failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlink("/dev/ptmx") < 0)
|
||||
if (unlink("./dev/ptmx") < 0)
|
||||
perror("remove /dev/ptmx failed");
|
||||
if (symlink("/dev/pts/ptmx", "/dev/ptmx") < 0)
|
||||
if (symlink("/dev/pts/ptmx", "./dev/ptmx") < 0)
|
||||
perror("link /dev/pts/ptmx to /dev/ptmx failed");
|
||||
|
||||
return 0;
|
||||
@@ -272,7 +243,7 @@ static int container_setup_dns(struct hyper_container *container)
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
char *src = "/.oldroot/tmp/hyper/resolv.conf";
|
||||
char *src = "/tmp/hyper/resolv.conf";
|
||||
|
||||
if (stat(src, &st) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
@@ -284,16 +255,16 @@ static int container_setup_dns(struct hyper_container *container)
|
||||
return -1;
|
||||
}
|
||||
|
||||
hyper_mkdir("/etc");
|
||||
hyper_mkdir("./etc");
|
||||
|
||||
fd = open("/etc/resolv.conf", O_CREAT| O_WRONLY, 0644);
|
||||
fd = open("./etc/resolv.conf", O_CREAT| O_WRONLY, 0644);
|
||||
if (fd < 0) {
|
||||
perror("create /etc/resolv.conf failed");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (mount(src, "/etc/resolv.conf", NULL, MS_BIND, NULL) < 0) {
|
||||
if (mount(src, "./etc/resolv.conf", NULL, MS_BIND, NULL) < 0) {
|
||||
perror("bind to /etc/resolv.conf failed");
|
||||
return -1;
|
||||
}
|
||||
@@ -378,7 +349,7 @@ static int hyper_container_init(void *data)
|
||||
{
|
||||
struct hyper_container_arg *arg = data;
|
||||
struct hyper_container *container = arg->c;
|
||||
char root[512], oldroot[512], rootfs[512];
|
||||
char root[512], rootfs[512];
|
||||
|
||||
fprintf(stdout, "%s in\n", __func__);
|
||||
if (container->exec.argv == NULL) {
|
||||
@@ -436,7 +407,7 @@ static int hyper_container_init(void *data)
|
||||
char dev[128];
|
||||
|
||||
if (container->scsiaddr)
|
||||
hyper_find_sd("", container->scsiaddr, &container->image);
|
||||
hyper_find_sd(container->scsiaddr, &container->image);
|
||||
|
||||
sprintf(dev, "/dev/%s", container->image);
|
||||
fprintf(stdout, "device %s\n", dev);
|
||||
@@ -460,32 +431,12 @@ static int hyper_container_init(void *data)
|
||||
fprintf(stdout, "root directory for container is %s/%s, init task %s\n",
|
||||
root, container->rootfs, container->exec.argv[0]);
|
||||
|
||||
sprintf(oldroot, "%s/%s/.oldroot", root, container->rootfs);
|
||||
if (hyper_mkdir(oldroot) < 0) {
|
||||
perror("make oldroot directroy failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mount("/", oldroot, NULL, MS_BIND|MS_REC, NULL) < 0) {
|
||||
perror("bind oldroot failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sprintf(rootfs, "%s/%s/", root, container->rootfs);
|
||||
if (mount(rootfs, rootfs, NULL, MS_BIND|MS_REC, NULL) < 0) {
|
||||
perror("failed to bind rootfs");
|
||||
goto fail;
|
||||
}
|
||||
chdir(rootfs);
|
||||
if (mount(rootfs, "/", NULL, MS_MOVE, NULL) < 0) {
|
||||
perror("failed to move rootfs");
|
||||
goto fail;
|
||||
}
|
||||
/* pivot_root won't work, see
|
||||
* Documention/filesystem/ramfs-rootfs-initramfs.txt */
|
||||
chroot(".");
|
||||
|
||||
chdir("/");
|
||||
|
||||
if (container_setup_mount(container) < 0) {
|
||||
fprintf(stderr, "container sets up mount failed\n");
|
||||
@@ -497,13 +448,24 @@ static int hyper_container_init(void *data)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (container_setup_sysctl(container) < 0) {
|
||||
fprintf(stderr, "container sets up sysctl failed\n");
|
||||
if (container_setup_dns(container) < 0) {
|
||||
fprintf(stderr, "container sets up dns failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (container_setup_dns(container) < 0) {
|
||||
fprintf(stderr, "container sets up dns failed\n");
|
||||
// manipulate the rootfs of the container/namespace: move the prepared path @rootfs to /
|
||||
if (mount(rootfs, "/", NULL, MS_MOVE, NULL) < 0) {
|
||||
perror("failed to move rootfs");
|
||||
goto fail;
|
||||
}
|
||||
/* pivot_root won't work, see
|
||||
* Documention/filesystem/ramfs-rootfs-initramfs.txt */
|
||||
chroot(".");
|
||||
|
||||
chdir("/");
|
||||
|
||||
if (container_setup_sysctl(container) < 0) {
|
||||
fprintf(stderr, "container sets up sysctl failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -512,8 +474,6 @@ static int hyper_container_init(void *data)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
container_unmount_oldroot("/.oldroot");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
if (container_setup_tty(arg->pipe[1], container) < 0) {
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ int hyper_copy_dir(char *src, char *dest) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_find_sd(char *prefix, char *addr, char **dev) {
|
||||
int hyper_find_sd(char *addr, char **dev) {
|
||||
struct dirent **list;
|
||||
struct dirent *dir;
|
||||
char path[512];
|
||||
int i, num;
|
||||
|
||||
sprintf(path, "%s/sys/class/scsi_disk/0:0:%s/device/block/", prefix, addr);
|
||||
sprintf(path, "/sys/class/scsi_disk/0:0:%s/device/block/", addr);
|
||||
fprintf(stdout, "orig dev %s, scan path %s\n", *dev, path);
|
||||
|
||||
num = scandir(path, &list, NULL, NULL);
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ struct env;
|
||||
|
||||
char *read_cmdline(void);
|
||||
int hyper_setup_env(struct env *envs, int num);
|
||||
int hyper_find_sd(char *prefix, char *addr, char **dev);
|
||||
int hyper_find_sd(char *addr, char **dev);
|
||||
int hyper_list_dir(char *path);
|
||||
int hyper_copy_dir(char *src, char *dst);
|
||||
void online_cpu(void);
|
||||
|
||||
Reference in New Issue
Block a user