diff --git a/criu/cr-check.c b/criu/cr-check.c index 4f6156a0b..c8e3543f5 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -392,16 +392,10 @@ pipe_err: return ret; } -static int check_one_inotify(union fdinfo_entries *e, void *arg) -{ - *(int *)arg = e->ify.e.wd; - free_inotify_wd_entry(e); - return 0; -} - static int check_fdinfo_inotify(void) { - int ifd, wd, proc_wd = -1, ret; + int ifd, wd, ret; + InotifyFileEntry ify = INOTIFY_FILE_ENTRY__INIT; ifd = inotify_init1(0); if (ifd < 0) { @@ -416,7 +410,7 @@ static int check_fdinfo_inotify(void) return -1; } - ret = parse_fdinfo(ifd, FD_TYPES__INOTIFY, check_one_inotify, &proc_wd); + ret = parse_fdinfo(ifd, FD_TYPES__INOTIFY, NULL, &ify); close(ifd); if (ret < 0) { @@ -424,12 +418,12 @@ static int check_fdinfo_inotify(void) return -1; } - if (wd != proc_wd) { - pr_err("WD mismatch (or not met) %d want %d\n", proc_wd, wd); + if (ify.n_wd != 1 || ify.wd[0]->wd != wd) { + pr_err("WD mismatch (or not met)\n"); return -1; } - pr_info("Inotify fdinfo works OK (%d vs %d)\n", wd, proc_wd); + pr_info("Inotify fdinfo works OK\n"); return 0; } diff --git a/criu/fsnotify.c b/criu/fsnotify.c index 3c71bf3ac..7bd441161 100644 --- a/criu/fsnotify.c +++ b/criu/fsnotify.c @@ -302,12 +302,8 @@ struct watch_list { int n; }; -static int dump_inotify_entry(union fdinfo_entries *e, void *arg) +static int check_one_wd(InotifyWdEntry *we) { - struct watch_list *wd_list = (struct watch_list *) arg; - struct inotify_wd_entry *wd_entry = (struct inotify_wd_entry *) e; - InotifyWdEntry *we = &wd_entry->e; - pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n", we->wd, we->s_dev, we->i_ino, we->mask); pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016"PRIx64":%#016"PRIx64"\n", @@ -318,22 +314,15 @@ static int dump_inotify_entry(union fdinfo_entries *e, void *arg) pr_warn_once("\t\tDetected FS_EVENT_ON_CHILD bit " "in mask (will be ignored on restore)\n"); - if (check_open_handle(we->s_dev, we->i_ino, we->f_handle)) { - free_inotify_wd_entry(e); + if (check_open_handle(we->s_dev, we->i_ino, we->f_handle)) return -1; - } - - list_add_tail(&wd_entry->node, &wd_list->list); - wd_list->n++; return 0; } static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) { - struct watch_list wd_list = {.list = LIST_HEAD_INIT(wd_list.list), .n = 0}; InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT; - union fdinfo_entries *we, *tmp; int exit_code = -1, i, ret; ret = fd_has_data(lfd); @@ -346,17 +335,12 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) ie.flags = p->flags; ie.fown = (FownEntry *)&p->fown; - if (parse_fdinfo(lfd, FD_TYPES__INOTIFY, dump_inotify_entry, &wd_list)) + if (parse_fdinfo(lfd, FD_TYPES__INOTIFY, NULL, &ie)) goto free; - ie.wd = xmalloc(sizeof(*ie.wd) * wd_list.n); - if (!ie.wd) - goto free; - - i = 0; - list_for_each_entry(we, &wd_list.list, ify.node) - ie.wd[i++] = &we->ify.e; - ie.n_wd = wd_list.n; + for (i = 0; i < ie.n_wd; i++) + if (check_one_wd(ie.wd[i])) + goto free; pr_info("id %#08x flags %#08x\n", ie.id, ie.flags); if (pb_write_one(img_from_set(glob_imgset, CR_FD_INOTIFY_FILE), &ie, PB_INOTIFY_FILE)) @@ -364,27 +348,31 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) exit_code = 0; free: + for (i = 0; i < ie.n_wd; i++) + xfree(ie.wd[i]); xfree(ie.wd); - list_for_each_entry_safe(we, tmp, &wd_list.list, ify.node) - free_inotify_wd_entry(we); return exit_code; } -static int pre_dump_inotify_entry(union fdinfo_entries *e, void *arg) -{ - InotifyWdEntry *we = &e->ify.e; - int ret; - - ret = irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle); - free_inotify_wd_entry(e); - - return ret; -} - static int pre_dump_one_inotify(int pid, int lfd) { - return parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, pre_dump_inotify_entry, NULL); + InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT; + int i; + + if (parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, NULL, &ie)) + return -1; + + for (i = 0; i < ie.n_wd; i++) { + InotifyWdEntry *we = ie.wd[i]; + + if (irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle)) + return -1; + + xfree(we); + } + + return 0; } const struct fdtype_ops inotify_dump_ops = { diff --git a/criu/include/fdinfo.h b/criu/include/fdinfo.h index 45f5746ab..5977a1d83 100644 --- a/criu/include/fdinfo.h +++ b/criu/include/fdinfo.h @@ -9,12 +9,6 @@ #include "images/fsnotify.pb-c.h" #include "images/timerfd.pb-c.h" -struct inotify_wd_entry { - InotifyWdEntry e; - FhEntry f_handle; - struct list_head node; -}; - struct fanotify_mark_entry { FanotifyMarkEntry e; FhEntry f_handle; @@ -26,12 +20,10 @@ struct fanotify_mark_entry { }; union fdinfo_entries { - struct inotify_wd_entry ify; struct fanotify_mark_entry ffy; TimerfdEntry tfy; }; -extern void free_inotify_wd_entry(union fdinfo_entries *e); extern void free_fanotify_mark_entry(union fdinfo_entries *e); struct fdinfo_common { diff --git a/criu/proc_parse.c b/criu/proc_parse.c index 4f9f2d7a2..7b2e2ec6e 100644 --- a/criu/proc_parse.c +++ b/criu/proc_parse.c @@ -1534,12 +1534,6 @@ static void free_fhandle(FhEntry *fh) xfree(fh->handle); } -void free_inotify_wd_entry(union fdinfo_entries *e) -{ - free_fhandle(e->ify.e.f_handle); - xfree(e); -} - void free_fanotify_mark_entry(union fdinfo_entries *e) { if (e->ffy.e.ie) @@ -1867,21 +1861,27 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, continue; } if (fdinfo_field(str, "inotify wd")) { + void *buf, *ob; + InotifyFileEntry *ie = arg; InotifyWdEntry *ify; - union fdinfo_entries *e; - int hoff; + int hoff, i; if (type != FD_TYPES__INOTIFY) goto parse_err; - e = xmalloc(sizeof(*e)); - if (!e) - goto parse_err; - ify = &e->ify.e; + ob = buf = xmalloc(sizeof(InotifyWdEntry) + + sizeof(FhEntry) + + FH_ENTRY_SIZES__min_entries * sizeof(uint64_t)); + if (!buf) + goto out; + ify = xptr_pull(&buf, InotifyWdEntry); inotify_wd_entry__init(ify); - ify->f_handle = &e->ify.f_handle; + ify->f_handle = xptr_pull(&buf, FhEntry); fh_entry__init(ify->f_handle); + ify->f_handle->n_handle = FH_ENTRY_SIZES__min_entries; + ify->f_handle->handle = xptr_pull_s(&buf, + FH_ENTRY_SIZES__min_entries * sizeof(uint64_t)); ret = sscanf(str, "inotify wd:%x ino:%"PRIx64" sdev:%x " @@ -1893,22 +1893,19 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, &ify->f_handle->bytes, &ify->f_handle->type, &hoff); if (ret != 7) { - free_inotify_wd_entry(e); + xfree(ob); goto parse_err; } - if (alloc_fhandle(ify->f_handle)) { - free_inotify_wd_entry(e); - goto out; - } - parse_fhandle_encoded(str + hoff, ify->f_handle); - ret = cb(e, arg); - - if (ret) + i = ie->n_wd++; + if (xrealloc_safe(&ie->wd, ie->n_wd * sizeof(InotifyWdEntry *))) { + xfree(ob); goto out; + } + ie->wd[i] = ify; entry_met = true; continue; }