2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +00:00

namespaces: make root_ns_mask more consistent

I) Make root_ns_mask always display namespaces of root task which are
different from criu ones. All this play with temporary unsetting it
makes this variable hard to understand (more over it is not in shared
memory).

II) Disable "INIT_PID + pidns is dumped" check for external pidns
explicitly.

III) On dump we should check that pidns of root task is external, not
just any pidns is external (in case in future we would support nested
pidns-es it would be wrong). That also allows us to use regular
lookup_ns_by_id search.

IV) On error when killing tasks we should kill only root task if it is
an init of pidns. Previousely we had CLONE_NEWPID set in root_ns_mask
for external pidns but root task was not init and we killed only root
task on error cleanup.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov
2020-10-28 11:45:55 +03:00
committed by Andrei Vagin
parent c629525cad
commit c5064eda12
2 changed files with 24 additions and 34 deletions

View File

@@ -1427,13 +1427,6 @@ static inline int fork_with_pid(struct pstree_item *item)
pr_err("Unable to enter existing PID namespace\n");
return -1;
}
/*
* If a process without a PID namespace is restored into
* a PID namespace this tells CRIU to still handle the
* process as if using CLONE_NEWPID.
*/
root_ns_mask |= CLONE_NEWPID;
}
ca.item = item;
@@ -2254,9 +2247,18 @@ static int restore_root_task(struct pstree_item *init)
"\"--namespace pid\" option.\n");
return -1;
}
} else if (root_ns_mask & CLONE_NEWPID) {
pr_err("Can't restore pid namespace without the process init\n");
return -1;
} else if (root_ns_mask & CLONE_NEWPID) {
struct ns_id *ns;
/*
* Restoring into an existing PID namespace. This disables
* the check to require a PID 1 when restoring a process
* which used to be in a PID namespace.
*/
ns = lookup_ns_by_id(init->ids->pid_ns_id, &pid_ns_desc);
if (!ns || !ns->ext_key) {
pr_err("Can't restore pid namespace without the process init\n");
return -1;
}
}
__restore_switch_stage_nw(CR_STATE_ROOT_TASK);
@@ -2476,7 +2478,7 @@ out_kill:
* The processes can be killed only when all of them have been created,
* otherwise an external processes can be killed.
*/
if (root_ns_mask & CLONE_NEWPID) {
if (vpid(root_item) == INIT_PID) {
int status;
/* Kill init */

View File

@@ -1082,21 +1082,18 @@ int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->ns[0].virt, ns_pid->real);
if ((ns_flags & CLONE_NEWPID) && ns_pid->ns[0].virt != 1) {
if ((ns_flags & CLONE_NEWPID) && ns_pid->ns[0].virt != INIT_PID) {
char *val = NULL;
for (ns = ns_ids; ns; ns = ns->next) {
if (ns->nd->cflag == CLONE_NEWPID) {
char id[64];
snprintf(id, sizeof(id), "pid[%u]", ns->kid);
val = external_lookup_by_key(id);
if (IS_ERR_OR_NULL(val)) {
val = NULL;
continue;
}
if (val)
break;
}
ns = lookup_ns_by_id(item->ids->pid_ns_id, &pid_ns_desc);
if (ns) {
char id[64];
snprintf(id, sizeof(id), "pid[%u]", ns->kid);
val = external_lookup_by_key(id);
if (IS_ERR_OR_NULL(val))
val = NULL;
}
if (!val) {
pr_err("Can't dump a pid namespace without the process init\n");
return -1;
@@ -1801,17 +1798,8 @@ static int read_pid_ns_img(void)
pr_err("Can not read pidns object\n");
return -1;
}
if (ret > 0) {
if (ret > 0)
ns->ext_key = e->ext_key;
/*
* Restoring into an existing PID namespace. This disables
* the check to require a PID 1 when restoring a process
* which used to be in a PID namespace.
* To keep the PID namespace code paths enabled this bit
* will be set after having clone()ed the process.
*/
root_ns_mask &= ~CLONE_NEWPID;
}
}
return 0;