[CRIU] [PATCH] unix: allow --external unix[ino]:stub[string]
Pavel Emelyanov
xemul at virtuozzo.com
Tue Feb 28 07:26:11 PST 2017
On 02/28/2017 04:47 PM, Ruslan Kuprieiev wrote:
> Needles to say it's useful for debug, but it is also
> very useful when you syncronise checkpoint/restore
> whith a dumpee using unix socketpair and want it to
> painlessly receive notification on restore.
>
> I.e. on dump, if --external unix[ino]:foo is specified,
Can you remind why it's a dump-time option, rather than the
restore-time one?
> criu will treat specified unix socket almost the same
> way it handles criu service socket. It will dump it as
> closed and will put "foo" string into images, to put
> that "foo" string into that socket on restore. This is
> almost identical to what criu does with service socket,
> but instead of putting a Criu_Resp message into it on
> restore, it puts an arbitrary string.
>
> Signed-off-by: Ruslan Kuprieiev <rkuprieiev at cloudlinux.com>
> ---
> criu/crtools.c | 2 +-
> criu/external.c | 26 ++++++++++++++++++++++++++
> criu/include/external.h | 1 +
> criu/sk-unix.c | 25 +++++++++++++++++++++++--
> images/sk-unix.proto | 1 +
> 5 files changed, 52 insertions(+), 3 deletions(-)
>
> diff --git a/criu/crtools.c b/criu/crtools.c
> index ec02fe3..4bb3c69 100644
> --- a/criu/crtools.c
> +++ b/criu/crtools.c
> @@ -884,7 +884,7 @@ usage:
> " tty[rdev:dev]\n"
> " file[mnt_id:inode]\n"
> " dev[major/minor]:NAME\n"
> -" unix[ino]\n"
> +" unix[ino]{:stub[string]}\n"
> " mnt[MOUNTPOINT]:COOKIE\n"
> " mnt[]{:AUTO_OPTIONS}\n"
> " Formats of RES on restore:\n"
> diff --git a/criu/external.c b/criu/external.c
> index 96e6768..721102d 100644
> --- a/criu/external.c
> +++ b/criu/external.c
> @@ -73,6 +73,32 @@ char *external_lookup_by_key(char *key)
> return ERR_PTR(-ENOENT);
> }
>
> +char *external_lookup_stub_by_key(char *key)
> +{
> + char *val, *stub, *end;
> + char prefix[] = "stub[";
> + char suffix = ']';
> +
> + val = external_lookup_by_key(key);
> + if (IS_ERR_OR_NULL(val))
> + return val;
> +
> + if (strncmp(val, prefix, strlen(prefix)))
> + return ERR_PTR(-ENOENT);
> +
> + val += strlen(prefix);
> + stub = strdup(val);
> +
> + end = strrchr(stub, suffix);
> + if (!end) {
> + free(stub);
> + return ERR_PTR(-EINVAL);
> + }
> + *end = '\0';
> +
> + return stub;
> +}
> +
> int external_for_each_type(char *type, int (*cb)(struct external *, void *), void *arg)
> {
> struct external *ext;
> diff --git a/criu/include/external.h b/criu/include/external.h
> index d284b79..08e04e4 100644
> --- a/criu/include/external.h
> +++ b/criu/include/external.h
> @@ -9,6 +9,7 @@ struct external {
> extern int add_external(char *key);
> extern bool external_lookup_id(char *id);
> extern char *external_lookup_by_key(char *id);
> +extern char *external_lookup_stub_by_key(char *id);
> extern void *external_lookup_data(char *id);
> extern int external_for_each_type(char *type, int (*cb)(struct external *, void *), void *arg);
>
> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
> index a44d998..419c061 100644
> --- a/criu/sk-unix.c
> +++ b/criu/sk-unix.c
> @@ -263,6 +263,8 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
> SkOptsEntry *skopts;
> FilePermsEntry *perms;
> FownEntry *fown;
> + char buf[PATH_MAX];
> + char *stub = NULL;
>
> ue = xmalloc(sizeof(UnixSkEntry) +
> sizeof(SkOptsEntry) +
> @@ -324,6 +326,18 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
> ue->uflags |= USK_SERVICE;
> }
>
> + /* Same as with service_sk, but for custom sockets */
> + snprintf(buf, sizeof(buf), "unix[%u]", ue->ino);
> + stub = external_lookup_stub_by_key(buf);
> + if (unlikely(!IS_ERR_OR_NULL(stub))) {
> + pr_info("Unix socket %#x is closed and plugged with stub '%s' "
> + "for restore\n", ue->ino, stub);
> + ue->state = TCP_CLOSE;
> + ue->peer = 0;
> + ue->uflags |= USK_SERVICE;
> + ue->stub = (void *)stub;
> + }
> +
> if (sk->namelen && *sk->name) {
> ue->file_perms = perms;
>
> @@ -1165,8 +1179,15 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
> return -1;
> }
>
> - if (send_criu_dump_resp(sks[1], true, true) == -1)
> - return -1;
> + if (ui->ue->stub) {
> + pr_warn("Writing stub %s to unix socket %#x\n",
> + (char *)ui->ue->stub, ui->ue->ino);
> + if (write(sks[1], ui->ue->stub, strlen(ui->ue->stub)) != strlen(ui->ue->stub))
> + return -1;
> + } else {
> + if (send_criu_dump_resp(sks[1], true, true) == -1)
> + return -1;
> + }
>
> close(sks[1]);
> sk = sks[0];
> diff --git a/images/sk-unix.proto b/images/sk-unix.proto
> index d695070..a1ce8be 100644
> --- a/images/sk-unix.proto
> +++ b/images/sk-unix.proto
> @@ -50,4 +50,5 @@ message unix_sk_entry {
> optional bool deleted = 15;
>
> optional uint32 ns_id = 16;
> + optional string stub = 17;
> }
>
More information about the CRIU
mailing list