Commit 3c8bd5cc authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

pstree: allocate fdt shared data

fdt shared data contains PID of process, which will restore file
descriptors and a futex for synchronization.

A process with mimimal pid restores file descriptors.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 0ec10e4e
......@@ -8,6 +8,7 @@
#include "list.h"
#include "util.h"
#include "image.h"
#include "lock.h"
#include "../protobuf/vma.pb-c.h"
......@@ -231,6 +232,16 @@ struct vma_area {
#define vma_area_is(vma_area, s) vma_entry_is(&((vma_area)->vma), s)
#define vma_area_len(vma_area) vma_entry_len(&((vma_area)->vma))
struct fdt {
int nr; /* How many tasks share this fd table */
pid_t pid; /* Who should restore this fd table */
/*
* The fd table is ready for restoing, if fdt_lock is equal to nr
* The fdt table was restrored, if fdt_lock is equal to nr + 1
*/
futex_t fdt_lock;
};
struct rst_info {
struct list_head fds;
struct list_head eventpoll;
......@@ -238,6 +249,8 @@ struct rst_info {
void *premmapped_addr;
unsigned long premmapped_len;
struct fdt *fdt;
};
static inline int in_vma_area(struct vma_area *vma, unsigned long addr)
......
......@@ -46,6 +46,14 @@ struct pstree_item {
struct rst_info rst[0];
};
static inline int shared_fdtable(struct pstree_item *item) {
return (item->parent && item->parent->state != TASK_HELPER &&
item->ids &&
item->parent->ids &&
item->ids->files_id &&
item->ids->files_id == item->parent->ids->files_id);
}
extern void free_pstree(struct pstree_item *root_item);
extern struct pstree_item *__alloc_pstree_item(bool rst);
#define alloc_pstree_item() __alloc_pstree_item(false)
......
......@@ -5,6 +5,7 @@
#include "pstree.h"
#include "restorer.h"
#include "util.h"
#include "lock.h"
#include "protobuf.h"
#include "protobuf/pstree.pb-c.h"
......@@ -434,6 +435,39 @@ static int prepare_pstree_ids(void)
helper->pid.virt, helper->pgid);
}
/* Find a process with minimal pid for shared fd tables */
for_each_pstree_item(item) {
struct pstree_item *parent = item->parent;
struct fdt *fdt;
if (item->state == TASK_HELPER)
continue;
if (parent == NULL)
continue;
if (!shared_fdtable(item))
continue;
if (!parent->rst->fdt) {
fdt = shmalloc(sizeof(*item->rst->fdt));
if (fdt == NULL)
return -1;
parent->rst->fdt = fdt;
futex_init(&fdt->fdt_lock);
fdt->nr = 1;
fdt->pid = parent->pid.virt;
} else
fdt = parent->rst->fdt;
item->rst->fdt = fdt;
fdt->nr++;
if (fdt->pid > item->pid.virt)
fdt->pid = item->pid.virt;
}
return 0;
}
......
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