Пример #1
0
static int container_setup_dns(struct hyper_container *container)
{
	int fd;
	struct stat st;
	char *src = "/.oldroot/tmp/hyper/resolv.conf";

	if (stat(src, &st) < 0) {
		if (errno == ENOENT) {
			fprintf(stdout, "no dns configured\n");
			return 0;
		}

		perror("stat resolve.conf failed");
		return -1;
	}

	hyper_mkdir("/etc");

	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) {
		perror("bind to /etc/resolv.conf failed");
		return -1;
	}

	return 0;
}
Пример #2
0
static int container_setup_volume(struct hyper_container *container)
{
	int i;
	char dev[512], path[512];
	struct volume *vol;

	for (i = 0; i < container->vols_num; i++) {
		vol = &container->vols[i];

		sprintf(dev, "/.oldroot/dev/%s", vol->device);
		sprintf(path, "/tmp/%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) {
			perror("create volume dir failed");
			return -1;
		}

		if (mount(dev, path, vol->fstype, 0, NULL) < 0) {
			perror("mount volume device faled");
			return -1;
		}

		if (mount(path, vol->mountpoint, NULL, MS_BIND, NULL) < 0) {
			perror("mount volume device faled");
			return -1;
		}

		if (vol->readonly &&
		    mount(path, vol->mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) {
			perror("mount fsmap faled");
			return -1;
		}

		umount(path);
	}

	return 0;
}
Пример #3
0
int hyper_mkdir(char *hyper_path, mode_t mode)
{
	struct stat st;
	char *p, *path = strdup(hyper_path);

	if (path == NULL) {
		errno = ENOMEM;
		goto fail;
	}

	if (stat(path, &st) >= 0) {
		if (S_ISDIR(st.st_mode))
			goto out;
		errno = ENOTDIR;
		goto fail;
	}

	if (errno != ENOENT)
		goto fail;

	p = strrchr(path, '/');
	if (p == NULL) {
		errno = EINVAL;
		goto fail;
	}

	if (p != path) {
		*p = '\0';

		if (hyper_mkdir(path, mode) < 0)
			goto fail;

		*p = '/';
	}

	fprintf(stdout, "create directory %s\n", path);
	if (mkdir(path, mode) < 0 && errno != EEXIST) {
		perror("failed to create directory");
		goto fail;
	}
out:
	free(path);
	return 0;

fail:
	free(path);
	return -1;
}
Пример #4
0
static int hyper_create_parent_dir(const char *hyper_path)
{
	char *p, *path = strdup(hyper_path);
	int ret = 0;

	if (path == NULL)
		return -1;
	p = strrchr(path, '/');
	if (p != NULL && p != path) {
		*p = '\0';
		ret = hyper_mkdir(path, 0777);
	}
	free(path);

	return ret;
}
Пример #5
0
static int hyper_setup_pty(struct hyper_container *c)
{
	char root[512];

	sprintf(root, "/tmp/hyper/%s/devpts/", c->id);

	if (hyper_mkdir(root) < 0) {
		perror("make container pts directroy failed");
		return -1;
	}

	if (mount("devpts", root, "devpts", MS_NOSUID,
		  "newinstance,ptmxmode=0666,mode=0620") < 0) {
		perror("mount devpts failed");
		return -1;
	}

	if (hyper_setup_exec_tty(&c->exec) < 0) {
		fprintf(stderr, "setup container pts failed\n");
		return -1;
	}

	return 0;
}
Пример #6
0
static int container_setup_mount(struct hyper_container *container)
{
	int i, fd;
	char src[512];
	struct fsmap *map;

	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) {
		perror("mount basic filesystem for container failed");
		return -1;
	}

	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) {
		perror("mount shm failed");
		return -1;
	}

	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) {
		fprintf(stderr, "get container devpts failed\n");
		return -1;
	}

	if (mount(src, "/dev/pts/", NULL, MS_BIND, NULL) < 0) {
		perror("move pts to /dev/pts failed");
		return -1;
	}

	if (unlink("/dev/ptmx") < 0)
		perror("remove /dev/ptmx failed");
	if (symlink("/dev/pts/ptmx", "/dev/ptmx") < 0)
		perror("link /dev/pts/ptmx to /dev/ptmx failed");

	for (i = 0; i < container->maps_num; i++) {
		struct stat st;

		map = &container->maps[i];

		sprintf(src, "/.oldroot/tmp/hyper/shared/%s", map->source);
		fprintf(stdout, "mount %s to %s\n", src, map->path);

		stat(src, &st);
		if (st.st_mode & S_IFDIR) {
			if (hyper_mkdir(map->path) < 0) {
				perror("create map dir failed");
				continue;
			}
		} else {
			fd = open(map->path, O_CREAT|O_WRONLY, 0755);
			if (fd < 0) {
				perror("create map file failed");
				continue;
			}
			close(fd);
		}

		if (mount(src, map->path, NULL, MS_BIND, NULL) < 0) {
			perror("mount fsmap faled");
			continue;
		}

		if (map->readonly == 0)
			continue;

		if (mount(src, map->path, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
			perror("mount fsmap faled");
	}

	return 0;
}
Пример #7
0
static int hyper_container_init(void *data)
{
	struct hyper_container_arg *arg = data;
	struct hyper_container *container = arg->c;
	char root[512], oldroot[512];

	fprintf(stdout, "%s in\n", __func__);
	if (container->exec.argv == NULL) {
		fprintf(stdout, "no cmd!\n");
		goto fail;
	}

	if (setns(arg->ipcns, CLONE_NEWIPC) < 0) {
		perror("setns to ipcns of pod init faild");
		goto fail;
	}

	if (setns(arg->utsns, CLONE_NEWUTS) < 0) {
		perror("setns to ipcns of pod init faild");
		goto fail;
	}

	if (hyper_rescan_scsi() < 0) {
		fprintf(stdout, "rescan scsi failed\n");
		goto fail;
	}

	if (hyper_setup_env(container->envs, container->envs_num) < 0) {
		fprintf(stdout, "setup env failed\n");
		goto fail;
	}

	if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
		perror("mount SLAVE failed");
		goto fail;
	}

	if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
		perror("mount PRIVATE failed");
		goto fail;
	}

	sprintf(root, "/tmp/hyper/%s/root/", container->id);
	if (hyper_mkdir(root) < 0) {
		perror("make root directroy failed");
		goto fail;
	}

	fprintf(stdout, "container root directory %s\n", root);

	if (container->fstype) {
		char dev[128];

		sprintf(dev, "/dev/%s", container->image);
		fprintf(stdout, "device %s\n", dev);

		if (mount(dev, root, container->fstype, 0, NULL) < 0) {
			perror("mount device failed");
			goto fail;
		}
	} else {
		char path[512];

		sprintf(path, "/tmp/hyper/shared/%s/", container->image);
		fprintf(stdout, "src directory %s\n", path);

		if (mount(path, root, NULL, MS_BIND, NULL) < 0) {
			perror("mount src dir failed");
			goto fail;
		}
	}

	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;
	}
	/* reuse oldroot array */
	sprintf(oldroot, "%s/%s/", root, container->rootfs);
	/* pivot_root won't work, see
	 * Documention/filesystem/ramfs-rootfs-initramfs.txt */
	chroot(oldroot);

	chdir("/");

	if (container_setup_volume(container) < 0) {
		fprintf(stderr, "container sets up voulme failed\n");
		goto fail;
	}

	if (container_setup_mount(container) < 0) {
		fprintf(stderr, "container sets up mount failed\n");
		goto fail;
	}

	if (container_setup_sysctl(container) < 0) {
		fprintf(stderr, "container sets up sysctl failed\n");
		goto fail;
	}

	if (container_setup_dns(container) < 0) {
		fprintf(stderr, "container sets up dns failed\n");
		goto fail;
	}

	if (container_setup_workdir(container) < 0) {
		fprintf(stderr, "container sets up work directory failed\n");
		goto fail;
	}

	container_unmount_oldroot("/.oldroot");

	fflush(stdout);

	if (container_setup_tty(arg->pipe[1], container) < 0) {
		fprintf(stdout, "setup tty failed\n");
		goto fail;
	}

	symlink("/proc/self/fd", "/dev/fd");
	symlink("/proc/self/fd/0", "/dev/stdin");
	symlink("/proc/self/fd/1", "/dev/stdout");
	symlink("/proc/self/fd/2", "/dev/stderr");

	execvp(container->exec.argv[0], container->exec.argv);
	perror("exec container command failed");

	_exit(-1);

fail:
	hyper_send_type(arg->pipe[1], ERROR);
	_exit(-1);
}
Пример #8
0
static int hyper_container_init(void *data)
{
	struct hyper_container_arg *arg = data;
	struct hyper_container *container = arg->c;
	char root[512], oldroot[512];

	fprintf(stdout, "%s in\n", __func__);
	if (container->exec.argv == NULL) {
		fprintf(stdout, "no cmd!\n");
		goto fail;
	}

	if (hyper_rescan_scsi() < 0) {
		fprintf(stdout, "rescan scsi failed\n");
		goto fail;
	}

	if (container_setup_env(container) < 0) {
		fprintf(stdout, "setup env failed\n");
		goto fail;
	}

	if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
		perror("mount SLAVE failed");
		goto fail;
	}

	if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
		perror("mount PRIVATE failed");
		goto fail;
	}

	sprintf(root, "/tmp/hyper/%s/root/", container->id);
	if (hyper_mkdir(root) < 0) {
		perror("make root directroy failed");
		goto fail;
	}

	fprintf(stdout, "container root directory %s\n", root);

	if (container->fstype) {
		char dev[128];

		sprintf(dev, "/dev/%s", container->image);
		fprintf(stdout, "device %s\n", dev);

		if (mount(dev, root, container->fstype, 0, NULL) < 0) {
			perror("mount device failed");
			goto fail;
		}
	} else {
		char path[512];

		sprintf(path, "/tmp/hyper/shared/%s/", container->image);
		fprintf(stdout, "src directory %s\n", path);

		if (mount(path, root, NULL, MS_BIND, NULL) < 0) {
			perror("mount src dir failed");
			goto fail;
		}
	}

	fprintf(stdout, "root directory for container is %s/%s, init task %s\n",
		root, container->rootfs, container->exec.argv[0]);

	hyper_list_dir(root);
	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;
	}
	/* reuse oldroot array */
	sprintf(oldroot, "%s/%s/", root, container->rootfs);
	/* pivot_root won't work, see
	 * Documention/filesystem/ramfs-rootfs-initramfs.txt */
	chroot(oldroot);

	chdir("/");

	if (container_setup_volume(container) < 0) {
		fprintf(stderr, "container sets up voulme failed\n");
		goto fail;
	}

	if (container_setup_mount(container) < 0) {
		fprintf(stderr, "container sets up mount ns failed\n");
		goto fail;
	}

	if (container_setup_workdir(container) < 0) {
		fprintf(stderr, "container sets up work directory failed\n");
		goto fail;
	}

	container_unmount_oldroot("/.oldroot");

	fflush(stdout);

	if (container_setup_tty(arg->pipe[1], container) < 0) {
		fprintf(stdout, "setup tty failed\n");
		goto fail;
	}

	close(arg->pipe[0]);
	close(arg->pipe[1]);

	execvp(container->exec.argv[0], container->exec.argv);

	_exit(-1);

fail:
	container->exec.code = -1;
	hyper_send_type_block(arg->pipe[1], ERROR, 0);
	_exit(-1);
}