mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-09-03 20:21:47 +00:00
support file destination volume
If a volume source contains only one file named ".hyper_file_volume_data_do_not_create_on_your_own", bind mount it as a file to the specified mountpoint inside container's namespace, rather than mounting its parent directory. The special name .hyper_file_volume_data_do_not_create_on_your_own is agreed upon with client which would save a file as this name if it wants to bind mount a single file rather than a directory. Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
+63
-9
@@ -49,6 +49,42 @@ static int container_populate_volume(char *src, char *dest)
|
||||
return hyper_copy_dir(src, dest);
|
||||
}
|
||||
|
||||
const char *INIT_VOLUME_FILENAME = ".hyper_file_volume_data_do_not_create_on_your_own";
|
||||
|
||||
static int container_check_file_volume(char *hyper_path, const char **filename)
|
||||
{
|
||||
struct dirent **list;
|
||||
struct stat stbuf;
|
||||
int i, num, found = 0;
|
||||
char path[PATH_MAX];
|
||||
|
||||
*filename = NULL;
|
||||
num = scandir(hyper_path, &list, NULL, NULL);
|
||||
if (num < 0) {
|
||||
perror("scan path failed");
|
||||
return -1;
|
||||
} else if (num != 3) {
|
||||
fprintf(stdout, "%s has %d files/dirs\n", hyper_path, num - 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf(path, "%s/%s", hyper_path, INIT_VOLUME_FILENAME);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (strcmp(list[i]->d_name, ".") != 0 &&
|
||||
strcmp(list[i]->d_name, "..") != 0 &&
|
||||
strcmp(list[i]->d_name, INIT_VOLUME_FILENAME) == 0 &&
|
||||
stat(path, &stbuf) == 0 && S_ISREG(stbuf.st_mode)) {
|
||||
found++;
|
||||
}
|
||||
free(list[i]);
|
||||
}
|
||||
free(list);
|
||||
|
||||
fprintf(stdout, "%s %s a file volume\n", hyper_path, found > 0?"is":"is not");
|
||||
*filename = found > 0 ? INIT_VOLUME_FILENAME : NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int container_setup_volume(struct hyper_container *container)
|
||||
{
|
||||
int i;
|
||||
@@ -59,6 +95,7 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
char volume[512];
|
||||
char mountpoint[512];
|
||||
char *options = NULL;
|
||||
const char *filevolume = NULL;
|
||||
vol = &container->vols[i];
|
||||
|
||||
if (vol->scsiaddr)
|
||||
@@ -66,13 +103,12 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
|
||||
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(mountpoint) < 0) {
|
||||
if (hyper_mkdir(path) < 0) {
|
||||
perror("create volume dir failed");
|
||||
return -1;
|
||||
}
|
||||
@@ -85,17 +121,35 @@ static int container_setup_volume(struct hyper_container *container)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vol->docker) {
|
||||
if (container->initialize &&
|
||||
(container_populate_volume(mountpoint, volume) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
|
||||
return -1;
|
||||
}
|
||||
} else if (hyper_mkdir(volume) < 0) {
|
||||
sprintf(volume, "/%s/_data", path);
|
||||
if (hyper_mkdir(volume) < 0) {
|
||||
fprintf(stderr, "fail to create directroy %s\n", volume);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (container_check_file_volume(volume, &filevolume) < 0)
|
||||
return -1;
|
||||
|
||||
if (filevolume == NULL) {
|
||||
if (hyper_mkdir(mountpoint) < 0) {
|
||||
perror("create volume dir failed");
|
||||
return -1;
|
||||
}
|
||||
if (vol->docker) {
|
||||
if (container->initialize &&
|
||||
(container_populate_volume(mountpoint, volume) < 0)) {
|
||||
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hyper_create_file(mountpoint) < 0) {
|
||||
perror("create volume file failed");
|
||||
return -1;
|
||||
}
|
||||
sprintf(volume, "/%s/_data/%s", path, filevolume);
|
||||
}
|
||||
|
||||
if (mount(volume, mountpoint, NULL, MS_BIND, NULL) < 0) {
|
||||
perror("mount volume device failed");
|
||||
return -1;
|
||||
|
||||
@@ -124,6 +124,7 @@ static inline int hyper_create(char *hyper_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_create_file(const char *hyper_path);
|
||||
int hyper_mkdir(char *hyper_path);
|
||||
int hyper_open_serial(char *tty);
|
||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
|
||||
|
||||
+20
@@ -233,6 +233,26 @@ int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroup
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hyper_create_file(const char *hyper_path)
|
||||
{
|
||||
int fd;
|
||||
struct stat stbuf;
|
||||
|
||||
if (stat(hyper_path, &stbuf) >= 0) {
|
||||
if (S_ISREG(stbuf.st_mode))
|
||||
return 0;
|
||||
errno = S_ISDIR(stbuf.st_mode) ? EISDIR : EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(hyper_path, O_CREAT|O_WRONLY, 0666);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
close(fd);
|
||||
fprintf(stdout, "created file %s\n", hyper_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_mkdir(char *hyper_path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
Reference in New Issue
Block a user