2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 01:51:51 +00:00

rpc: Support gathering external file list after freezing process tree.

New 'query-ext-files' action for `criu dump` is sent after
freezing the process tree. This allows to defer gathering
the external file list when the process tree is in a stable
state and avoids race with the process creating and deleting
files.

Change-Id: Iae32149dc3992dea086f513ada52cf6863beaa1f
Signed-off-by: Michał Mirosław <emmir@google.com>
This commit is contained in:
Michał Mirosław 2022-03-31 06:59:34 -07:00 committed by Andrei Vagin
parent 82a0db036e
commit 439b522433
5 changed files with 69 additions and 0 deletions

View File

@ -155,6 +155,11 @@ not compatible with *--external* *dev*.
notification message contains a file descriptor for
the master pty
*query-ext-files*:::
called after the process tree is stopped and network is locked.
This hook is used only in the RPC mode. The notification reply
contains file ids to be added to external file list (may be empty).
*--unprivileged*::
This option tells *criu* to accept the limitations when running
as non-root. Running as non-root requires *criu* at least to have

View File

@ -31,6 +31,7 @@ static const char *action_names[ACT_MAX] = {
[ACT_POST_RESUME] = "post-resume",
[ACT_ORPHAN_PTS_MASTER] = "orphan-pts-master",
[ACT_STATUS_READY] = "status-ready",
[ACT_QUERY_EXT_FILES] = "query-ext-files",
};
struct script {
@ -115,6 +116,20 @@ int rpc_send_fd(enum script_actions act, int fd)
return send_criu_rpc_script(act, (char *)action, rpc_sk, fd);
}
int rpc_query_external_files(void)
{
int rpc_sk;
if (scripts_mode != SCRIPTS_RPC)
return 0;
rpc_sk = get_service_fd(RPC_SK_OFF);
if (rpc_sk < 0)
return -1;
return exec_rpc_query_external_files((char *)action_names[ACT_QUERY_EXT_FILES], rpc_sk);
}
int run_scripts(enum script_actions act)
{
int ret = 0;

View File

@ -2180,6 +2180,9 @@ int cr_dump_tasks(pid_t pid)
if (network_lock())
goto err;
if (rpc_query_external_files())
goto err;
if (collect_file_locks())
goto err;

View File

@ -240,6 +240,49 @@ int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd)
return 0;
}
int exec_rpc_query_external_files(char *name, int sk)
{
int i, ret;
CriuNotify cn = CRIU_NOTIFY__INIT;
CriuResp msg = CRIU_RESP__INIT;
CriuReq *req;
cn.script = name;
msg.type = CRIU_REQ_TYPE__NOTIFY;
msg.success = true;
msg.notify = &cn;
ret = send_criu_msg_with_fd(sk, &msg, -1);
if (ret < 0)
return ret;
ret = recv_criu_msg(sk, &req);
if (ret < 0)
return ret;
if (req->type != CRIU_REQ_TYPE__NOTIFY || !req->notify_success) {
pr_err("RPC client reported script error\n");
return -1;
}
ret = 0;
if (req->opts)
for (i = 0; i < req->opts->n_external; i++) {
char *key = req->opts->external[i];
pr_info("Adding external object: %s\n", key);
if (add_external(key)) {
pr_err("Failed to add external object: %s\n", key);
ret = -1;
}
}
else
pr_info("RPC NOTIFY %s: no `opts` returned.\n", name);
criu_req__free_unpacked(req, NULL);
return ret;
}
static char images_dir[PATH_MAX];
static int setup_opts_from_req(int sk, CriuOpts *req)

View File

@ -17,6 +17,7 @@ enum script_actions {
ACT_PRE_RESUME,
ACT_ORPHAN_PTS_MASTER,
ACT_STATUS_READY,
ACT_QUERY_EXT_FILES,
ACT_MAX
};
@ -25,6 +26,8 @@ extern int add_script(char *path);
extern int add_rpc_notify(int sk);
extern int run_scripts(enum script_actions);
extern int rpc_send_fd(enum script_actions, int fd);
extern int rpc_query_external_files(void);
extern int exec_rpc_query_external_files(char *name, int sk);
extern int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd);
#endif /* __CR_ACTION_SCRIPTS_H__ */