diff --git a/files-reg.c b/files-reg.c index 21b984947..c99c34940 100644 --- a/files-reg.c +++ b/files-reg.c @@ -28,14 +28,11 @@ struct ghost_file { struct list_head list; u32 id; - union { - struct /* for dumping */ { - u32 dev; - u32 ino; - }; - struct file_remap remap; /* for restoring */ - }; + u32 dev; + u32 ino; + + struct file_remap remap; }; static u32 ghost_file_ids = 1; @@ -83,6 +80,14 @@ static int open_remap_ghost(struct reg_file_info *rfi, if (pb_read_one(ifd, &gfe, PB_GHOST_FILE) < 0) goto close_ifd; + /* + * For old formats where optional has_[dev|ino] is + * not present we will have zeros here which is quite + * a sign for "absent" fields. + */ + gf->dev = gfe->dev; + gf->ino = gfe->ino; + snprintf(gf->remap.path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id); if (S_ISFIFO(gfe->mode)) { @@ -218,6 +223,10 @@ static int dump_ghost_file(int _fd, u32 id, const struct stat *st) gfe.gid = st->st_gid; gfe.mode = st->st_mode; + gfe.has_dev = gfe.has_ino = true; + gfe.dev = MKKDEV(MAJOR(st->st_dev), MINOR(st->st_dev)); + gfe.ino = st->st_ino; + if (pb_write_one(img, &gfe, PB_GHOST_FILE)) return -1; diff --git a/include/types.h b/include/types.h index 29b27ec9d..9b7884f32 100644 --- a/include/types.h +++ b/include/types.h @@ -79,6 +79,7 @@ typedef unsigned char u8; typedef signed char s8; #define MAJOR(dev) ((dev)>>8) +#define MINOR(dev) ((dev) & 0xff) #define _LINUX_CAPABILITY_VERSION_3 0x20080522 #define _LINUX_CAPABILITY_U32S_3 2 diff --git a/protobuf/ghost-file.proto b/protobuf/ghost-file.proto index 8f362fad7..d1946d8a8 100644 --- a/protobuf/ghost-file.proto +++ b/protobuf/ghost-file.proto @@ -2,4 +2,7 @@ message ghost_file_entry { required uint32 uid = 1; required uint32 gid = 2; required uint32 mode = 3; + + optional uint32 dev = 4; + optional uint64 ino = 5; }