[CRIU] [PATCH 2/3] dump: Add dumping of file owners

Cyrill Gorcunov gorcunov at openvz.org
Fri Mar 23 11:11:35 EDT 2012


While fcntl provides almost all data file
owner handler might have, a missing piece reminds
uid and euid of owner.

For this sake a kernel patch is needed, which means
the crtools will refuse to work on old kernels (older
than crtools-v3.3).

This patch brings only dump/show procedure for a while,
the restore patch will be provided later, still all
existing test cases are passed well because restoring
code have no idea about file owners.

One of important detail of the patch -- the image format
is extended, again ;)

The show procedure will print out the fowners info iif
the owner was ever changed, skipping untouched entries.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c       |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 cr-show.c       |   13 +++++++++++
 include/image.h |   14 +++++++++++
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index b5c9a3c..5da4080 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -125,6 +125,12 @@ struct fd_parms {
 	unsigned int	flags;
 	unsigned int	type;
 
+	unsigned int	owner_uid;
+	unsigned int	owner_euid;
+	unsigned int	owner_signum;
+	unsigned int	owner_pid_type;
+	unsigned int	owner_pid;
+
 	u64		id;
 	pid_t		pid;
 };
@@ -133,7 +139,7 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
 			     const struct cr_fdset *cr_fdset,
 			     bool do_close_lfd)
 {
-	struct fdinfo_entry e;
+	struct fdinfo_entry e = { };
 	char fd_str[128];
 	int len;
 	int ret = -1;
@@ -159,6 +165,14 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
 	e.addr	= p->fd_name;
 	e.id	= FD_ID_INVALID;
 
+	if (p->owner_pid) {
+		e.owner_uid	= p->owner_uid;
+		e.owner_euid	= p->owner_euid;
+		e.owner_signum	= p->owner_signum;
+		e.owner_pid_type= p->owner_pid_type;
+		e.owner_pid	= p->owner_pid;
+	}
+
 	if (likely(!fd_is_special(&e))) {
 		struct fd_id_entry *entry;
 
@@ -281,7 +295,7 @@ err:
 static int dump_one_pipe(const struct fd_parms *p, unsigned int id, int lfd,
 			 const struct cr_fdset *cr_fdset)
 {
-	struct pipe_entry e;
+	struct pipe_entry e = { };
 	int ret = -1;
 	struct statfs stfs_buf;
 
@@ -301,6 +315,14 @@ static int dump_one_pipe(const struct fd_parms *p, unsigned int id, int lfd,
 	e.pipeid	= id;
 	e.flags		= p->flags;
 
+	if (p->owner_pid) {
+		e.owner_uid	= p->owner_uid;
+		e.owner_euid	= p->owner_euid;
+		e.owner_signum	= p->owner_signum;
+		e.owner_pid_type= p->owner_pid_type;
+		e.owner_pid	= p->owner_pid;
+	}
+
 	if (p->flags & O_WRONLY) {
 		e.bytes = 0;
 		ret = write_img(cr_fdset->fds[CR_FD_PIPES], &e);
@@ -317,8 +339,13 @@ err:
 	return ret;
 }
 
-static void fill_fd_params(pid_t pid, int fd, int lfd, struct fd_parms *p)
+static int fill_fd_params(pid_t pid, int fd, int lfd, struct fd_parms *p)
 {
+	struct f_owner_ex owner_ex;
+	u32 v[2];
+
+	memzero(p, sizeof(*p));
+
 	p->fd_name	= fd;
 	p->pos		= lseek(lfd, 0, SEEK_CUR);
 	p->flags	= fcntl(lfd, F_GETFL);
@@ -327,6 +354,35 @@ static void fill_fd_params(pid_t pid, int fd, int lfd, struct fd_parms *p)
 
 	pr_info("%d fdinfo %d: pos: %16lx flags: %16o\n",
 		pid, fd, p->pos, p->flags);
+
+	if (fcntl(lfd, F_GETOWN_EX, (long)&owner_ex)) {
+		pr_perror("Can't get owners on %d/%d\n", pid, fd);
+		return -1;
+	}
+
+	/*
+	 * Simple case -- nothing is changed.
+	 */
+	if (owner_ex.pid == 0)
+		return 0;
+
+	p->owner_signum = fcntl(lfd, F_GETSIG, 0);
+	if (p->owner_signum < 0) {
+		pr_perror("Can't get owner signum on %d/%d\n", pid, fd);
+		return -1;
+	}
+
+	if (fcntl(lfd, F_GETOWNER_UIDS, (long)&v)) {
+		pr_perror("Can't get owner uids on %d/%d\n", pid, fd);
+		return -1;
+	}
+
+	p->owner_uid		= v[0];
+	p->owner_euid		= v[1];
+	p->owner_pid_type	= owner_ex.type;
+	p->owner_pid		= owner_ex.pid;
+
+	return 0;
 }
 
 static int dump_one_fd(pid_t pid, int fd, int lfd,
@@ -337,7 +393,8 @@ static int dump_one_fd(pid_t pid, int fd, int lfd,
 	struct fd_parms p;
 	int err;
 
-	fill_fd_params(pid, fd, lfd, &p);
+	if (fill_fd_params(pid, fd, lfd, &p))
+		return -1;
 
 	err = open_proc_nocheck(pid, "fd/%d", fd);
 	if (err < 0) {
diff --git a/cr-show.c b/cr-show.c
index 7eafdbd..f8a525d 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -82,6 +82,13 @@ static void show_files(int fd_files)
 		}
 
 		pr_msg("\n");
+
+		if (e.owner_pid) {
+			pr_msg("\touid: %4x oeuid: %4x osignum: %4x "
+			       "opid_type: %2x opid: %8x\n",
+			       e.owner_uid, e.owner_euid, e.owner_signum,
+			       e.owner_pid_type, e.owner_pid);
+		}
 	}
 
 out:
@@ -103,6 +110,12 @@ static void show_pipes(int fd_pipes)
 			goto out;
 		pr_msg("fd: %8x pipeid: %8x flags: %8x bytes: %8x\n",
 		       e.fd, e.pipeid, e.flags, e.bytes);
+		if (e.owner_pid) {
+			pr_msg("\touid: %4x oeuid: %4x osignum: %4x "
+			       "opid_type: %2x opid: %8x\n",
+			       e.owner_uid, e.owner_euid, e.owner_signum,
+			       e.owner_pid_type, e.owner_pid);
+		}
 		if (e.bytes)
 			lseek(fd_pipes, e.bytes, SEEK_CUR);
 	}
diff --git a/include/image.h b/include/image.h
index cdc4af8..775bbb2 100644
--- a/include/image.h
+++ b/include/image.h
@@ -46,6 +46,13 @@ struct fdinfo_entry {
 	u32	pos;
 	u64	addr;
 	u64	id;
+
+	u32	owner_uid;
+	u32	owner_euid;
+	u32	owner_signum;
+	u32	owner_pid_type;
+	u32	owner_pid;
+
 	u8	name[0];
 } __packed;
 
@@ -65,6 +72,13 @@ struct pipe_entry {
 	u32	pipeid;
 	u32	flags;
 	u32	bytes;
+
+	u32	owner_uid;
+	u32	owner_euid;
+	u32	owner_signum;
+	u32	owner_pid_type;
+	u32	owner_pid;
+
 	u8	data[0];
 } __packed;
 
-- 
1.7.7.6



More information about the CRIU mailing list