Commit b0e23c3d authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Collect ghosts and regilfes early

Info about ghosts presence and paths will be needed to
remove the ghosts itself and thus are needed in criu.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 4f7c8af0
...@@ -126,6 +126,10 @@ static int crtools_prepare_shared(void) ...@@ -126,6 +126,10 @@ static int crtools_prepare_shared(void)
if (prepare_shared_fdinfo()) if (prepare_shared_fdinfo())
return -1; return -1;
/* We might want to remove ghost files on failed restore */
if (collect_remaps_and_regfiles())
return -1;
/* Connections are unlocked from criu */ /* Connections are unlocked from criu */
if (collect_inet_sockets()) if (collect_inet_sockets())
return -1; return -1;
...@@ -149,8 +153,6 @@ static int crtools_prepare_shared(void) ...@@ -149,8 +153,6 @@ static int crtools_prepare_shared(void)
*/ */
static struct collect_image_info *cinfos[] = { static struct collect_image_info *cinfos[] = {
&reg_file_cinfo,
&remap_cinfo,
&nsfile_cinfo, &nsfile_cinfo,
&pipe_cinfo, &pipe_cinfo,
&fifo_cinfo, &fifo_cinfo,
...@@ -186,6 +188,9 @@ static int root_prepare_shared(void) ...@@ -186,6 +188,9 @@ static int root_prepare_shared(void)
if (prepare_shared_reg_files()) if (prepare_shared_reg_files())
return -1; return -1;
if (prepare_remaps())
return -1;
for (i = 0; i < ARRAY_SIZE(cinfos); i++) { for (i = 0; i < ARRAY_SIZE(cinfos); i++) {
ret = collect_image(cinfos[i]); ret = collect_image(cinfos[i]);
if (ret) if (ret)
......
...@@ -301,25 +301,19 @@ static int open_remap_dead_process(struct reg_file_info *rfi, ...@@ -301,25 +301,19 @@ static int open_remap_dead_process(struct reg_file_info *rfi,
return 0; return 0;
} }
struct remap_info {
struct list_head list;
RemapFilePathEntry *rfe;
struct reg_file_info *rfi;
};
static int collect_one_remap(void *obj, ProtobufCMessage *msg) static int collect_one_remap(void *obj, ProtobufCMessage *msg)
{ {
int ret = -1; struct remap_info *ri = obj;
RemapFilePathEntry *rfe; RemapFilePathEntry *rfe;
struct file_desc *fdesc; struct file_desc *fdesc;
struct reg_file_info *rfi;
rfe = pb_msg(msg, RemapFilePathEntry);
fdesc = find_file_desc_raw(FD_TYPES__REG, rfe->orig_id);
if (fdesc == NULL) {
pr_err("Remap for non existing file %#x\n",
rfe->orig_id);
goto out;
}
rfi = container_of(fdesc, struct reg_file_info, d);
pr_info("Configuring remap %#x -> %#x\n", rfi->rfe->id, rfe->remap_id);
ri->rfe = rfe = pb_msg(msg, RemapFilePathEntry);
if (!rfe->has_remap_type) { if (!rfe->has_remap_type) {
rfe->has_remap_type = true; rfe->has_remap_type = true;
...@@ -331,6 +325,27 @@ static int collect_one_remap(void *obj, ProtobufCMessage *msg) ...@@ -331,6 +325,27 @@ static int collect_one_remap(void *obj, ProtobufCMessage *msg)
rfe->remap_type = REMAP_TYPE__LINKED; rfe->remap_type = REMAP_TYPE__LINKED;
} }
fdesc = find_file_desc_raw(FD_TYPES__REG, rfe->orig_id);
if (fdesc == NULL) {
pr_err("Remap for non existing file %#x\n", rfe->orig_id);
return -1;
}
ri->rfi = container_of(fdesc, struct reg_file_info, d);
list_add_tail(&ri->list, &remaps);
return 0;
}
static int prepare_one_remap(struct remap_info *ri)
{
int ret = -1;
RemapFilePathEntry *rfe = ri->rfe;
struct reg_file_info *rfi = ri->rfi;
pr_info("Configuring remap %#x -> %#x\n", rfi->rfe->id, rfe->remap_id);
switch (rfe->remap_type) { switch (rfe->remap_type) {
case REMAP_TYPE__LINKED: case REMAP_TYPE__LINKED:
ret = open_remap_linked(rfi, rfe); ret = open_remap_linked(rfi, rfe);
...@@ -350,9 +365,24 @@ out: ...@@ -350,9 +365,24 @@ out:
return ret; return ret;
} }
struct collect_image_info remap_cinfo = { int prepare_remaps(void)
{
struct remap_info *ri;
int ret = 0;
list_for_each_entry(ri, &remaps, list) {
ret = prepare_one_remap(ri);
if (ret)
break;
}
return ret;
}
static struct collect_image_info remap_cinfo = {
.fd_type = CR_FD_REMAP_FPATH, .fd_type = CR_FD_REMAP_FPATH,
.pb_type = PB_REMAP_FPATH, .pb_type = PB_REMAP_FPATH,
.priv_size = sizeof(struct remap_info),
.collect = collect_one_remap, .collect = collect_one_remap,
}; };
...@@ -1273,7 +1303,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base) ...@@ -1273,7 +1303,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base)
return file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops); return file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops);
} }
struct collect_image_info reg_file_cinfo = { static struct collect_image_info reg_file_cinfo = {
.fd_type = CR_FD_REG_FILES, .fd_type = CR_FD_REG_FILES,
.pb_type = PB_REG_FILE, .pb_type = PB_REG_FILE,
.priv_size = sizeof(struct reg_file_info), .priv_size = sizeof(struct reg_file_info),
...@@ -1289,3 +1319,14 @@ int prepare_shared_reg_files(void) ...@@ -1289,3 +1319,14 @@ int prepare_shared_reg_files(void)
mutex_init(ghost_file_mutex); mutex_init(ghost_file_mutex);
return 0; return 0;
} }
int collect_remaps_and_regfiles(void)
{
if (collect_image(&reg_file_cinfo))
return -1;
if (collect_image(&remap_cinfo))
return -1;
return 0;
}
...@@ -45,11 +45,11 @@ extern void remap_put(struct file_remap *remap); ...@@ -45,11 +45,11 @@ extern void remap_put(struct file_remap *remap);
extern struct file_desc *try_collect_special_file(u32 id, int optional); extern struct file_desc *try_collect_special_file(u32 id, int optional);
#define collect_special_file(id) try_collect_special_file(id, 0) #define collect_special_file(id) try_collect_special_file(id, 0)
extern struct collect_image_info reg_file_cinfo; extern int collect_remaps_and_regfiles(void);
extern struct collect_image_info remap_cinfo;
extern void delete_link_remaps(void); extern void delete_link_remaps(void);
extern void free_link_remaps(void); extern void free_link_remaps(void);
extern int prepare_remaps(void);
extern int strip_deleted(struct fd_link *link); extern int strip_deleted(struct fd_link *link);
......
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