[CRIU] [PATCH 7/8] files: add ability to set callbacks for character devices
Andrey Vagin
avagin at openvz.org
Tue Dec 10 08:26:01 PST 2013
The difference in compare with unix sockets is that dump callbacks
for character devices can be executed to test, which callback can be
used for a given fd.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
files-reg.c | 16 ++++++++++++++++
files.c | 14 ++++++++++++++
include/criu-plugin.h | 3 +++
include/files.h | 2 ++
include/plugin.h | 4 ++++
plugin.c | 21 +++++++++++++++++++++
protobuf/regfile.proto | 1 +
7 files changed, 61 insertions(+)
diff --git a/files-reg.c b/files-reg.c
index fb5d7ca..8d48bc0 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -20,6 +20,7 @@
#include "protobuf/remap-file-path.pb-c.h"
#include "files-reg.h"
+#include "plugin.h"
/*
* Ghost files are those not visible from the FS. Dumping them is
@@ -484,6 +485,13 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
+ if (p->cb) {
+ if (p->cb(lfd, id, false))
+ return -1;
+ rfe.has_need_callback = true;
+ rfe.need_callback = true;
+ }
+
if (!p->link) {
if (fill_fdlink(lfd, p, &_link))
return -1;
@@ -583,6 +591,14 @@ static int do_open_reg(struct reg_file_info *rfi, void *arg)
return fd;
}
+ if (rfi->rfe->need_callback) {
+ if (cr_plugin_restore_file(fd, rfi->rfe->id)) {
+ pr_err("Unable to restore %#x\n", rfi->rfe->id);
+ close(fd);
+ }
+ return fd;
+ }
+
if ((rfi->rfe->pos != -1ULL) &&
lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
pr_perror("Can't restore file pos");
diff --git a/files.c b/files.c
index 6eb7282..8ff05a3 100644
--- a/files.c
+++ b/files.c
@@ -39,6 +39,8 @@
#include "protobuf.h"
#include "protobuf/fs.pb-c.h"
+#include "plugin.h"
+
#define FDESC_HASH_SIZE 64
static struct hlist_head file_desc_hash[FDESC_HASH_SIZE];
@@ -276,7 +278,19 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const int fdinfo)
break;
/* fallthrough */
default: {
+ cr_plugin_dump_file_t *cb;
char more[32];
+ int ret;
+
+ ret = cr_plugin_dump_file(lfd, 0, true, &cb);
+ if (ret < 0 && ret != CRIU_CB_SKIP)
+ return -1;
+
+ if (ret == 0) {
+ p->cb = cb;
+ ops = ®file_dump_ops;
+ break;
+ }
sprintf(more, "%d:%d", maj, minor(p->stat.st_dev));
return dump_unsupp_fd(p, "chr", more);
diff --git a/include/criu-plugin.h b/include/criu-plugin.h
index d4ea30c..53efa41 100644
--- a/include/criu-plugin.h
+++ b/include/criu-plugin.h
@@ -21,6 +21,7 @@
#define __CRIU_PLUGIN_H__
#include <limits.h>
+#include <stdbool.h>
typedef int (cr_plugin_init_t)(void);
typedef void (cr_plugin_fini_t)(void);
@@ -31,6 +32,8 @@ typedef void (cr_plugin_fini_t)(void);
typedef int (cr_plugin_dump_unix_sk_t)(int fd, int id);
typedef int (cr_plugin_restore_unix_sk_t)(int id);
+typedef int (cr_plugin_dump_file_t)(int fd, int id, bool test_only);
+typedef int (cr_plugin_restore_file_t)(int fd, int id);
extern void print_on_level(unsigned int loglevel, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
diff --git a/include/files.h b/include/files.h
index d491cf1..85246dd 100644
--- a/include/files.h
+++ b/include/files.h
@@ -46,6 +46,8 @@ struct fd_parms {
struct fd_link *link;
struct parasite_ctl *ctl;
+
+ cr_plugin_dump_file_t *cb;
};
#define FD_PARMS_INIT \
diff --git a/include/plugin.h b/include/plugin.h
index a70dde3..b3d5f15 100644
--- a/include/plugin.h
+++ b/include/plugin.h
@@ -11,4 +11,8 @@ int cr_plugin_init(void);
int cr_plugin_dump_unix_sk(int fd, int id);
int cr_plugin_restore_unix_sk(int id);
+int cr_plugin_dump_file(int fd, int id, bool test_only,
+ cr_plugin_dump_file_t **cb);
+int cr_plugin_restore_file(int fd, int id);
+
#endif
diff --git a/plugin.c b/plugin.c
index 114a507..2dc947f 100644
--- a/plugin.c
+++ b/plugin.c
@@ -17,6 +17,8 @@ struct cr_plugin_entry {
cr_plugin_dump_unix_sk_t *cr_plugin_dump_unix_sk;
cr_plugin_restore_unix_sk_t *cr_plugin_restore_unix_sk;
+ cr_plugin_dump_file_t *cr_plugin_dump_file;
+ cr_plugin_restore_file_t *cr_plugin_restore_file;
};
struct cr_plugin_entry *next;
@@ -27,6 +29,8 @@ struct cr_plugins {
struct cr_plugin_entry *cr_plugin_dump_unix_sk;
struct cr_plugin_entry *cr_plugin_restore_unix_sk;
+ struct cr_plugin_entry *cr_plugin_dump_file;
+ struct cr_plugin_entry *cr_plugin_restore_file;
};
struct cr_plugins cr_plugins;
@@ -77,6 +81,17 @@ int cr_plugin_restore_unix_sk(int ino)
(cr_plugin_restore_unix_sk_t **) NULL, ino);
}
+int cr_plugin_dump_file(int fd, int id, bool test, cr_plugin_dump_file_t **cb)
+{
+ return run_plugin_funcs(cr_plugin_dump_file, cb, fd, id, test);
+}
+
+int cr_plugin_restore_file(int fd, int id)
+{
+ return run_plugin_funcs(cr_plugin_restore_file,
+ (cr_plugin_restore_file_t **) NULL, fd, id);
+}
+
static int cr_lib_load(char *path)
{
struct cr_plugin_entry *ce;
@@ -93,6 +108,9 @@ static int cr_lib_load(char *path)
add_plugin_func(cr_plugin_dump_unix_sk);
add_plugin_func(cr_plugin_restore_unix_sk);
+ add_plugin_func(cr_plugin_dump_file);
+ add_plugin_func(cr_plugin_restore_file);
+
ce = NULL;
f_fini = dlsym(h, "cr_plugin_fini");
if (f_fini) {
@@ -131,6 +149,9 @@ void cr_plugin_fini(void)
cr_plugin_free(cr_plugin_dump_unix_sk);
cr_plugin_free(cr_plugin_restore_unix_sk);
+ cr_plugin_free(cr_plugin_dump_file);
+ cr_plugin_free(cr_plugin_restore_file);
+
while (cr_plugins.cr_fini) {
ce = cr_plugins.cr_fini;
cr_plugins.cr_fini = cr_plugins.cr_fini->next;
diff --git a/protobuf/regfile.proto b/protobuf/regfile.proto
index d975ab0..925d39a 100644
--- a/protobuf/regfile.proto
+++ b/protobuf/regfile.proto
@@ -6,4 +6,5 @@ message reg_file_entry {
required uint64 pos = 3;
required fown_entry fown = 5;
required string name = 6;
+ optional bool need_callback = 7;
}
--
1.8.3.1
More information about the CRIU
mailing list