Commit 7960379f authored by Pavel Emelyanov's avatar Pavel Emelyanov

flock: Merge all file lock entries into single image file

They are now in per-pid images, but every entry contains a
pid to which it "belongs". This belonging is fake -- it's
just a pid of a task who placed the lock, while locks really
belong to files. We even have a bug when task that locked
a file exited and "delegated" the lock to its child.

This images merge reduces the amount of image files criu
generates and may simplify the fix of mentioned above issue.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 4816882d
......@@ -70,6 +70,7 @@
#include "plugin.h"
#include "cgroup.h"
#include "timerfd.h"
#include "file-lock.h"
#include "parasite-syscall.h"
......@@ -155,6 +156,7 @@ static struct collect_image_info *cinfos[] = {
&tunfile_cinfo,
&ext_file_cinfo,
&timerfd_cinfo,
&file_locks_cinfo,
};
static int root_prepare_shared(void)
......
......@@ -14,8 +14,31 @@
#include "parasite.h"
#include "parasite-syscall.h"
struct file_lock_rst {
FileLockEntry *fle;
struct list_head l;
};
struct list_head file_lock_list = LIST_HEAD_INIT(file_lock_list);
static int collect_one_file_lock(void *o, ProtobufCMessage *m)
{
struct file_lock_rst *lr = o;
lr->fle = pb_msg(m, FileLockEntry);
list_add_tail(&lr->l, &file_lock_list);
return 0;
}
struct collect_image_info file_locks_cinfo = {
.fd_type = CR_FD_FILE_LOCKS,
.pb_type = PB_FILE_LOCK,
.priv_size = sizeof(struct file_lock_rst),
.collect = collect_one_file_lock,
.flags = COLLECT_OPTIONAL,
};
struct file_lock *alloc_file_lock(void)
{
struct file_lock *flock;
......@@ -45,7 +68,7 @@ static int dump_one_file_lock(FileLockEntry *fle, const struct cr_fdset *fdset)
pr_info("flag: %d,type: %d,pid: %d,fd: %d,start: %8"PRIx64",len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd, fle->start, fle->len);
return pb_write_one(fdset_fd(fdset, CR_FD_FILE_LOCKS),
return pb_write_one(fdset_fd(glob_fdset, CR_FD_FILE_LOCKS),
fle, PB_FILE_LOCK);
}
......@@ -222,6 +245,22 @@ err:
}
static int restore_file_locks(int pid)
{
int ret = 0;
struct file_lock_rst *lr;
list_for_each_entry(lr, &file_lock_list, l) {
if (lr->fle->pid == pid) {
ret = restore_file_lock(lr->fle);
if (ret)
break;
}
}
return ret;
}
static int restore_file_locks_legacy(int pid)
{
int fd, ret = -1;
FileLockEntry *fle;
......@@ -255,6 +294,8 @@ int prepare_file_locks(int pid)
return 0;
pr_info("Restore file locks.\n");
if (file_locks_cinfo.flags & COLLECT_HAPPENED)
return restore_file_locks(pid);
return restore_file_locks_legacy(pid);
}
......@@ -69,7 +69,7 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
FD_ENTRY(TMPFS_DEV, "tmpfs-dev-%d.tar.gz"),
FD_ENTRY(TTY_FILES, "tty"),
FD_ENTRY(TTY_INFO, "tty-info"),
FD_ENTRY(FILE_LOCKS, "filelocks-%d"),
FD_ENTRY(FILE_LOCKS, "filelocks"),
FD_ENTRY(RLIMIT, "rlimit-%d"),
FD_ENTRY(PAGES, "pages-%u"),
FD_ENTRY(PAGES_OLD, "pages-%d"),
......@@ -89,4 +89,9 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
.fmt = "irmap-cache",
.magic = IRMAP_CACHE_MAGIC,
},
[CR_FD_FILE_LOCKS_PID] = {
.fmt = "filelocks-%d",
.magic = FILE_LOCKS_MAGIC,
},
};
......@@ -53,6 +53,7 @@ extern int dump_task_file_locks(struct parasite_ctl *ctl,
struct cr_fdset *fdset, struct parasite_drain_fd *dfds);
extern int prepare_file_locks(int pid);
extern struct collect_image_info file_locks_cinfo;
#define OPT_FILE_LOCKS "file-locks"
......
......@@ -11,7 +11,6 @@ enum {
*/
_CR_FD_TASK_FROM,
CR_FD_FILE_LOCKS,
CR_FD_CORE,
CR_FD_IDS,
CR_FD_MM,
......@@ -76,6 +75,7 @@ enum {
CR_FD_TUNFILE,
CR_FD_CGROUP,
CR_FD_TIMERFD,
CR_FD_FILE_LOCKS,
_CR_FD_GLOB_TO,
CR_FD_TMPFS_IMG,
......@@ -89,6 +89,7 @@ enum {
CR_FD_RLIMIT,
CR_FD_ITIMERS,
CR_FD_POSIX_TIMERS,
CR_FD_FILE_LOCKS_PID,
CR_FD_IRMAP_CACHE,
......
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