Commit 5ca34788 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: support any format of image path (v3)

Now a name of an image file is hard coded ("smth-%d.img", pid),
but the images of namespaces, shared memery, etc belong to
not one task, so they may have other formats of names, which
will describe objects.

For example a image of shared memory content may have name like
this ("pages-shmem-%ld.img", shmid)

v2: fix comment
v3: rebase
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent d463b15b
......@@ -148,7 +148,7 @@ static struct cr_fdset *alloc_cr_fdset(void)
cr_fdset = xmalloc(sizeof(*cr_fdset));
if (cr_fdset)
for (i = 0; i < CR_FD_MAX; i++)
for (i = 0; i < CR_FD_PID_MAX; i++)
cr_fdset->fds[i] = -1;
return cr_fdset;
}
......@@ -160,7 +160,7 @@ void __close_cr_fdset(struct cr_fdset *cr_fdset)
if (!cr_fdset)
return;
for (i = 0; i < CR_FD_MAX; i++) {
for (i = 0; i < CR_FD_PID_MAX; i++) {
if (cr_fdset->fds[i] == -1)
continue;
close_safe(&cr_fdset->fds[i]);
......@@ -185,7 +185,6 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
struct cr_fdset *fdset;
unsigned int i;
int ret = -1;
char path[PATH_MAX];
/*
* We either reuse existing fdset or create new one.
......@@ -197,46 +196,22 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
} else
fdset = cr_fdset;
for (i = 0; i < CR_FD_MAX; i++) {
for (i = 0; i < CR_FD_PID_MAX; i++) {
if (!(use_mask & CR_FD_DESC_USE(i)))
continue;
if (fdset->fds[i] != -1)
continue;
sprintf(path, fdset_template[i].fmt, pid);
if (flags & O_EXCL) {
ret = unlinkat(image_dir_fd, path, 0);
if (ret && errno != ENOENT) {
pr_perror("Unable to unlink %s", path);
goto err;
}
}
ret = openat(image_dir_fd, path, flags, CR_FD_PERM);
ret = open_image(i, flags, pid);
if (ret < 0) {
if (!(flags & O_CREAT))
/* caller should check himself */
continue;
pr_perror("Unable to open %s", path);
goto err;
}
fdset->fds[i] = ret;
if (flags == O_RDONLY) {
u32 magic;
if (read_img(ret, &magic) < 0)
goto err;
if (magic != fdset_template[i].magic) {
pr_err("Magic doesn't match for %s\n", path);
goto err;
}
} else {
if (write_img(ret, &fdset_template[i].magic))
goto err;
}
fdset->fds[i] = ret;
}
return fdset;
......
......@@ -44,6 +44,8 @@ enum {
CR_FD_SK_QUEUES,
CR_FD_PID_MAX, /* fmt, pid */
CR_FD_MAX
};
......@@ -98,14 +100,16 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
extern int image_dir_fd;
extern int open_image_dir(void);
extern void close_image_dir(void);
extern int open_image_ro(int type, int pid);
int open_image(int type, unsigned long flags, ...);
#define open_image_ro(type, ...) open_image(type, O_RDONLY, __VA_ARGS__);
extern int open_image_ro_nocheck(const char *fmt, int pid);
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
#define LAST_PID_PERM 0666
struct cr_fdset {
int fds[CR_FD_MAX];
int fds[CR_FD_PID_MAX];
};
#define CR_FD_DESC_USE(type) ((1 << (type)))
......
......@@ -161,23 +161,47 @@ int open_image_ro_nocheck(const char *fmt, int pid)
return tmp;
}
int open_image_ro(int type, int pid)
int open_image(int type, unsigned long flags, ...)
{
int fd;
u32 magic = 0;
char path[PATH_MAX];
va_list args;
int ret;
fd = open_image_ro_nocheck(fdset_template[type].fmt, pid);
if (fd < 0)
return fd;
va_start(args, flags);
vsnprintf(path, PATH_MAX, fdset_template[type].fmt, args);
va_end(args);
if (flags & O_EXCL) {
ret = unlinkat(image_dir_fd, path, 0);
if (ret && errno != ENOENT) {
pr_perror("Unable to unlink %s", path);
goto err;
}
}
read(fd, &magic, sizeof(magic));
ret = openat(image_dir_fd, path, flags, CR_FD_PERM);
if (ret < 0) {
pr_perror("Unable to open %s", path);
goto err;
}
if (flags == O_RDONLY) {
u32 magic;
if (read_img(ret, &magic) < 0)
goto err;
if (magic != fdset_template[type].magic) {
pr_err("Magic mismatch for %d of %d\n", type, pid);
close(fd);
return -1;
pr_err("Magic doesn't match for %s\n", path);
goto err;
}
} else {
if (write_img(ret, &fdset_template[type].magic))
goto err;
}
return fd;
return ret;
err:
return -1;
}
int image_dir_fd = -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment