diff --git a/include/namespaces.h b/include/namespaces.h index 52d2f34f5..b76c7d9b9 100644 --- a/include/namespaces.h +++ b/include/namespaces.h @@ -54,7 +54,7 @@ extern unsigned long root_ns_mask; extern const struct fdtype_ops nsfile_dump_ops; extern struct collect_image_info nsfile_cinfo; -extern int walk_namespaces(struct ns_desc *nd, int (*cb)(struct ns_id *, void *), void *oarg); +extern int walk_namespaces(struct ns_desc *nd, bool walk_all, int (*cb)(struct ns_id *, void *), void *oarg); extern int collect_namespaces(bool for_dump); extern int collect_mnt_namespaces(bool for_dump); extern int dump_mnt_namespaces(void); diff --git a/mount.c b/mount.c index 71c39bf87..c4c2c860d 100644 --- a/mount.c +++ b/mount.c @@ -2372,7 +2372,7 @@ int collect_mnt_namespaces(bool for_dump) arg.for_dump = for_dump; arg.need_to_validate = false; - ret = walk_namespaces(&mnt_ns_desc, collect_mntns, &arg); + ret = walk_namespaces(&mnt_ns_desc, false, collect_mntns, &need_to_validate); if (ret) goto err; diff --git a/namespaces.c b/namespaces.c index 9fdd9b30c..167adf92e 100644 --- a/namespaces.c +++ b/namespaces.c @@ -201,9 +201,14 @@ struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd) * tasks may live in it. Sometimes (CLONE_SUBNS) there can * be more than one namespace of that type. For this case * we dump all namespace's info and recreate them on restore. + * + * In some cases (e.g. for external mount autodetection), we want to walk all + * the namespaces, regardless of who it is attached to. Passing walk_all=true + * forces the function to walk all the namespaces, regardless of who they + * belong to. */ -int walk_namespaces(struct ns_desc *nd, int (*cb)(struct ns_id *, void *), void *oarg) +int walk_namespaces(struct ns_desc *nd, bool walk_all, int (*cb)(struct ns_id *, void *), void *oarg) { int ret = 0; struct ns_id *ns; @@ -212,7 +217,7 @@ int walk_namespaces(struct ns_desc *nd, int (*cb)(struct ns_id *, void *), void if (ns->nd != nd) continue; - if (ns->pid == getpid()) { + if (ns->pid == getpid() && !walk_all) { if (root_ns_mask & nd->cflag) continue; @@ -597,7 +602,7 @@ int collect_user_namespaces(bool for_dump) if (!(root_ns_mask & CLONE_NEWUSER)) return 0; - return walk_namespaces(&net_ns_desc, collect_user_ns, NULL); + return walk_namespaces(&net_ns_desc, false, collect_user_ns, NULL); } static int check_user_ns(int pid) diff --git a/net.c b/net.c index ad314dfa5..c2b661ba9 100644 --- a/net.c +++ b/net.c @@ -716,7 +716,7 @@ static int collect_net_ns(struct ns_id *ns, void *oarg) int collect_net_namespaces(bool for_dump) { - return walk_namespaces(&net_ns_desc, collect_net_ns, + return walk_namespaces(&net_ns_desc, false, collect_net_ns, (void *)(for_dump ? 1UL : 0)); }