Skip to content

Commit

Permalink
Add support for pidfd
Browse files Browse the repository at this point in the history
Signed-off-by: Suraj Shirvankar <[email protected]>
  • Loading branch information
h0lyalg0rithm committed Sep 5, 2023
1 parent 82bfb67 commit 9b0a7ce
Show file tree
Hide file tree
Showing 15 changed files with 156 additions and 2 deletions.
1 change: 1 addition & 0 deletions criu/Makefile.crtools
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ obj-$(CONFIG_COMPAT) += vdso-compat.o
CFLAGS_REMOVE_vdso-compat.o += $(CFLAGS-ASAN) $(CFLAGS-GCOV)
obj-y += pidfd-store.o
obj-y += hugetlb.o
obj-y += pidfd.o

PROTOBUF_GEN := scripts/protobuf-gen.sh

Expand Down
3 changes: 2 additions & 1 deletion criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#include "timens.h"
#include "bpfmap.h"
#include "apparmor.h"
#include "pidfd.h"

#include "parasite-syscall.h"
#include "files-reg.h"
Expand Down Expand Up @@ -279,7 +280,7 @@ static struct collect_image_info *cinfos_files[] = {
&unix_sk_cinfo, &fifo_cinfo, &pipe_cinfo, &nsfile_cinfo, &packet_sk_cinfo,
&netlink_sk_cinfo, &eventfd_cinfo, &epoll_cinfo, &epoll_tfd_cinfo, &signalfd_cinfo,
&tunfile_cinfo, &timerfd_cinfo, &inotify_cinfo, &inotify_mark_cinfo, &fanotify_cinfo,
&fanotify_mark_cinfo, &ext_file_cinfo, &memfd_cinfo,
&fanotify_mark_cinfo, &ext_file_cinfo, &memfd_cinfo, &pidfd_cinfo
};

/* These images are required to restore namespaces */
Expand Down
6 changes: 6 additions & 0 deletions criu/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "kerndat.h"
#include "fdstore.h"
#include "bpfmap.h"
#include "pidfd.h"

#include "protobuf.h"
#include "util.h"
Expand Down Expand Up @@ -544,6 +545,8 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
ops = &signalfd_dump_ops;
else if (is_timerfd_link(link))
ops = &timerfd_dump_ops;
else if (is_pidfd_link(link))
ops = &pidfd_dump_ops;
#ifdef CONFIG_HAS_LIBBPF
else if (is_bpfmap_link(link))
ops = &bpfmap_dump_ops;
Expand Down Expand Up @@ -1778,6 +1781,9 @@ static int collect_one_file(void *o, ProtobufCMessage *base, struct cr_img *i)
case FD_TYPES__MEMFD:
ret = collect_one_file_entry(fe, fe->memfd->id, &fe->memfd->base, &memfd_cinfo);
break;
case FD_TYPES__PIDFD:
ret = collect_one_file_entry(fe, fe->pidfd->id, &fe->pidfd->base, &pidfd_cinfo);
break;
#ifdef CONFIG_HAS_LIBBPF
case FD_TYPES__BPFMAP:
ret = collect_one_file_entry(fe, fe->bpf->id, &fe->bpf->base, &bpfmap_cinfo);
Expand Down
1 change: 1 addition & 0 deletions criu/image-desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
FD_ENTRY_F(BPFMAP_FILE, "bpfmap-file", O_NOBUF),
FD_ENTRY_F(BPFMAP_DATA, "bpfmap-data", O_NOBUF),
FD_ENTRY(APPARMOR, "apparmor"),
FD_ENTRY(PIDFD, "pidfd-%u"),

[CR_FD_STATS] = {
.fmt = "stats-%s",
Expand Down
4 changes: 3 additions & 1 deletion criu/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ int check_img_inventory(bool restore)
int ret = -1;
struct cr_img *img;
InventoryEntry *he;
int loaded;

img = open_image(CR_FD_INVENTORY, O_RSTR);
if (!img)
return -1;

if (pb_read_one(img, &he, PB_INVENTORY) < 0)
loaded = pb_read_one(img, &he, PB_INVENTORY);
if (loaded < 0)
goto out_close;

if (!he->has_fdinfo_per_id || !he->fdinfo_per_id) {
Expand Down
1 change: 1 addition & 0 deletions criu/include/fdinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "images/signalfd.pb-c.h"
#include "images/fsnotify.pb-c.h"
#include "images/timerfd.pb-c.h"
#include "images/pidfd.pb-c.h"

struct fdinfo_common {
off64_t pos;
Expand Down
1 change: 1 addition & 0 deletions criu/include/image-desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ enum {
CR_FD_PIPES,
CR_FD_TTY_FILES,
CR_FD_MEMFD_FILE,
CR_FD_PIDFD,

CR_FD_AUTOFS,

Expand Down
1 change: 1 addition & 0 deletions criu/include/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#define BPFMAP_FILE_MAGIC 0x57506142 /* Alapayevsk */
#define BPFMAP_DATA_MAGIC 0x64324033 /* Arkhangelsk */
#define APPARMOR_MAGIC 0x59423047 /* Nikolskoye */
#define PIDFD_MAGIC 0x59423447

#define IFADDR_MAGIC RAW_IMAGE_MAGIC
#define ROUTE_MAGIC RAW_IMAGE_MAGIC
Expand Down
19 changes: 19 additions & 0 deletions criu/include/pidfd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef __CR_PIDFD_H__
#define __CR_PIDFD_H__

#include <sys/stat.h>
#include "images/pidfd.pb-c.h"
#include <sys/syscall.h>
#include <unistd.h>

struct fd_parms;

extern const struct fdtype_ops pidfd_dump_ops;
extern struct collect_image_info pidfd_cinfo;
extern int is_pidfd_link(char *link);

static inline int pidfd_open(pid_t pid, unsigned int flags)
{
return syscall(SYS_pidfd_open, pid, flags);
}
#endif
1 change: 1 addition & 0 deletions criu/include/protobuf-desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum {
PB_SK_QUEUES,
PB_IPCNS_MSG,
PB_IPCNS_MSG_ENT,
PB_PIDFD,

PB_MAX,
};
Expand Down
81 changes: 81 additions & 0 deletions criu/pidfd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "pidfd.h"
#include "util.h"

#include "fdinfo.h"
#include "files.h"
#include "imgset.h"
#include "protobuf.h"
#include "fdinfo.pb-c.h"

int is_pidfd_link(char *link)
{
return is_anon_link_type(link, "[pidfd]");
}

static int dump_one_pidfd(int lfd, u32 id, const struct fd_parms *p)
{
PidfdEntry tfe = PIDFD_ENTRY__INIT;
FileEntry fe = FILE_ENTRY__INIT;

if (parse_fdinfo(lfd, FD_TYPES__PIDFD, &tfe))
return -1;

tfe.id = id;
tfe.flags = p->flags;
tfe.inode = p->stat.st_ino;
tfe.mnt_id = p->mnt_id;
tfe.fown = (FownEntry *)&p->fown;

fe.type = FD_TYPES__PIDFD;
fe.id = tfe.id;
fe.pidfd = &tfe;

return pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fe, PB_FILE);
}

const struct fdtype_ops pidfd_dump_ops = {
.type = FD_TYPES__PIDFD,
.dump = dump_one_pidfd,
};

struct pidfd_info {
PidfdEntry *pidfde;
struct file_desc d;
};

static int open_pidfd_fd(struct file_desc *d, int *new_fd)
{
int fd = -1;
struct pidfd_info *info = container_of(d, struct pidfd_info, d);
PidfdEntry *pidfde = info->pidfde;

pr_info("Creating new pidfd %" PRId64 "\n", pidfde->pid);
fd = pidfd_open(pidfde->pid, 0);
if (fd < 0) {
pr_perror("Cannot create pidfd %" PRId64, pidfde->pid);
return -1;
}

*new_fd = fd;
return 0;
}

static struct file_desc_ops pidfd_desc_ops = {
.type = FD_TYPES__PIDFD,
.open = open_pidfd_fd,
};

static int collect_one_pidfd(void *o, ProtobufCMessage *msg, struct cr_img *i)
{
struct pidfd_info *info = o;

info->pidfde = pb_msg(msg, PidfdEntry);
return file_desc_add(&info->d, info->pidfde->id, &pidfd_desc_ops);
}

struct collect_image_info pidfd_cinfo = {
.fd_type = CR_FD_PIDFD,
.pb_type = PB_PIDFD,
.priv_size = sizeof(struct pidfd_info),
.collect = collect_one_pidfd,
};
19 changes: 19 additions & 0 deletions criu/proc_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "protobuf.h"
#include "images/fdinfo.pb-c.h"
#include "images/mnt.pb-c.h"
#include "images/pidfd.pb-c.h"
#include "plugin.h"

#include <stdlib.h>
Expand Down Expand Up @@ -2160,6 +2161,24 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, void *arg)
entry_met = true;
continue;
}
if (fdinfo_field(str, "Pid") || fdinfo_field(str, "NSpid")) {
unsigned long long val;
PidfdEntry *pfd = arg;

if (type != FD_TYPES__PIDFD)
continue;
ret = sscanf(str, "%*s %lli", &val);
if (ret != 1)
goto parse_err;

if (fdinfo_field(str, "Pid"))
pfd->pid = val;
else if (fdinfo_field(str, "NSpid"))
pfd->nspid = val;

entry_met = true;
continue;
}
}

exit_code = 0;
Expand Down
1 change: 1 addition & 0 deletions images/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ proto-obj-y += bpfmap-file.o
proto-obj-y += bpfmap-data.o
proto-obj-y += apparmor.o
proto-obj-y += rseq.o
proto-obj-y += pidfd.o

CFLAGS += -iquote $(obj)/

Expand Down
3 changes: 3 additions & 0 deletions images/fdinfo.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import "pipe.proto";
import "tty.proto";
import "memfd.proto";
import "bpfmap-file.proto";
import "pidfd.proto";

enum fd_types {
UND = 0;
Expand All @@ -42,6 +43,7 @@ enum fd_types {
TIMERFD = 17;
MEMFD = 18;
BPFMAP = 19;
PIDFD = 20;

/* Any number above the real used. Not stored to image */
CTL_TTY = 65534;
Expand Down Expand Up @@ -78,4 +80,5 @@ message file_entry {
optional tty_file_entry tty = 19;
optional memfd_file_entry memfd = 20;
optional bpfmap_file_entry bpf = 21;
optional pidfd_entry pidfd = 22;
}
16 changes: 16 additions & 0 deletions images/pidfd.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT

syntax = "proto2";

import "fown.proto";

message pidfd_entry {
required uint32 id = 1;
required uint64 pos = 2;
required uint32 flags = 3;
required uint32 mnt_id = 4;
required uint64 inode = 5;
required int64 pid = 6;
required int64 nspid = 7;
required fown_entry fown = 8;
}

0 comments on commit 9b0a7ce

Please sign in to comment.