Commit 1fb1d941 authored by Pavel Emelyanov's avatar Pavel Emelyanov

fdset: Introduce new fdsets

Current fdsets are ugly, limited (bitmask will exhaust in several months) and
suffer from unknown problems with fdsets reuse :(

With new approach (this set) the images management is simple. The basic function
is open_image, which gives you an fd for an image. If you want to pre-open several
images at once instead of calling open_image every single time, you can use the
new fdsets.

Images CR_FD_ descriptors should be grouped like

_CR_FD_FOO_FROM,
CR_FD_FOO_ITEM1,
CR_FD_FOO_ITEM2,
..
CR_FD_FOO_ITEMN,
_CR_FD_FOO_TO,

After this you can call cr_fd_open() specifying ranges -- _FROM and _TO macros,
it will give you an cr_fdset object. Then the fdset_fd(set, type) will give you
the descriptor of the open "set" group corresponding to the "type" type.

3 groups are introduced in this set -- tasks, ns and global.

That's it.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 44a6dd4f
...@@ -145,15 +145,22 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = { ...@@ -145,15 +145,22 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
}, },
}; };
static struct cr_fdset *alloc_cr_fdset(void) static struct cr_fdset *alloc_cr_fdset(int nr)
{ {
struct cr_fdset *cr_fdset; struct cr_fdset *cr_fdset;
unsigned int i; unsigned int i;
cr_fdset = xmalloc(sizeof(*cr_fdset)); cr_fdset = xmalloc(sizeof(*cr_fdset));
if (cr_fdset) if (cr_fdset == NULL)
for (i = 0; i < CR_FD_PID_MAX; i++) return NULL;
cr_fdset->_fds[i] = -1;
cr_fdset->_fds = xmalloc(nr * sizeof(int));
if (cr_fdset->_fds == NULL) {
xfree(cr_fdset);
return NULL;
}
cr_fdset->fd_nr = nr;
return cr_fdset; return cr_fdset;
} }
...@@ -164,7 +171,7 @@ static void __close_cr_fdset(struct cr_fdset *cr_fdset) ...@@ -164,7 +171,7 @@ static void __close_cr_fdset(struct cr_fdset *cr_fdset)
if (!cr_fdset) if (!cr_fdset)
return; return;
for (i = 0; i < CR_FD_PID_MAX; i++) { for (i = 0; i < cr_fdset->fd_nr; 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]);
...@@ -179,30 +186,25 @@ void close_cr_fdset(struct cr_fdset **cr_fdset) ...@@ -179,30 +186,25 @@ void close_cr_fdset(struct cr_fdset **cr_fdset)
__close_cr_fdset(*cr_fdset); __close_cr_fdset(*cr_fdset);
xfree((*cr_fdset)->_fds);
xfree(*cr_fdset); xfree(*cr_fdset);
*cr_fdset = NULL; *cr_fdset = NULL;
} }
#define CR_FD_DESC_USE(type) ((1 << (type))) static struct cr_fdset *cr_fdset_open(int pid, int from, int to,
static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
unsigned long flags) unsigned long flags)
{ {
struct cr_fdset *fdset; struct cr_fdset *fdset;
unsigned int i; unsigned int i;
int ret = -1; int ret = -1;
fdset = alloc_cr_fdset(); fdset = alloc_cr_fdset(to - from);
if (!fdset) if (!fdset)
goto err; goto err;
for (i = 0; i < CR_FD_PID_MAX; i++) { from++;
if (!(use_mask & CR_FD_DESC_USE(i))) fdset->fd_off = from;
continue; for (i = from; i < to; i++) {
if (fdset->_fds[i] != -1)
continue;
ret = open_image(i, flags, pid); ret = open_image(i, flags, pid);
if (ret < 0) { if (ret < 0) {
if (!(flags & O_CREAT)) if (!(flags & O_CREAT))
...@@ -211,7 +213,7 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask, ...@@ -211,7 +213,7 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
goto err; goto err;
} }
fdset->_fds[i] = ret; fdset->_fds[i - from] = ret;
} }
return fdset; return fdset;
...@@ -221,33 +223,14 @@ err: ...@@ -221,33 +223,14 @@ err:
return NULL; return NULL;
} }
#define CR_FD_DESC_TASK (\
CR_FD_DESC_USE(CR_FD_FDINFO) |\
CR_FD_DESC_USE(CR_FD_PAGES) |\
CR_FD_DESC_USE(CR_FD_CORE) |\
CR_FD_DESC_USE(CR_FD_VMAS) |\
CR_FD_DESC_USE(CR_FD_PIPES) |\
CR_FD_DESC_USE(CR_FD_SIGACT) |\
CR_FD_DESC_USE(CR_FD_UNIXSK) |\
CR_FD_DESC_USE(CR_FD_INETSK) |\
CR_FD_DESC_USE(CR_FD_ITIMERS) |\
CR_FD_DESC_USE(CR_FD_CREDS) )
struct cr_fdset *cr_task_fdset_open(int pid, int mode) struct cr_fdset *cr_task_fdset_open(int pid, int mode)
{ {
return cr_fdset_open(pid, CR_FD_DESC_TASK, mode); return cr_fdset_open(pid, _CR_FD_TASK_FROM, _CR_FD_TASK_TO, mode);
} }
#define CR_FD_DESC_NS (\
CR_FD_DESC_USE(CR_FD_UTSNS) |\
CR_FD_DESC_USE(CR_FD_IPCNS_VAR) |\
CR_FD_DESC_USE(CR_FD_IPCNS_MSG) |\
CR_FD_DESC_USE(CR_FD_IPCNS_SEM) |\
CR_FD_DESC_USE(CR_FD_IPCNS_SHM) )
struct cr_fdset *cr_ns_fdset_open(int pid, int mode) struct cr_fdset *cr_ns_fdset_open(int pid, int mode)
{ {
return cr_fdset_open(pid, CR_FD_DESC_NS, mode); return cr_fdset_open(pid, _CR_FD_NS_FROM, _CR_FD_NS_TO, mode);
} }
static int parse_ns_string(const char *ptr, unsigned int *flags) static int parse_ns_string(const char *ptr, unsigned int *flags)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "types.h" #include "types.h"
#include "list.h" #include "list.h"
#include "util.h"
#include "image.h" #include "image.h"
extern struct page_entry zero_page_entry; extern struct page_entry zero_page_entry;
...@@ -19,6 +19,7 @@ enum { ...@@ -19,6 +19,7 @@ enum {
* Task entries * Task entries
*/ */
_CR_FD_TASK_FROM,
CR_FD_FDINFO, CR_FD_FDINFO,
CR_FD_PAGES, CR_FD_PAGES,
CR_FD_CORE, CR_FD_CORE,
...@@ -29,18 +30,19 @@ enum { ...@@ -29,18 +30,19 @@ enum {
CR_FD_INETSK, CR_FD_INETSK,
CR_FD_ITIMERS, CR_FD_ITIMERS,
CR_FD_CREDS, CR_FD_CREDS,
_CR_FD_TASK_TO,
/* /*
* Global entries * NS entries
*/ */
_CR_FD_NS_FROM,
CR_FD_UTSNS, CR_FD_UTSNS,
CR_FD_IPCNS_VAR, CR_FD_IPCNS_VAR,
CR_FD_IPCNS_SHM, CR_FD_IPCNS_SHM,
CR_FD_IPCNS_MSG, CR_FD_IPCNS_MSG,
CR_FD_IPCNS_SEM, CR_FD_IPCNS_SEM,
_CR_FD_NS_TO,
CR_FD_PID_MAX, /* fmt, pid */
CR_FD_PSTREE, CR_FD_PSTREE,
CR_FD_SHMEM_PAGES, CR_FD_SHMEM_PAGES,
...@@ -112,12 +114,19 @@ extern int open_image_ro_nocheck(const char *fmt, ...); ...@@ -112,12 +114,19 @@ extern int open_image_ro_nocheck(const char *fmt, ...);
#define LAST_PID_PERM 0666 #define LAST_PID_PERM 0666
struct cr_fdset { struct cr_fdset {
int _fds[CR_FD_PID_MAX]; int fd_off;
int fd_nr;
int *_fds;
}; };
static inline int fdset_fd(const struct cr_fdset *fdset, int type) static inline int fdset_fd(const struct cr_fdset *fdset, int type)
{ {
return fdset->_fds[type]; int idx;
idx = type - fdset->fd_off;
BUG_ON(idx > fdset->fd_nr);
return fdset->_fds[idx];
} }
int cr_dump_tasks(pid_t pid, const struct cr_options *opts); int cr_dump_tasks(pid_t pid, const struct cr_options *opts);
......
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