diff options
-rw-r--r-- | cr-dump.c | 3 | ||||
-rw-r--r-- | include/irmap.h | 1 | ||||
-rw-r--r-- | irmap.c | 27 |
3 files changed, 30 insertions, 1 deletions
@@ -1734,6 +1734,9 @@ int cr_pre_dump_tasks(pid_t pid) if (pre_dump_one_task(item, &ctls)) goto err; + if (irmap_predump_prep()) + goto err; + ret = 0; err: pstree_switch_state(root_item, diff --git a/include/irmap.h b/include/irmap.h index b5b495ddc..3938d07be 100644 --- a/include/irmap.h +++ b/include/irmap.h @@ -4,6 +4,7 @@ char *irmap_lookup(unsigned int s_dev, unsigned long i_ino); struct _FhEntry; int irmap_queue_cache(unsigned int dev, unsigned long ino, struct _FhEntry *fh); +int irmap_predump_prep(void); int irmap_predump_run(void); int check_open_handle(unsigned int s_dev, unsigned long i_ino, struct _FhEntry *f_handle); @@ -217,6 +217,8 @@ invalid: return 1; } +static bool doing_predump = false; + char *irmap_lookup(unsigned int s_dev, unsigned long i_ino) { struct irmap *c, *h, **p; @@ -227,7 +229,14 @@ char *irmap_lookup(unsigned int s_dev, unsigned long i_ino) pr_debug("Resolving %x:%lx path\n", s_dev, i_ino); - if (__mntns_get_root_fd(root_item->pid.real) < 0) + /* + * If we're in predump, then processes already run + * and the root_item is already freed by that time. + * But the root service fd is already set by the + * irmap_predump_prep, so we just go ahead and scan. + */ + if (!doing_predump && + __mntns_get_root_fd(root_item->pid.real) < 0) goto out; timing_start(TIME_IRMAP_RESOLVE); @@ -296,6 +305,22 @@ int irmap_queue_cache(unsigned int dev, unsigned long ino, return 0; } +int irmap_predump_prep(void) +{ + /* + * Tasks are about to get released soon, but + * we'll need to do FS scan for irmaps. In this + * scan we will need to know the root dir tasks + * live in. Need to make sure the respective fd + * (service) is set to that root, so that the + * scan works and doesn't race with the tasks + * dying or changind root. + */ + + doing_predump = true; + return __mntns_get_root_fd(root_item->pid.real) < 0 ? -1 : 0; +} + int irmap_predump_run(void) { int ret = 0, fd; |