Branch data Line data Source code
1 : : #include <unistd.h>
2 : : #include <fcntl.h>
3 : : #include <sys/wait.h>
4 : : #include <stdlib.h>
5 : : #include "cr-show.h"
6 : : #include "util.h"
7 : : #include "fdset.h"
8 : : #include "syscall.h"
9 : : #include "uts_ns.h"
10 : : #include "ipc_ns.h"
11 : : #include "mount.h"
12 : : #include "pstree.h"
13 : : #include "namespaces.h"
14 : : #include "net.h"
15 : :
16 : : #include "protobuf.h"
17 : : #include "protobuf/ns.pb-c.h"
18 : :
19 : : static struct ns_desc *ns_desc_array[] = {
20 : : &net_ns_desc,
21 : : &uts_ns_desc,
22 : : &ipc_ns_desc,
23 : : &pid_ns_desc,
24 : : &user_ns_desc,
25 : : &mnt_ns_desc,
26 : : };
27 : :
28 : 9537 : static unsigned int parse_ns_link(char *link, size_t len, struct ns_desc *d)
29 : : {
30 : : unsigned long kid = 0;
31 : : char *end;
32 : :
33 [ + - ]: 9537 : if (len >= d->len + 2) {
34 [ + - ][ + - ]: 9537 : if (link[d->len] == ':' && !memcmp(link, d->str, d->len)) {
35 : 9537 : kid = strtoul(&link[d->len + 2], &end, 10);
36 [ + - ][ + - ]: 9537 : if (end && *end == ']')
37 [ - + ]: 9537 : BUG_ON(kid > UINT_MAX);
38 : : else
39 : : kid = 0;
40 : : }
41 : : }
42 : :
43 : 9537 : return (unsigned int)kid;
44 : : }
45 : :
46 : 4 : bool check_ns_proc(struct fd_link *link)
47 : : {
48 : : unsigned int i, kid;
49 : :
50 [ + - ]: 4 : for (i = 0; i < ARRAY_SIZE(ns_desc_array); i++) {
51 : 4 : kid = parse_ns_link(link->name + 1, link->len - 1, ns_desc_array[i]);
52 [ - + ]: 4 : if (!kid)
53 : 0 : continue;
54 : :
55 : 4 : link->ns_d = ns_desc_array[i];
56 : 4 : link->ns_kid = kid;
57 : 4 : return true;
58 : : }
59 : :
60 : : return false;
61 : : }
62 : :
63 : 2654 : int switch_ns(int pid, struct ns_desc *nd, int *rst)
64 : : {
65 : : char buf[32];
66 : : int nsfd;
67 : : int ret = -1;
68 : :
69 : 2654 : snprintf(buf, sizeof(buf), "/proc/%d/ns/%s", pid, nd->str);
70 : : nsfd = open(buf, O_RDONLY);
71 [ - + ]: 2654 : if (nsfd < 0) {
72 : 0 : pr_perror("Can't open ipcns file");
73 : 0 : goto err_ns;
74 : : }
75 : :
76 [ + + ]: 2654 : if (rst) {
77 : 2008 : snprintf(buf, sizeof(buf), "/proc/self/ns/%s", nd->str);
78 : 2008 : *rst = open(buf, O_RDONLY);
79 [ - + ]: 2008 : if (*rst < 0) {
80 : 0 : pr_perror("Can't open ns file");
81 : 0 : goto err_rst;
82 : : }
83 : : }
84 : :
85 : 2654 : ret = setns(nsfd, nd->cflag);
86 [ - + ]: 2654 : if (ret < 0) {
87 : 0 : pr_perror("Can't setns %d/%s", pid, nd->str);
88 : : goto err_set;
89 : : }
90 : :
91 : 2654 : close(nsfd);
92 : 2654 : return 0;
93 : :
94 : : err_set:
95 [ # # ]: 0 : if (rst)
96 : 0 : close(*rst);
97 : : err_rst:
98 : 0 : close(nsfd);
99 : : err_ns:
100 : : return -1;
101 : : }
102 : :
103 : 2008 : int restore_ns(int rst, struct ns_desc *nd)
104 : : {
105 : : int ret;
106 : :
107 : 2008 : ret = setns(rst, nd->cflag);
108 [ - + ]: 2008 : if (ret < 0)
109 : 0 : pr_perror("Can't restore ns back");
110 : :
111 : 2008 : close(rst);
112 : :
113 : 2008 : return ret;
114 : : }
115 : :
116 : : struct ns_id *ns_ids = NULL;
117 : : static unsigned int ns_next_id = 1;
118 : : unsigned long root_ns_mask = 0;
119 : :
120 : 2466 : int rst_add_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd)
121 : : {
122 : : struct ns_id *nsid;
123 : :
124 [ + + ]: 2466 : for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
125 [ + - ]: 1453 : if (nsid->id == id) {
126 [ - + ]: 1453 : if (pid_rst_prio(pid, nsid->pid))
127 : 0 : nsid->pid = pid;
128 : : return 0;
129 : : }
130 : : }
131 : :
132 : 1013 : nsid = shmalloc(sizeof(struct ns_id));
133 [ + - ]: 1013 : if (nsid == NULL)
134 : : return -1;
135 : :
136 : 1013 : nsid->nd = nd;
137 : 1013 : nsid->id = id;
138 : 1013 : nsid->pid = pid;
139 : : futex_set(&nsid->created, 0);
140 : :
141 : 1013 : nsid->next = ns_ids;
142 : 1013 : ns_ids = nsid;
143 : :
144 : 1013 : pr_info("Add namespace %d pid %d\n", nsid->id, nsid->pid);
145 : :
146 : 1013 : return 0;
147 : : }
148 : :
149 : : static unsigned int lookup_ns_id(unsigned int kid, struct ns_desc *nd)
150 : : {
151 : : struct ns_id *nsid;
152 : :
153 [ + - ][ + + ]: 29211 : for (nsid = ns_ids; nsid != NULL; nsid = nsid->next)
154 [ + + ][ + - ]: 23921 : if (nsid->kid == kid && nsid->nd == nd)
[ + + ][ + - ]
155 : 4247 : return nsid->id;
156 : :
157 : : return 0;
158 : : }
159 : :
160 : 133866 : struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd)
161 : : {
162 : : struct ns_id *nsid;
163 : :
164 [ + - ]: 141018 : for (nsid = ns_ids; nsid != NULL; nsid = nsid->next)
165 [ + + ][ - + ]: 141018 : if (nsid->id == id && nsid->nd == nd)
166 : : return nsid;
167 : :
168 : : return NULL;
169 : : }
170 : :
171 : 9533 : static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd)
172 : : {
173 : : unsigned int id;
174 : : struct ns_id *nsid;
175 : :
176 : : id = lookup_ns_id(kid, nd);
177 [ + + ]: 9533 : if (id)
178 : : return id;
179 : :
180 [ + + ]: 5290 : if (pid != getpid()) {
181 [ + - ]: 1696 : if (pid == root_item->pid.real) {
182 [ - + ]: 1696 : BUG_ON(root_ns_mask & nd->cflag);
183 : 1696 : pr_info("Will take %s namespace in the image\n", nd->str);
184 : 1696 : root_ns_mask |= nd->cflag;
185 [ # # ]: 0 : } else if (nd->cflag & ~CLONE_SUBNS) {
186 : 0 : pr_err("Can't dump nested %s namespace for %d\n",
187 : : nd->str, pid);
188 : 0 : return 0;
189 : : }
190 : : }
191 : :
192 [ - + ]: 5290 : nsid = xmalloc(sizeof(*nsid));
193 [ + - ]: 5290 : if (!nsid)
194 : : return 0;
195 : :
196 : 5290 : nsid->id = ns_next_id++;
197 : 5290 : nsid->kid = kid;
198 : 5290 : nsid->nd = nd;
199 : 5290 : nsid->next = ns_ids;
200 : 5290 : nsid->pid = pid;
201 : 5290 : ns_ids = nsid;
202 : :
203 : 5290 : pr_info("Collected %u.%s namespace\n", nsid->id, nd->str);
204 : :
205 : 5290 : return nsid->id;
206 : : }
207 : :
208 : 9533 : static unsigned int get_ns_id(int pid, struct ns_desc *nd)
209 : : {
210 : : int proc_dir, ret;
211 : : unsigned int kid;
212 : : char ns_path[10], ns_id[32];
213 : :
214 : 9533 : proc_dir = open_pid_proc(pid);
215 [ + - ]: 9533 : if (proc_dir < 0)
216 : : return 0;
217 : :
218 : 9533 : sprintf(ns_path, "ns/%s", nd->str);
219 : 9533 : ret = readlinkat(proc_dir, ns_path, ns_id, sizeof(ns_id));
220 [ - + ]: 9533 : if (ret < 0) {
221 : 0 : pr_perror("Can't readlink ns link");
222 : 0 : return 0;
223 : : }
224 : :
225 : 9533 : kid = parse_ns_link(ns_id, ret, nd);
226 [ - + ]: 9533 : BUG_ON(!kid);
227 : :
228 : 9533 : return generate_ns_id(pid, kid, nd);
229 : : }
230 : :
231 : 4 : int dump_one_ns_file(int lfd, u32 id, const struct fd_parms *p)
232 : : {
233 : 4 : int fd = fdset_fd(glob_fdset, CR_FD_NS_FILES);
234 : 4 : NsFileEntry nfe = NS_FILE_ENTRY__INIT;
235 : 4 : struct fd_link *link = p->link;
236 : : unsigned int nsid;
237 : :
238 : 4 : nsid = lookup_ns_id(link->ns_kid, link->ns_d);
239 [ - + ]: 4 : if (!nsid) {
240 : 0 : pr_err("No NS ID with kid %u\n", link->ns_kid);
241 : 0 : return -1;
242 : : }
243 : :
244 : 4 : nfe.id = id;
245 : 4 : nfe.ns_id = nsid;
246 : 4 : nfe.ns_cflag = link->ns_d->cflag;
247 : 4 : nfe.flags = p->flags;
248 : :
249 : 4 : return pb_write_one(fd, &nfe, PB_NS_FILE);
250 : : }
251 : :
252 : : const struct fdtype_ops nsfile_dump_ops = {
253 : : .type = FD_TYPES__NS,
254 : : .dump = dump_one_ns_file,
255 : : };
256 : :
257 : : struct ns_file_info {
258 : : struct file_desc d;
259 : : NsFileEntry *nfe;
260 : : };
261 : :
262 : 2 : static int open_ns_fd(struct file_desc *d)
263 : : {
264 : : struct ns_file_info *nfi = container_of(d, struct ns_file_info, d);
265 : : struct pstree_item *item, *t;
266 : : struct ns_desc *nd = NULL;
267 : : char path[64];
268 : : int fd;
269 : :
270 : : /*
271 : : * Find out who can open us.
272 : : *
273 : : * FIXME I need a hash or RBtree here.
274 : : */
275 [ + - ]: 2 : for_each_pstree_item(t) {
276 : 2 : TaskKobjIdsEntry *ids = t->ids;
277 : :
278 [ + - ]: 2 : if (ids->pid_ns_id == nfi->nfe->ns_id) {
279 : : item = t;
280 : : nd = &pid_ns_desc;
281 : : break;
282 [ - + ]: 2 : } else if (ids->net_ns_id == nfi->nfe->ns_id) {
283 : : item = t;
284 : : nd = &net_ns_desc;
285 : : break;
286 [ # # ]: 0 : } else if (ids->ipc_ns_id == nfi->nfe->ns_id) {
287 : : item = t;
288 : : nd = &ipc_ns_desc;
289 : : break;
290 [ # # ]: 0 : } else if (ids->uts_ns_id == nfi->nfe->ns_id) {
291 : : item = t;
292 : : nd = &uts_ns_desc;
293 : : break;
294 [ # # ]: 0 : } else if (ids->mnt_ns_id == nfi->nfe->ns_id) {
295 : : item = t;
296 : : nd = &mnt_ns_desc;
297 : : break;
298 : : }
299 : : }
300 : :
301 [ - + ]: 2 : if (!nd || !item) {
302 : 0 : pr_err("Can't find suitable NS ID for %#x\n", nfi->nfe->ns_id);
303 : 0 : return -1;
304 : : }
305 : :
306 [ - + ]: 2 : if (nd->cflag != nfi->nfe->ns_cflag) {
307 : 0 : pr_err("Clone flag mismatch for %#x\n", nfi->nfe->ns_id);
308 : 0 : return -1;
309 : : }
310 : :
311 : 2 : snprintf(path, sizeof(path) - 1, "/proc/%d/ns/%s", item->pid.virt, nd->str);
312 : 2 : path[sizeof(path) - 1] = '\0';
313 : :
314 : 2 : fd = open(path, nfi->nfe->flags);
315 [ - + ]: 2 : if (fd < 0) {
316 : 0 : pr_perror("Can't open file %s on restore", path);
317 : 0 : return fd;
318 : : }
319 : :
320 : : return fd;
321 : : }
322 : :
323 : : static struct file_desc_ops ns_desc_ops = {
324 : : .type = FD_TYPES__NS,
325 : : .open = open_ns_fd,
326 : : };
327 : :
328 : 2 : static int collect_one_nsfile(void *o, ProtobufCMessage *base)
329 : : {
330 : : struct ns_file_info *nfi = o;
331 : :
332 : 2 : nfi->nfe = pb_msg(base, NsFileEntry);
333 : 2 : pr_info("Collected ns file ID %#x NS-ID %#x\n", nfi->nfe->id, nfi->nfe->ns_id);
334 : 2 : return file_desc_add(&nfi->d, nfi->nfe->id, &ns_desc_ops);
335 : : }
336 : :
337 : : struct collect_image_info nsfile_cinfo = {
338 : : .fd_type = CR_FD_NS_FILES,
339 : : .pb_type = PB_NS_FILE,
340 : : .priv_size = sizeof(struct ns_file_info),
341 : : .collect = collect_one_nsfile,
342 : : .flags = COLLECT_OPTIONAL,
343 : : };
344 : :
345 : 1369 : int dump_task_ns_ids(struct pstree_item *item)
346 : : {
347 : 1369 : int pid = item->pid.real;
348 : 1369 : TaskKobjIdsEntry *ids = item->ids;
349 : :
350 : 1369 : ids->has_pid_ns_id = true;
351 : 1369 : ids->pid_ns_id = get_ns_id(pid, &pid_ns_desc);
352 [ - + ]: 1369 : if (!ids->pid_ns_id) {
353 : 0 : pr_err("Can't make pidns id\n");
354 : 0 : return -1;
355 : : }
356 : :
357 : 1369 : ids->has_net_ns_id = true;
358 : 1369 : ids->net_ns_id = get_ns_id(pid, &net_ns_desc);
359 [ - + ]: 1369 : if (!ids->net_ns_id) {
360 : 0 : pr_err("Can't make netns id\n");
361 : 0 : return -1;
362 : : }
363 : :
364 : 1369 : ids->has_ipc_ns_id = true;
365 : 1369 : ids->ipc_ns_id = get_ns_id(pid, &ipc_ns_desc);
366 [ - + ]: 1369 : if (!ids->ipc_ns_id) {
367 : 0 : pr_err("Can't make ipcns id\n");
368 : 0 : return -1;
369 : : }
370 : :
371 : 1369 : ids->has_uts_ns_id = true;
372 : 1369 : ids->uts_ns_id = get_ns_id(pid, &uts_ns_desc);
373 [ - + ]: 1369 : if (!ids->uts_ns_id) {
374 : 0 : pr_err("Can't make utsns id\n");
375 : 0 : return -1;
376 : : }
377 : :
378 : 1369 : ids->has_mnt_ns_id = true;
379 : 1369 : ids->mnt_ns_id = get_ns_id(pid, &mnt_ns_desc);
380 [ - + ]: 1369 : if (!ids->mnt_ns_id) {
381 : 0 : pr_err("Can't make mntns id\n");
382 : 0 : return -1;
383 : : }
384 : :
385 : : return 0;
386 : : }
387 : :
388 : : static int gen_ns_ids(int pid)
389 : : {
390 : : /* needed for mntns_collect_root */
391 [ + - ][ + - ]: 2688 : if (!get_ns_id(pid, &mnt_ns_desc))
392 : : return -1;
393 : : return 0;
394 : : }
395 : :
396 : : /*
397 : : * We use ns_mask in various places to check whether
398 : : * the tasks we dump live in namespaces or not. The
399 : : * mask generation is tied with dumping inventory and
400 : : * tasks' images, which is not needed for pre-dump.
401 : : * This routine generates a mask for pre-dump.
402 : : */
403 : 1344 : int gen_predump_ns_mask(void)
404 : : {
405 [ - + ]: 1344 : BUG_ON(root_ns_mask);
406 : :
407 [ + - ]: 2688 : if (gen_ns_ids(getpid()))
408 : : return -1;
409 [ + - ]: 1344 : if (gen_ns_ids(root_item->pid.real))
410 : : return -1;
411 : :
412 : 1344 : pr_info("NS mask generated: %lx\n", root_ns_mask);
413 : 1344 : return 0;
414 : : }
415 : :
416 : 1066 : static int do_dump_namespaces(struct ns_id *ns)
417 : : {
418 : : int ret = -1;
419 : :
420 [ + + + - : 1066 : switch (ns->nd->cflag) {
+ ]
421 : : case CLONE_NEWPID:
422 : : case CLONE_NEWNS:
423 : : ret = 0;
424 : : break;
425 : : case CLONE_NEWUTS:
426 : 212 : pr_info("Dump UTS namespace %d via %d\n",
427 : : ns->id, ns->pid);
428 : 212 : ret = dump_uts_ns(ns->pid, ns->id);
429 : 212 : break;
430 : : case CLONE_NEWIPC:
431 : 220 : pr_info("Dump IPC namespace %d via %d\n",
432 : : ns->id, ns->pid);
433 : 220 : ret = dump_ipc_ns(ns->pid, ns->id);
434 : 220 : break;
435 : : case CLONE_NEWNET:
436 : 214 : pr_info("Dump NET namespace info %d via %d\n",
437 : : ns->id, ns->pid);
438 : 214 : ret = dump_net_ns(ns->pid, ns->id);
439 : 214 : break;
440 : : default:
441 : 0 : pr_err("Unknown namespace flag %x", ns->nd->cflag);
442 : 0 : break;
443 : : }
444 : :
445 : 1066 : return ret;
446 : :
447 : : }
448 : :
449 : 226 : int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
450 : : {
451 : : struct pid *ns_pid = &item->pid;
452 : : struct ns_id *ns;
453 : : int pid, status;
454 : : int ret = 0;
455 : :
456 : : /*
457 : : * The setns syscall is cool, we can switch to the other
458 : : * namespace and then return back to our initial one, but
459 : : * for me it's much easier just to fork another task and
460 : : * let it do the job, all the more so it can be done in
461 : : * parallel with task dumping routine.
462 : : *
463 : : * However, the question how to dump sockets from the target
464 : : * net namespace with this is still open
465 : : */
466 : :
467 : 226 : pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->virt, ns_pid->real);
468 : :
469 [ + + ][ - + ]: 226 : if ((ns_flags & CLONE_NEWPID) && ns_pid->virt != 1) {
470 : 0 : pr_err("Can't dump a pid namespace without the process init\n");
471 : 0 : return -1;
472 : : }
473 : :
474 [ + + ]: 2422 : for (ns = ns_ids; ns; ns = ns->next) {
475 : : /* Skip current namespaces, which are in the list too */
476 [ + + ]: 2196 : if (ns->pid == getpid())
477 : 1130 : continue;
478 : :
479 : 1066 : pid = fork();
480 [ - + ]: 2132 : if (pid < 0) {
481 : 0 : pr_perror("Can't fork ns dumper");
482 : 0 : return -1;
483 : : }
484 : :
485 [ + + ]: 2132 : if (pid == 0) {
486 : 1066 : ret = do_dump_namespaces(ns);
487 : 1066 : exit(ret);
488 : : }
489 : :
490 : 1066 : ret = waitpid(pid, &status, 0);
491 [ - + ]: 1066 : if (ret != pid) {
492 : 0 : pr_perror("Can't wait ns dumper");
493 : 0 : return -1;
494 : : }
495 : :
496 [ + - ][ - + ]: 1066 : if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
497 : 0 : pr_err("Namespaces dumping finished with error %d\n", status);
498 : 0 : return -1;
499 : : }
500 : : }
501 : :
502 : 226 : pr_info("Namespaces dump complete\n");
503 : 226 : return 0;
504 : : }
505 : :
506 : 565 : int prepare_namespace(struct pstree_item *item, unsigned long clone_flags)
507 : : {
508 : 565 : pid_t pid = item->pid.virt;
509 : : int id;
510 : :
511 : 565 : pr_info("Restoring namespaces %d flags 0x%lx\n",
512 : : item->pid.virt, clone_flags);
513 : :
514 : : /*
515 : : * On netns restore we launch an IP tool, thus we
516 : : * have to restore it _before_ altering the mount
517 : : * tree (i.e. -- mnt_ns restoring)
518 : : */
519 : :
520 [ + - ]: 565 : id = ns_per_id ? item->ids->net_ns_id : pid;
521 [ + + ][ + - ]: 565 : if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(id))
522 : : return -1;
523 [ + - ]: 357 : id = ns_per_id ? item->ids->uts_ns_id : pid;
524 [ + + ][ + - ]: 357 : if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(id))
525 : : return -1;
526 [ + - ]: 357 : id = ns_per_id ? item->ids->ipc_ns_id : pid;
527 [ + + ][ + - ]: 357 : if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(id))
528 : : return -1;
529 [ + - ]: 357 : id = ns_per_id ? item->ids->mnt_ns_id : pid;
530 [ + + ][ # # ]: 357 : if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(id))
531 : : return -1;
532 : :
533 : : return 0;
534 : : }
535 : :
536 : 0 : int try_show_namespaces(int ns_pid)
537 : : {
538 : : struct cr_fdset *fdset;
539 : : int i, fd, ret;
540 : : TaskKobjIdsEntry *ids;
541 : :
542 : 0 : pr_msg("Namespaces for %d:\n", ns_pid);
543 : :
544 : 0 : fd = open_image(CR_FD_IDS, O_RSTR, ns_pid);
545 [ # # ]: 0 : if (fd < 0)
546 : : return -1;
547 : 0 : ret = pb_read_one(fd, &ids, PB_IDS);
548 : 0 : close(fd);
549 [ # # ]: 0 : if (ret < 0)
550 : : return -1;
551 : :
552 : 0 : fdset = cr_fdset_open(ids->net_ns_id, NETNS, O_SHOW);
553 [ # # ]: 0 : if (fdset) {
554 : 0 : pr_msg("-------------------NETNS---------------------\n");
555 [ # # ]: 0 : for (i = _CR_FD_NETNS_FROM + 1; i < _CR_FD_NETNS_TO; i++) {
556 : : int fd;
557 : :
558 : 0 : fd = fdset_fd(fdset, i);
559 [ # # ]: 0 : if (fd == -1)
560 : 0 : continue;
561 : :
562 : 0 : cr_parse_fd(fd, fdset_template[i].magic);
563 : : }
564 : 0 : close_cr_fdset(&fdset);
565 : : }
566 : :
567 : 0 : fdset = cr_fdset_open(ids->ipc_ns_id, IPCNS, O_SHOW);
568 [ # # ]: 0 : if (fdset) {
569 : 0 : pr_msg("-------------------IPCNS---------------------\n");
570 [ # # ]: 0 : for (i = _CR_FD_IPCNS_FROM + 1; i < _CR_FD_IPCNS_TO; i++) {
571 : 0 : fd = fdset_fd(fdset, i);
572 [ # # ]: 0 : if (fd == -1)
573 : 0 : continue;
574 : :
575 : 0 : cr_parse_fd(fd, fdset_template[i].magic);
576 : : }
577 : 0 : close_cr_fdset(&fdset);
578 : : }
579 : :
580 : 0 : fd = open_image(CR_FD_UTSNS, O_SHOW, ids->uts_ns_id);
581 [ # # ]: 0 : if (fd >= 0) {
582 : 0 : pr_msg("-------------------UTSNS---------------------\n");
583 : 0 : cr_parse_fd(fd, fdset_template[CR_FD_UTSNS].magic);
584 : 0 : close(fd);
585 : : }
586 : :
587 : 0 : fd = open_image(CR_FD_MNTS, O_SHOW, ids->mnt_ns_id);
588 [ # # ]: 0 : if (fd > 0) {
589 : 0 : pr_msg("-------------------MNTNS---------------------\n");
590 : 0 : cr_parse_fd(fd, fdset_template[CR_FD_MNTS].magic);
591 : 0 : close(fd);
592 : : }
593 : :
594 : 0 : pr_msg("---[ end of %d namespaces ]---\n", ns_pid);
595 : 0 : return 0;
596 : : }
597 : :
598 : : struct ns_desc pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid");
599 : : struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");
|