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) ...@@ -148,7 +148,7 @@ static struct cr_fdset *alloc_cr_fdset(void)
cr_fdset = xmalloc(sizeof(*cr_fdset)); cr_fdset = xmalloc(sizeof(*cr_fdset));
if (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; cr_fdset->fds[i] = -1;
return cr_fdset; return cr_fdset;
} }
...@@ -160,7 +160,7 @@ void __close_cr_fdset(struct cr_fdset *cr_fdset) ...@@ -160,7 +160,7 @@ void __close_cr_fdset(struct cr_fdset *cr_fdset)
if (!cr_fdset) if (!cr_fdset)
return; return;
for (i = 0; i < CR_FD_MAX; i++) { for (i = 0; i < CR_FD_PID_MAX; i++) {
if (cr_fdset->fds[i] == -1) if (cr_fdset->fds[i] == -1)
continue; continue;
close_safe(&cr_fdset->fds[i]); close_safe(&cr_fdset->fds[i]);
...@@ -185,7 +185,6 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask, ...@@ -185,7 +185,6 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
struct cr_fdset *fdset; struct cr_fdset *fdset;
unsigned int i; unsigned int i;
int ret = -1; int ret = -1;
char path[PATH_MAX];
/* /*
* We either reuse existing fdset or create new one. * 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, ...@@ -197,46 +196,22 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
} else } else
fdset = cr_fdset; 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))) if (!(use_mask & CR_FD_DESC_USE(i)))
continue; continue;
if (fdset->fds[i] != -1) if (fdset->fds[i] != -1)
continue; continue;
sprintf(path, fdset_template[i].fmt, pid); ret = open_image(i, flags, 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);
if (ret < 0) { if (ret < 0) {
if (!(flags & O_CREAT)) if (!(flags & O_CREAT))
/* caller should check himself */ /* caller should check himself */
continue; continue;
pr_perror("Unable to open %s", path);
goto err; goto err;
} }
fdset->fds[i] = ret;
if (flags == O_RDONLY) { fdset->fds[i] = ret;
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;
}
} }
return fdset; return fdset;
......
...@@ -44,6 +44,8 @@ enum { ...@@ -44,6 +44,8 @@ enum {
CR_FD_SK_QUEUES, CR_FD_SK_QUEUES,
CR_FD_PID_MAX, /* fmt, pid */
CR_FD_MAX CR_FD_MAX
}; };
...@@ -98,14 +100,16 @@ extern struct cr_fd_desc_tmpl fdset_template[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 image_dir_fd;
extern int open_image_dir(void); extern int open_image_dir(void);
extern void close_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); extern int open_image_ro_nocheck(const char *fmt, int pid);
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid" #define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
#define LAST_PID_PERM 0666 #define LAST_PID_PERM 0666
struct cr_fdset { struct cr_fdset {
int fds[CR_FD_MAX]; int fds[CR_FD_PID_MAX];
}; };
#define CR_FD_DESC_USE(type) ((1 << (type))) #define CR_FD_DESC_USE(type) ((1 << (type)))
......
...@@ -161,23 +161,47 @@ int open_image_ro_nocheck(const char *fmt, int pid) ...@@ -161,23 +161,47 @@ int open_image_ro_nocheck(const char *fmt, int pid)
return tmp; return tmp;
} }
int open_image_ro(int type, int pid) int open_image(int type, unsigned long flags, ...)
{ {
int fd; char path[PATH_MAX];
u32 magic = 0; va_list args;
int ret;
fd = open_image_ro_nocheck(fdset_template[type].fmt, pid); va_start(args, flags);
if (fd < 0) vsnprintf(path, PATH_MAX, fdset_template[type].fmt, args);
return fd; va_end(args);
read(fd, &magic, sizeof(magic)); if (flags & O_EXCL) {
if (magic != fdset_template[type].magic) { ret = unlinkat(image_dir_fd, path, 0);
pr_err("Magic mismatch for %d of %d\n", type, pid); if (ret && errno != ENOENT) {
close(fd); pr_perror("Unable to unlink %s", path);
return -1; goto err;
}
} }
return fd; 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 doesn't match for %s\n", path);
goto err;
}
} else {
if (write_img(ret, &fdset_template[type].magic))
goto err;
}
return ret;
err:
return -1;
} }
int image_dir_fd = -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