Branch data Line data Source code
1 : : #include <sys/time.h>
2 : : #include <stdio.h>
3 : : #include <stdlib.h>
4 : : #include <stdarg.h>
5 : : #include <signal.h>
6 : : #include <limits.h>
7 : : #include <unistd.h>
8 : : #include <errno.h>
9 : : #include <string.h>
10 : :
11 : : #include <fcntl.h>
12 : :
13 : : #include <sys/types.h>
14 : : #include <sys/stat.h>
15 : : #include <sys/vfs.h>
16 : :
17 : : #include <sys/sendfile.h>
18 : :
19 : : #include <sched.h>
20 : : #include <sys/resource.h>
21 : :
22 : : #include "protobuf.h"
23 : : #include "protobuf/fdinfo.pb-c.h"
24 : : #include "protobuf/fs.pb-c.h"
25 : : #include "protobuf/mm.pb-c.h"
26 : : #include "protobuf/creds.pb-c.h"
27 : : #include "protobuf/core.pb-c.h"
28 : : #include "protobuf/file-lock.pb-c.h"
29 : : #include "protobuf/rlimit.pb-c.h"
30 : : #include "protobuf/siginfo.pb-c.h"
31 : :
32 : : #include "asm/types.h"
33 : : #include "list.h"
34 : : #include "fdset.h"
35 : : #include "file-ids.h"
36 : : #include "kcmp-ids.h"
37 : : #include "compiler.h"
38 : : #include "crtools.h"
39 : : #include "cr_options.h"
40 : : #include "servicefd.h"
41 : : #include "syscall.h"
42 : : #include "ptrace.h"
43 : : #include "util.h"
44 : : #include "sockets.h"
45 : : #include "namespaces.h"
46 : : #include "image.h"
47 : : #include "proc_parse.h"
48 : : #include "parasite.h"
49 : : #include "parasite-syscall.h"
50 : : #include "files.h"
51 : : #include "files-reg.h"
52 : : #include "shmem.h"
53 : : #include "sk-inet.h"
54 : : #include "pstree.h"
55 : : #include "mount.h"
56 : : #include "tty.h"
57 : : #include "net.h"
58 : : #include "sk-packet.h"
59 : : #include "cpu.h"
60 : : #include "elf.h"
61 : : #include "file-lock.h"
62 : : #include "page-xfer.h"
63 : : #include "kerndat.h"
64 : : #include "stats.h"
65 : : #include "mem.h"
66 : : #include "vdso.h"
67 : : #include "page-pipe.h"
68 : : #include "posix-timer.h"
69 : : #include "vdso.h"
70 : : #include "vma.h"
71 : : #include "cr-service.h"
72 : : #include "plugin.h"
73 : : #include "irmap.h"
74 : :
75 : : #include "asm/dump.h"
76 : :
77 : : #define NR_ATTEMPTS 5
78 : :
79 : : static char loc_buf[PAGE_SIZE];
80 : :
81 : 466752 : bool privately_dump_vma(struct vma_area *vma)
82 : : {
83 : : /*
84 : : * The special areas are not dumped.
85 : : */
86 [ + + ]: 466752 : if (!(vma->e->status & VMA_AREA_REGULAR))
87 : : return false;
88 : :
89 : : /* No dumps for file-shared mappings */
90 [ + + ]: 455760 : if (vma->e->status & VMA_FILE_SHARED)
91 : : return false;
92 : :
93 : : /* No dumps for SYSV IPC mappings */
94 [ + + ]: 455472 : if (vma->e->status & VMA_AREA_SYSVIPC)
95 : : return false;
96 : :
97 [ + + ]: 455352 : if (vma_area_is(vma, VMA_ANON_SHARED))
98 : : return false;
99 : :
100 [ - + ]: 454200 : if (!vma_area_is(vma, VMA_ANON_PRIVATE) &&
101 : : !vma_area_is(vma, VMA_FILE_PRIVATE)) {
102 : 0 : pr_warn("Unexpected VMA area found\n");
103 : 0 : return false;
104 : : }
105 : :
106 [ + - ]: 454200 : if (vma->e->end > TASK_SIZE)
107 : : return false;
108 : :
109 : 454200 : return true;
110 : : }
111 : :
112 : 155584 : static void close_vma_file(struct vma_area *vma)
113 : : {
114 [ + + ]: 155584 : if (vma->vm_file_fd < 0)
115 : : return;
116 [ + - ]: 39528 : if (vma->e->status & VMA_AREA_SOCKET)
117 : : return;
118 [ + + ]: 39528 : if (vma->file_borrowed)
119 : : return;
120 : :
121 : 15816 : close(vma->vm_file_fd);
122 : : }
123 : :
124 : 3664 : void free_mappings(struct vm_area_list *vma_area_list)
125 : : {
126 : : struct vma_area *vma_area, *p;
127 : :
128 [ + + ]: 159248 : list_for_each_entry_safe(vma_area, p, &vma_area_list->h, list) {
129 : 155584 : close_vma_file(vma_area);
130 [ + + ]: 155584 : if (!vma_area->file_borrowed)
131 : 131872 : free(vma_area->st);
132 : 155584 : free(vma_area);
133 : : }
134 : :
135 : 3664 : INIT_LIST_HEAD(&vma_area_list->h);
136 : 3664 : vma_area_list->nr = 0;
137 : 3664 : }
138 : :
139 : 3664 : int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list)
140 : : {
141 : : int ret = -1;
142 : :
143 : 3664 : pr_info("\n");
144 : 3664 : pr_info("Collecting mappings (pid: %d)\n", pid);
145 : 3664 : pr_info("----------------------------------------\n");
146 : :
147 : 3664 : ret = parse_smaps(pid, vma_area_list, true);
148 [ + - ]: 3664 : if (ret < 0)
149 : : goto err;
150 : :
151 : 3664 : pr_info("Collected, longest area occupies %lu pages\n", vma_area_list->longest);
152 [ + + ]: 159248 : pr_info_vma_list(&vma_area_list->h);
153 : :
154 : 3664 : pr_info("----------------------------------------\n");
155 : : err:
156 : 3664 : return ret;
157 : : }
158 : :
159 : 1389 : static int dump_sched_info(int pid, ThreadCoreEntry *tc)
160 : : {
161 : : int ret;
162 : : struct sched_param sp;
163 : :
164 : : BUILD_BUG_ON(SCHED_OTHER != 0); /* default in proto message */
165 : :
166 : 1389 : ret = sched_getscheduler(pid);
167 [ - + ]: 1389 : if (ret < 0) {
168 : 0 : pr_perror("Can't get sched policy for %d", pid);
169 : 0 : return -1;
170 : : }
171 : :
172 : 1389 : pr_info("%d has %d sched policy\n", pid, ret);
173 : 1389 : tc->has_sched_policy = true;
174 : 1389 : tc->sched_policy = ret;
175 : :
176 [ + + ]: 1389 : if ((ret == SCHED_RR) || (ret == SCHED_FIFO)) {
177 : 4 : ret = sched_getparam(pid, &sp);
178 [ - + ]: 4 : if (ret < 0) {
179 : 0 : pr_perror("Can't get sched param for %d", pid);
180 : 0 : return -1;
181 : : }
182 : :
183 : 4 : pr_info("\tdumping %d prio for %d\n", sp.sched_priority, pid);
184 : 4 : tc->has_sched_prio = true;
185 : 4 : tc->sched_prio = sp.sched_priority;
186 : : }
187 : :
188 : : /*
189 : : * The nice is ignored for RT sched policies, but is stored
190 : : * in kernel. Thus we have to take it with us in the image.
191 : : */
192 : :
193 : 1389 : errno = 0;
194 : 1389 : ret = getpriority(PRIO_PROCESS, pid);
195 [ - + ]: 1389 : if (errno) {
196 : 0 : pr_perror("Can't get nice for %d", pid);
197 : 0 : return -1;
198 : : }
199 : :
200 : 1389 : pr_info("\tdumping %d nice for %d\n", ret, pid);
201 : 1389 : tc->has_sched_nice = true;
202 : 1389 : tc->sched_nice = ret;
203 : :
204 : 1389 : return 0;
205 : : }
206 : :
207 : : struct cr_fdset *glob_fdset;
208 : :
209 : 919 : static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds)
210 : : {
211 : : struct dirent *de;
212 : : DIR *fd_dir;
213 : : int n;
214 : :
215 : 919 : pr_info("\n");
216 : 919 : pr_info("Collecting fds (pid: %d)\n", pid);
217 : 919 : pr_info("----------------------------------------\n");
218 : :
219 [ - + ][ + - ]: 919 : fd_dir = opendir_proc(pid, "fd");
[ - + ]
220 [ + - ]: 919 : if (!fd_dir)
221 : : return -1;
222 : :
223 : : n = 0;
224 [ + + ]: 6632 : while ((de = readdir(fd_dir))) {
225 [ + + ]: 5713 : if (dir_dots(de))
226 : 1838 : continue;
227 : :
228 [ + - ]: 3875 : if (n > PARASITE_MAX_FDS - 1)
229 : : return -ENOMEM;
230 : :
231 : 5713 : dfds->fds[n++] = atoi(de->d_name);
232 : : }
233 : :
234 : 919 : dfds->nr_fds = n;
235 : 919 : pr_info("Found %d file descriptors\n", n);
236 : 919 : pr_info("----------------------------------------\n");
237 : :
238 : 919 : closedir(fd_dir);
239 : :
240 : 919 : return 0;
241 : : }
242 : :
243 : 12563 : static int get_fd_mntid(int fd, int *mnt_id)
244 : : {
245 : 12563 : struct fdinfo_common fdinfo = { .mnt_id = -1};
246 : :
247 [ + - ]: 12563 : if (parse_fdinfo(fd, FD_TYPES__UND, NULL, &fdinfo))
248 : : return -1;
249 : :
250 : 12563 : *mnt_id = fdinfo.mnt_id;
251 : 12563 : return 0;
252 : : }
253 : :
254 : 2757 : static int fill_fd_params_special(int fd, struct fd_parms *p)
255 : : {
256 : 2757 : *p = FD_PARMS_INIT;
257 : :
258 [ - + ]: 2757 : if (fstat(fd, &p->stat) < 0) {
259 : 0 : pr_perror("Can't fstat exe link");
260 : 0 : return -1;
261 : : }
262 : :
263 [ + - ]: 2757 : if (get_fd_mntid(fd, &p->mnt_id))
264 : : return -1;
265 : :
266 : 2757 : return 0;
267 : : }
268 : :
269 : 919 : static int dump_task_exe_link(pid_t pid, MmEntry *mm)
270 : : {
271 : : struct fd_parms params;
272 : : int fd, ret = 0;
273 : :
274 [ - + ]: 919 : fd = open_proc(pid, "exe");
275 [ + - ]: 919 : if (fd < 0)
276 : : return -1;
277 : :
278 [ + - ]: 919 : if (fill_fd_params_special(fd, ¶ms))
279 : : return -1;
280 : :
281 [ - + ]: 919 : if (fd_id_generate_special(¶ms, &mm->exe_file_id))
282 : 0 : ret = dump_one_reg_file(fd, mm->exe_file_id, ¶ms);
283 : :
284 : 919 : close(fd);
285 : 919 : return ret;
286 : : }
287 : :
288 : 1838 : static int dump_task_fs(pid_t pid, struct parasite_dump_misc *misc, struct cr_fdset *fdset)
289 : : {
290 : : struct fd_parms p;
291 : 919 : FsEntry fe = FS_ENTRY__INIT;
292 : : int fd, ret;
293 : :
294 : 919 : fe.has_umask = true;
295 : 919 : fe.umask = misc->umask;
296 : :
297 [ - + ]: 919 : fd = open_proc(pid, "cwd");
298 [ + - ]: 919 : if (fd < 0)
299 : : return -1;
300 : :
301 [ + - ]: 919 : if (fill_fd_params_special(fd, &p))
302 : : return -1;
303 : :
304 [ + + ]: 919 : if (fd_id_generate_special(&p, &fe.cwd_id)) {
305 : 454 : ret = dump_one_reg_file(fd, fe.cwd_id, &p);
306 [ + - ]: 454 : if (ret < 0)
307 : : return ret;
308 : : }
309 : :
310 : 919 : close(fd);
311 : :
312 [ - + ]: 919 : fd = open_proc(pid, "root");
313 [ + - ]: 919 : if (fd < 0)
314 : : return -1;
315 : :
316 [ + - ]: 919 : if (fill_fd_params_special(fd, &p))
317 : : return -1;
318 : :
319 [ + + ]: 919 : if (fd_id_generate_special(&p, &fe.root_id)) {
320 : 452 : ret = dump_one_reg_file(fd, fe.root_id, &p);
321 [ + - ]: 452 : if (ret < 0)
322 : : return ret;
323 : : }
324 : :
325 : 919 : close(fd);
326 : :
327 : 919 : pr_info("Dumping task cwd id %#x root id %#x\n",
328 : : fe.cwd_id, fe.root_id);
329 : :
330 : 919 : return pb_write_one(fdset_fd(fdset, CR_FD_FS), &fe, PB_FS);
331 : : }
332 : :
333 : : static inline u_int64_t encode_rlim(unsigned long val)
334 : : {
335 : : return val == RLIM_INFINITY ? -1 : val;
336 : : }
337 : :
338 : 1838 : static int dump_task_rlimits(int pid, TaskRlimitsEntry *rls)
339 : : {
340 : : int res;
341 : :
342 [ + + ]: 15623 : for (res = 0; res <rls->n_rlimits ; res++) {
343 : : struct rlimit lim;
344 : :
345 [ - + ]: 14704 : if (prlimit(pid, res, NULL, &lim)) {
346 : 0 : pr_perror("Can't get rlimit %d", res);
347 : 0 : return -1;
348 : : }
349 : :
350 : 14704 : rls->rlimits[res]->cur = encode_rlim(lim.rlim_cur);
351 : 14704 : rls->rlimits[res]->max = encode_rlim(lim.rlim_max);
352 : : }
353 : :
354 : : return 0;
355 : : }
356 : :
357 : 19612 : static int dump_filemap(pid_t pid, struct vma_area *vma_area,
358 : : const struct cr_fdset *fdset)
359 : : {
360 : 9806 : struct fd_parms p = FD_PARMS_INIT;
361 : 9806 : VmaEntry *vma = vma_area->e;
362 : : int ret = 0;
363 : : u32 id;
364 : :
365 [ - + ]: 9806 : BUG_ON(!vma_area->st);
366 : 9806 : p.stat = *vma_area->st;
367 : :
368 [ + - ]: 9806 : if (get_fd_mntid(vma_area->vm_file_fd, &p.mnt_id))
369 : : return -1;
370 : :
371 : : /* Flags will be set during restore in get_filemap_fd() */
372 : :
373 [ + + ]: 9806 : if (fd_id_generate_special(&p, &id))
374 : 1448 : ret = dump_one_reg_file(vma_area->vm_file_fd, id, &p);
375 : :
376 : 9806 : vma->shmid = id;
377 : : return ret;
378 : : }
379 : :
380 : 20 : static int check_sysvipc_map_dump(pid_t pid, VmaEntry *vma)
381 : : {
382 [ - + ]: 10 : if (root_ns_mask & CLONE_NEWIPC)
383 : : return 0;
384 : :
385 : 0 : pr_err("Task %d with SysVIPC shmem map @%"PRIx64" doesn't live in IPC ns\n",
386 : : pid, vma->start);
387 : : return -1;
388 : : }
389 : :
390 : 1838 : static int get_task_auxv(pid_t pid, MmEntry *mm)
391 : : {
392 : : auxv_t mm_saved_auxv[AT_VECTOR_SIZE];
393 : : int fd, i, ret;
394 : :
395 : 919 : pr_info("Obtaining task auvx ...\n");
396 : :
397 [ - + ]: 919 : fd = open_proc(pid, "auxv");
398 [ + - ]: 919 : if (fd < 0)
399 : : return -1;
400 : :
401 : 919 : ret = read(fd, mm_saved_auxv, sizeof(mm_saved_auxv));
402 [ - + ]: 919 : if (ret < 0) {
403 : : ret = -1;
404 : 0 : pr_perror("Error reading %d's auxv", pid);
405 : : goto err;
406 : : } else {
407 : 919 : mm->n_mm_saved_auxv = ret / sizeof(auxv_t);
408 [ + + ]: 35841 : for (i = 0; i < mm->n_mm_saved_auxv; i++)
409 : 34922 : mm->mm_saved_auxv[i] = (u64)mm_saved_auxv[i];
410 : : }
411 : :
412 : : ret = 0;
413 : : err:
414 : 919 : close_safe(&fd);
415 : : return ret;
416 : : }
417 : :
418 : 1838 : static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
419 : : const struct parasite_dump_misc *misc,
420 : : const struct vm_area_list *vma_area_list,
421 : : const struct cr_fdset *fdset)
422 : : {
423 : 919 : MmEntry mme = MM_ENTRY__INIT;
424 : : struct vma_area *vma_area;
425 : : int ret = -1, i = 0;
426 : :
427 : 919 : pr_info("\n");
428 : 919 : pr_info("Dumping mm (pid: %d)\n", pid);
429 : 919 : pr_info("----------------------------------------\n");
430 : :
431 : 919 : mme.n_vmas = vma_area_list->nr;
432 [ - + ]: 919 : mme.vmas = xmalloc(mme.n_vmas * sizeof(VmaEntry *));
433 [ + - ]: 919 : if (!mme.vmas)
434 : : goto err;
435 : :
436 [ + + ]: 40206 : list_for_each_entry(vma_area, &vma_area_list->h, list) {
437 : 39287 : VmaEntry *vma = vma_area->e;
438 : :
439 : 39287 : pr_info_vma(vma_area);
440 : :
441 [ + + ]: 39287 : if (!vma_entry_is(vma, VMA_AREA_REGULAR))
442 : : ret = 0;
443 [ + + ]: 38368 : else if (vma_entry_is(vma, VMA_AREA_SYSVIPC))
444 : 10 : ret = check_sysvipc_map_dump(pid, vma);
445 [ + + ]: 38358 : else if (vma_entry_is(vma, VMA_ANON_SHARED))
446 : 96 : ret = add_shmem_area(pid, vma);
447 [ + + ]: 38262 : else if (vma_entry_is(vma, VMA_FILE_PRIVATE) ||
448 : : vma_entry_is(vma, VMA_FILE_SHARED))
449 : 9806 : ret = dump_filemap(pid, vma_area, fdset);
450 [ - + ]: 28456 : else if (vma_entry_is(vma, VMA_AREA_SOCKET))
451 : 0 : ret = dump_socket_map(vma_area);
452 : : else
453 : : ret = 0;
454 [ + - ]: 39287 : if (ret)
455 : : goto err;
456 : :
457 : 39287 : mme.vmas[i++] = vma;
458 : : }
459 : :
460 : 919 : mme.mm_start_code = stat->start_code;
461 : 919 : mme.mm_end_code = stat->end_code;
462 : 919 : mme.mm_start_data = stat->start_data;
463 : 919 : mme.mm_end_data = stat->end_data;
464 : 919 : mme.mm_start_stack = stat->start_stack;
465 : 919 : mme.mm_start_brk = stat->start_brk;
466 : :
467 : 919 : mme.mm_arg_start = stat->arg_start;
468 : 919 : mme.mm_arg_end = stat->arg_end;
469 : 919 : mme.mm_env_start = stat->env_start;
470 : 919 : mme.mm_env_end = stat->env_end;
471 : :
472 : 919 : mme.mm_brk = misc->brk;
473 : :
474 : 919 : mme.n_mm_saved_auxv = AT_VECTOR_SIZE;
475 [ - + ]: 919 : mme.mm_saved_auxv = xmalloc(pb_repeated_size(&mme, mm_saved_auxv));
476 [ + - ]: 919 : if (!mme.mm_saved_auxv)
477 : : goto err;
478 : :
479 [ + - ]: 919 : if (get_task_auxv(pid, &mme))
480 : : goto err;
481 : :
482 [ + - ]: 919 : if (dump_task_exe_link(pid, &mme))
483 : : goto err;
484 : :
485 : 919 : ret = pb_write_one(fdset_fd(fdset, CR_FD_MM), &mme, PB_MM);
486 [ + - ]: 919 : xfree(mme.mm_saved_auxv);
487 : : err:
488 : 919 : return ret;
489 : : }
490 : :
491 : 919 : static int dump_task_creds(struct parasite_ctl *ctl,
492 : : const struct cr_fdset *fds,
493 : : struct proc_status_creds *cr)
494 : : {
495 : 919 : CredsEntry ce = CREDS_ENTRY__INIT;
496 : :
497 : 919 : pr_info("\n");
498 : 919 : pr_info("Dumping creds for %d)\n", ctl->pid.real);
499 : 919 : pr_info("----------------------------------------\n");
500 : :
501 : 919 : ce.uid = cr->uids[0];
502 : 919 : ce.gid = cr->gids[0];
503 : 919 : ce.euid = cr->uids[1];
504 : 919 : ce.egid = cr->gids[1];
505 : 919 : ce.suid = cr->uids[2];
506 : 919 : ce.sgid = cr->gids[2];
507 : 919 : ce.fsuid = cr->uids[3];
508 : 919 : ce.fsgid = cr->gids[3];
509 : :
510 : : BUILD_BUG_ON(CR_CAP_SIZE != PROC_CAP_SIZE);
511 : :
512 : 919 : ce.n_cap_inh = CR_CAP_SIZE;
513 : 919 : ce.cap_inh = cr->cap_inh;
514 : 919 : ce.n_cap_prm = CR_CAP_SIZE;
515 : 919 : ce.cap_prm = cr->cap_prm;
516 : 919 : ce.n_cap_eff = CR_CAP_SIZE;
517 : 919 : ce.cap_eff = cr->cap_eff;
518 : 919 : ce.n_cap_bnd = CR_CAP_SIZE;
519 : 919 : ce.cap_bnd = cr->cap_bnd;
520 : :
521 [ + - ]: 919 : if (parasite_dump_creds(ctl, &ce) < 0)
522 : : return -1;
523 : :
524 : 919 : return pb_write_one(fdset_fd(fds, CR_FD_CREDS), &ce, PB_CREDS);
525 : : }
526 : :
527 : 2778 : static int get_task_futex_robust_list(pid_t pid, ThreadCoreEntry *info)
528 : : {
529 : 1389 : struct robust_list_head *head = NULL;
530 : 1389 : size_t len = 0;
531 : : int ret;
532 : :
533 : 1389 : ret = sys_get_robust_list(pid, &head, &len);
534 [ - + ]: 1389 : if (ret) {
535 : 0 : pr_err("Failed obtaining futex robust list on %d\n", pid);
536 : : return -1;
537 : : }
538 : :
539 : 2778 : info->futex_rla = encode_pointer(head);
540 : 1389 : info->futex_rla_len = (u32)len;
541 : :
542 : : return 0;
543 : : }
544 : :
545 : 919 : static int get_task_personality(pid_t pid, u32 *personality)
546 : : {
547 : : FILE *file = NULL;
548 : : int ret = -1;
549 : :
550 : 919 : pr_info("Obtaining personality ... ");
551 : :
552 [ - + ][ + - ]: 919 : file = fopen_proc(pid, "personality");
[ - + ]
553 [ + - ]: 919 : if (!file)
554 : : goto err;
555 : :
556 [ - + ]: 919 : if (!fgets(loc_buf, sizeof(loc_buf), file)) {
557 : 0 : pr_perror("Can't read task personality");
558 : 0 : goto err;
559 : : }
560 : :
561 : 919 : *personality = atoi(loc_buf);
562 : : ret = 0;
563 : :
564 : : err:
565 [ + - ]: 919 : if (file)
566 : 919 : fclose(file);
567 : 919 : return ret;
568 : : }
569 : :
570 : : static DECLARE_KCMP_TREE(vm_tree, KCMP_VM);
571 : : static DECLARE_KCMP_TREE(fs_tree, KCMP_FS);
572 : : static DECLARE_KCMP_TREE(files_tree, KCMP_FILES);
573 : : static DECLARE_KCMP_TREE(sighand_tree, KCMP_SIGHAND);
574 : :
575 : 1369 : static int dump_task_kobj_ids(struct pstree_item *item)
576 : : {
577 : : int new;
578 : : struct kid_elem elem;
579 : 1369 : int pid = item->pid.real;
580 : 1369 : TaskKobjIdsEntry *ids = item->ids;
581 : :
582 : 1369 : elem.pid = pid;
583 : 1369 : elem.idx = 0; /* really 0 for all */
584 : 1369 : elem.genid = 0; /* FIXME optimize */
585 : :
586 : 1369 : new = 0;
587 : 1369 : ids->vm_id = kid_generate_gen(&vm_tree, &elem, &new);
588 [ + - ][ - + ]: 1369 : if (!ids->vm_id || !new) {
589 : 0 : pr_err("Can't make VM id for %d\n", pid);
590 : 0 : return -1;
591 : : }
592 : :
593 : 1369 : new = 0;
594 : 1369 : ids->fs_id = kid_generate_gen(&fs_tree, &elem, &new);
595 [ + - ][ - + ]: 1369 : if (!ids->fs_id || !new) {
596 : 0 : pr_err("Can't make FS id for %d\n", pid);
597 : 0 : return -1;
598 : : }
599 : :
600 : 1369 : new = 0;
601 : 1369 : ids->files_id = kid_generate_gen(&files_tree, &elem, &new);
602 [ + - ][ + + ]: 1369 : if (!ids->files_id || (!new && !shared_fdtable(item))) {
[ - + ]
603 : 0 : pr_err("Can't make FILES id for %d\n", pid);
604 : 0 : return -1;
605 : : }
606 : :
607 : 1369 : new = 0;
608 : 1369 : ids->sighand_id = kid_generate_gen(&sighand_tree, &elem, &new);
609 [ + - ][ - + ]: 1369 : if (!ids->sighand_id || !new) {
610 : 0 : pr_err("Can't make IO id for %d\n", pid);
611 : 0 : return -1;
612 : : }
613 : :
614 : : return 0;
615 : : }
616 : :
617 : 1390 : int get_task_ids(struct pstree_item *item)
618 : : {
619 : : int ret;
620 : :
621 [ - + ]: 1390 : item->ids = xmalloc(sizeof(*item->ids));
622 [ + - ]: 1390 : if (!item->ids)
623 : : goto err;
624 : :
625 : 1390 : task_kobj_ids_entry__init(item->ids);
626 : :
627 [ + + ]: 1390 : if (item->state != TASK_DEAD) {
628 : 1369 : ret = dump_task_kobj_ids(item);
629 [ + - ]: 1369 : if (ret)
630 : : goto err_free;
631 : :
632 : 1369 : ret = dump_task_ns_ids(item);
633 [ - + ]: 1369 : if (ret)
634 : : goto err_free;
635 : : }
636 : :
637 : : return 0;
638 : :
639 : : err_free:
640 [ # # ]: 0 : xfree(item->ids);
641 : 0 : item->ids = NULL;
642 : : err:
643 : : return -1;
644 : : }
645 : :
646 : 1838 : static int dump_task_ids(struct pstree_item *item, const struct cr_fdset *cr_fdset)
647 : : {
648 : 919 : return pb_write_one(fdset_fd(cr_fdset, CR_FD_IDS), item->ids, PB_IDS);
649 : : }
650 : :
651 : 1389 : int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread *ti)
652 : : {
653 : : int ret;
654 : 1389 : ThreadCoreEntry *tc = core->thread_core;
655 : :
656 : 1389 : ret = get_task_futex_robust_list(pid, tc);
657 [ + - ]: 1389 : if (!ret)
658 : 1389 : ret = dump_sched_info(pid, tc);
659 [ + - ]: 1389 : if (!ret) {
660 : : core_put_tls(core, ti->tls);
661 : 2778 : CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(ti->tid_addr);
662 [ - + ]: 1389 : BUG_ON(!tc->sas);
663 : 1389 : copy_sas(tc->sas, &ti->sas);
664 : : }
665 : :
666 : 1389 : return ret;
667 : : }
668 : :
669 : 919 : static int dump_task_core_all(struct pstree_item *item,
670 : : const struct proc_pid_stat *stat,
671 : : const struct parasite_dump_misc *misc,
672 : : const struct cr_fdset *cr_fdset)
673 : : {
674 : 919 : int fd_core = fdset_fd(cr_fdset, CR_FD_CORE);
675 : 919 : CoreEntry *core = item->core[0];
676 : 919 : pid_t pid = item->pid.real;
677 : : int ret = -1;
678 : :
679 : 919 : pr_info("\n");
680 : 919 : pr_info("Dumping core (pid: %d)\n", pid);
681 : 919 : pr_info("----------------------------------------\n");
682 : :
683 : 919 : ret = get_task_personality(pid, &core->tc->personality);
684 [ + - ]: 919 : if (ret)
685 : : goto err;
686 : :
687 : 919 : strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
688 : 919 : core->tc->flags = stat->flags;
689 : 919 : core->tc->task_state = item->state;
690 : 919 : core->tc->exit_code = 0;
691 : :
692 : 919 : ret = dump_thread_core(pid, core, &misc->ti);
693 [ + - ]: 919 : if (ret)
694 : : goto err;
695 : :
696 : 919 : ret = dump_task_rlimits(pid, core->tc->rlimits);
697 [ + - ]: 919 : if (ret)
698 : : goto err;
699 : :
700 : 919 : ret = pb_write_one(fd_core, core, PB_CORE);
701 : : if (ret < 0)
702 : : goto err;
703 : :
704 : : err:
705 : 919 : pr_info("----------------------------------------\n");
706 : :
707 : 919 : return ret;
708 : : }
709 : :
710 : 5132 : static int parse_children(pid_t pid, pid_t **_c, int *_n)
711 : : {
712 : : FILE *file;
713 : : char *tok;
714 : : pid_t *ch = NULL;
715 : : int nr = 1;
716 : : DIR *dir;
717 : : struct dirent *de;
718 : :
719 [ - + ][ + - ]: 5132 : dir = opendir_proc(pid, "task");
[ - + ]
720 [ + - ]: 5132 : if (dir == NULL)
721 : : return -1;
722 : :
723 [ + + ]: 22476 : while ((de = readdir(dir))) {
724 [ + + ]: 17344 : if (dir_dots(de))
725 : 10264 : continue;
726 : :
727 [ - + ][ + - ]: 7080 : file = fopen_proc(pid, "task/%s/children", de->d_name);
[ - + ]
728 [ + - ]: 7080 : if (!file)
729 : : goto err;
730 : :
731 [ + + ]: 7080 : if (!(fgets(loc_buf, sizeof(loc_buf), file)))
732 : 4108 : loc_buf[0] = 0;
733 : :
734 : 7080 : fclose(file);
735 : :
736 : 7080 : tok = strtok(loc_buf, " \n");
737 [ + + ]: 21298 : while (tok) {
738 [ - + ]: 3954 : pid_t *tmp = xrealloc(ch, nr * sizeof(pid_t));
739 [ + - ]: 3954 : if (!tmp)
740 : : goto err;
741 : : ch = tmp;
742 : 7908 : ch[nr - 1] = atoi(tok);
743 : 3954 : nr++;
744 : 3954 : tok = strtok(NULL, " \n");
745 : : }
746 : :
747 : : }
748 : :
749 : 5132 : *_c = ch;
750 : 5132 : *_n = nr - 1;
751 : :
752 : 5132 : closedir(dir);
753 : 5132 : return 0;
754 : : err:
755 : 0 : closedir(dir);
756 [ # # ]: 0 : xfree(ch);
757 : : return -1;
758 : : }
759 : :
760 : : static int collect_task(struct pstree_item *item);
761 : 5128 : static int get_children(struct pstree_item *item)
762 : : {
763 : : pid_t *ch;
764 : : int ret, i, nr_children, nr_inprogress;
765 : : struct pstree_item *c;
766 : :
767 : 5128 : ret = parse_children(item->pid.real, &ch, &nr_children);
768 [ + - ]: 5128 : if (ret < 0)
769 : : return ret;
770 : :
771 : : nr_inprogress = 0;
772 [ + + ]: 9072 : for (i = 0; i < nr_children; i++) {
773 : 3944 : pid_t pid = ch[i];
774 : :
775 : : /* Is it already frozen? */
776 [ + + ]: 7464 : list_for_each_entry(c, &item->children, sibling)
777 [ + + ]: 5492 : if (c->pid.real == pid)
778 : : break;
779 : :
780 [ + + ]: 3944 : if (&c->sibling != &item->children)
781 : 1972 : continue;
782 : :
783 : 1972 : nr_inprogress++;
784 : :
785 : 1972 : pr_info("Seized task %d, state %d\n", pid, ret);
786 : :
787 : 1972 : c = alloc_pstree_item();
788 [ + - ]: 1972 : if (c == NULL) {
789 : : ret = -1;
790 : : goto free;
791 : : }
792 : :
793 : 1972 : ret = seize_task(pid, item->pid.real, &item->pgid, &item->sid);
794 [ - + ]: 1972 : if (ret < 0) {
795 : : /*
796 : : * Here is a race window between parse_children() and seize(),
797 : : * so the task could die for these time.
798 : : * Don't worry, will try again on the next attempt. The number
799 : : * of attempts is restricted, so it will exit if something
800 : : * really wrong.
801 : : */
802 : : ret = 0;
803 [ # # ]: 0 : xfree(c);
804 : 0 : continue;
805 : : }
806 : :
807 : 1972 : c->pid.real = ch[i];
808 : 1972 : c->parent = item;
809 : 1972 : c->state = ret;
810 : 1972 : list_add_tail(&c->sibling, &item->children);
811 : :
812 : : /* Here is a recursive call (Depth-first search) */
813 : 1972 : ret = collect_task(c);
814 [ + - ]: 1972 : if (ret < 0)
815 : : goto free;
816 : : }
817 : : free:
818 [ + + ]: 5128 : xfree(ch);
819 [ + - ]: 5128 : return ret < 0 ? ret : nr_inprogress;
820 : : }
821 : :
822 : 3764 : static void unseize_task_and_threads(const struct pstree_item *item, int st)
823 : : {
824 : : int i;
825 : :
826 [ + + ]: 3764 : if (item->state == TASK_DEAD)
827 : 3764 : return;
828 : :
829 : : /*
830 : : * The st is the state we want to switch tasks into,
831 : : * the item->state is the state task was in when we seized one.
832 : : */
833 : :
834 : 3676 : unseize_task(item->pid.real, item->state, st);
835 : :
836 [ + + ]: 5558 : for (i = 1; i < item->nr_threads; i++)
837 : 1882 : ptrace(PTRACE_DETACH, item->threads[i].real, NULL, NULL);
838 : : }
839 : :
840 : 1792 : static void pstree_switch_state(struct pstree_item *root_item, int st)
841 : : {
842 : : struct pstree_item *item = root_item;
843 : :
844 : 1792 : pr_info("Unfreezing tasks into %d\n", st);
845 [ + + ]: 5556 : for_each_pstree_item(item)
846 : 3764 : unseize_task_and_threads(item, st);
847 : 1792 : }
848 : :
849 : : static pid_t item_ppid(const struct pstree_item *item)
850 : : {
851 : : item = item->parent;
852 [ + + ]: 1893 : return item ? item->pid.real : -1;
853 : : }
854 : :
855 : 3885 : static int seize_threads(struct pstree_item *item,
856 : : struct pid *threads, int nr_threads)
857 : : {
858 : : int i = 0, ret, j, nr_inprogress, nr_stopped = 0;
859 : :
860 [ + + ][ - + ]: 3885 : if ((item->state == TASK_DEAD) && (nr_threads > 1)) {
861 : 0 : pr_err("Zombies with threads are not supported\n");
862 : 0 : goto err;
863 : : }
864 : :
865 : : /* The number of threads can't be less than allready frozen */
866 [ - + ]: 3885 : item->threads = xrealloc(item->threads, nr_threads * sizeof(struct pid));
867 [ + - ]: 3885 : if (item->threads == NULL)
868 : : return -1;
869 : :
870 [ + + ]: 3885 : if (item->nr_threads == 0) {
871 : 3764 : item->threads[0].real = item->pid.real;
872 : 3885 : item->nr_threads = 1;
873 : : }
874 : :
875 : : nr_inprogress = 0;
876 [ + + ]: 12436 : for (i = 0; i < nr_threads; i++) {
877 : 8551 : pid_t pid = threads[i].real;
878 [ + + ]: 8551 : if (item->pid.real == pid)
879 : 3885 : continue;
880 : :
881 [ + + ]: 212860 : for (j = 0; j < item->nr_threads; j++)
882 [ + + ]: 210967 : if (pid == item->threads[j].real)
883 : : break;
884 : :
885 [ + + ]: 4666 : if (j != item->nr_threads)
886 : 2773 : continue;
887 : 1893 : nr_inprogress++;
888 : :
889 : 1893 : pr_info("\tSeizing %d's %d thread\n",
890 : : item->pid.real, pid);
891 : :
892 : 1893 : ret = seize_task(pid, item_ppid(item), NULL, NULL);
893 [ + + ]: 1893 : if (ret < 0) {
894 : : /*
895 : : * Here is a race window between parse_threads() and seize(),
896 : : * so the task could die for these time.
897 : : * Don't worry, will try again on the next attempt. The number
898 : : * of attempts is restricted, so it will exit if something
899 : : * really wrong.
900 : : */
901 : 11 : continue;
902 : : }
903 : :
904 [ - + ]: 1882 : BUG_ON(item->nr_threads + 1 > nr_threads);
905 : 1882 : item->threads[item->nr_threads].real = pid;
906 : 1882 : item->nr_threads++;
907 : :
908 [ - + ]: 1882 : if (ret == TASK_DEAD) {
909 : 0 : pr_err("Zombie thread not supported\n");
910 : 0 : goto err;
911 : : }
912 : :
913 [ - + ]: 1882 : if (ret == TASK_STOPPED) {
914 : 0 : nr_stopped++;
915 : : }
916 : : }
917 : :
918 [ - + ]: 3885 : if (nr_stopped && nr_stopped != nr_inprogress) {
919 : 0 : pr_err("Individually stopped threads not supported\n");
920 : 0 : goto err;
921 : : }
922 : :
923 : : return nr_inprogress;
924 : : err:
925 : : return -1;
926 : : }
927 : :
928 : 3764 : static int collect_threads(struct pstree_item *item)
929 : : {
930 : : int ret, attempts = NR_ATTEMPTS;
931 : : struct pid *t;
932 : : int nr, nr_inprogress;
933 : :
934 : : nr_inprogress = 1;
935 [ + + ]: 7649 : while (nr_inprogress > 0 && attempts) {
936 : 3885 : attempts--;
937 : :
938 : 3885 : t = NULL;
939 : 3885 : nr = 0;
940 : :
941 : 3885 : ret = parse_threads(item->pid.real, &t, &nr);
942 [ + - ]: 3885 : if (ret < 0)
943 : : break;
944 : :
945 : 3885 : nr_inprogress = seize_threads(item, t, nr);
946 [ + - ]: 3885 : xfree(t);
947 [ + - ]: 3885 : if (nr_inprogress < 0)
948 : : break;
949 : :
950 : : }
951 : :
952 [ + - ]: 3764 : if (nr_inprogress && attempts)
953 : : return -1;
954 : :
955 : 3764 : return 0;
956 : : }
957 : :
958 : 3764 : static int collect_task(struct pstree_item *item)
959 : : {
960 : : int ret, nr_inprogress, attempts = NR_ATTEMPTS;
961 : :
962 : 3764 : ret = collect_threads(item);
963 [ + - ]: 3764 : if (ret < 0)
964 : : goto err_close;
965 : :
966 [ + + ]: 3764 : if (item->state == TASK_DEAD)
967 : : return 0;
968 : :
969 : : /* Depth-first search (DFS) is used for traversing a process tree. */
970 : : nr_inprogress = 1;
971 [ + + ]: 8804 : while (nr_inprogress && attempts) {
972 : 5128 : attempts--;
973 : :
974 : : /*
975 : : * Freeze children and children of children, etc.
976 : : * Then check again, that nobody is reparented.
977 : : */
978 : 5128 : nr_inprogress = get_children(item);
979 [ + - ]: 8804 : if (nr_inprogress < 0)
980 : : goto err_close;
981 : : }
982 : :
983 [ + - ]: 3676 : if (attempts == 0)
984 : : goto err_close;
985 : :
986 [ - + ][ # # ]: 3676 : if ((item->state == TASK_DEAD) && !list_empty(&item->children)) {
987 : 0 : pr_err("Zombie with children?! O_o Run, run, run!\n");
988 : 0 : goto err_close;
989 : : }
990 : :
991 : 3676 : close_pid_proc();
992 : :
993 : 3676 : pr_info("Collected %d in %d state\n", item->pid.real, item->state);
994 : 3676 : return 0;
995 : :
996 : : err_close:
997 : 0 : close_pid_proc();
998 : 0 : return -1;
999 : : }
1000 : :
1001 : 450 : int collect_pstree_ids(void)
1002 : : {
1003 : : struct pstree_item *item;
1004 : :
1005 [ + + ]: 1392 : for_each_pstree_item(item)
1006 [ + - ]: 942 : if (get_task_ids(item))
1007 : : return -1;
1008 : :
1009 : : return 0;
1010 : : }
1011 : :
1012 : 1792 : static int collect_pstree(pid_t pid)
1013 : : {
1014 : : int ret;
1015 : :
1016 : 1792 : timing_start(TIME_FREEZING);
1017 : :
1018 : 1792 : root_item = alloc_pstree_item();
1019 [ + - ]: 1792 : if (root_item == NULL)
1020 : : return -1;
1021 : :
1022 : 1792 : root_item->pid.real = pid;
1023 : 1792 : ret = seize_task(pid, -1, &root_item->pgid, &root_item->sid);
1024 [ + - ]: 1792 : if (ret < 0)
1025 : : goto err;
1026 : 1792 : pr_info("Seized task %d, state %d\n", pid, ret);
1027 : 1792 : root_item->state = ret;
1028 : :
1029 : 1792 : ret = collect_task(root_item);
1030 [ + - ]: 1792 : if (ret < 0)
1031 : : goto err;
1032 : :
1033 : 1792 : timing_stop(TIME_FREEZING);
1034 : 1792 : timing_start(TIME_FROZEN);
1035 : :
1036 : 1792 : return 0;
1037 : : err:
1038 : 0 : pstree_switch_state(root_item, TASK_ALIVE);
1039 : 0 : return -1;
1040 : : }
1041 : :
1042 : 448 : static int collect_file_locks(void)
1043 : : {
1044 [ + - ]: 448 : if (parse_file_locks())
1045 : : return -1;
1046 : :
1047 [ - + ]: 448 : if (opts.handle_file_locks)
1048 : : /*
1049 : : * If the handle file locks option(-l) is set,
1050 : : * collect work is over.
1051 : : */
1052 : : return 0;
1053 : :
1054 : : /*
1055 : : * If the handle file locks option is not set, we need to do
1056 : : * the check, any file locks hold by tasks in our pstree is
1057 : : * not allowed.
1058 : : *
1059 : : * It's hard to do it carefully, there might be some other
1060 : : * issues like tasks beyond pstree would use flocks hold by
1061 : : * dumping tasks, but we can't know it in dumping time.
1062 : : * We need to make sure these flocks only used by dumping tasks.
1063 : : * We might have to do the check that this option would only
1064 : : * be used by container dumping.
1065 : : */
1066 [ # # ]: 0 : if (!list_empty(&file_lock_list)) {
1067 : 0 : pr_err("Some file locks are hold by dumping tasks!"
1068 : : "You can try --" OPT_FILE_LOCKS " to dump them.\n");
1069 : 0 : return -1;
1070 : : }
1071 : :
1072 : : return 0;
1073 : :
1074 : : }
1075 : :
1076 : 940 : static int dump_task_thread(struct parasite_ctl *parasite_ctl,
1077 : : const struct pstree_item *item, int id)
1078 : : {
1079 : 470 : struct pid *tid = &item->threads[id];
1080 : 470 : CoreEntry *core = item->core[id];
1081 : 470 : pid_t pid = tid->real;
1082 : : int ret = -1, fd_core;
1083 : :
1084 : 470 : pr_info("\n");
1085 : 470 : pr_info("Dumping core for thread (pid: %d)\n", pid);
1086 : 470 : pr_info("----------------------------------------\n");
1087 : :
1088 : 470 : ret = parasite_dump_thread_seized(parasite_ctl, id, tid, core);
1089 [ - + ]: 470 : if (ret) {
1090 : 0 : pr_err("Can't dump thread for pid %d\n", pid);
1091 : : goto err;
1092 : : }
1093 : :
1094 : 470 : fd_core = open_image(CR_FD_CORE, O_DUMP, tid->virt);
1095 [ + - ]: 470 : if (fd_core < 0)
1096 : : goto err;
1097 : :
1098 : 470 : ret = pb_write_one(fd_core, core, PB_CORE);
1099 : :
1100 : 470 : close(fd_core);
1101 : : err:
1102 : 470 : pr_info("----------------------------------------\n");
1103 : 470 : return ret;
1104 : : }
1105 : :
1106 : 21 : static int dump_one_zombie(const struct pstree_item *item,
1107 : : const struct proc_pid_stat *pps)
1108 : : {
1109 : : CoreEntry *core;
1110 : : int ret = -1, fd_core;
1111 : :
1112 : 21 : core = core_entry_alloc(0, 1);
1113 [ + - ]: 21 : if (!core)
1114 : : return -1;
1115 : :
1116 : 21 : strncpy((char *)core->tc->comm, pps->comm, TASK_COMM_LEN);
1117 : 21 : core->tc->task_state = TASK_DEAD;
1118 : 21 : core->tc->exit_code = pps->exit_code;
1119 : :
1120 : 21 : fd_core = open_image(CR_FD_CORE, O_DUMP, item->pid.virt);
1121 [ + - ]: 21 : if (fd_core < 0)
1122 : : goto err;
1123 : :
1124 : 21 : ret = pb_write_one(fd_core, core, PB_CORE);
1125 : 21 : close(fd_core);
1126 : : err:
1127 : 21 : core_entry_free(core);
1128 : : return ret;
1129 : : }
1130 : :
1131 : 2308 : static int dump_signal_queue(pid_t tid, int fd, bool group)
1132 : : {
1133 : : struct ptrace_peeksiginfo_args arg;
1134 : : siginfo_t siginfo[32]; /* One page or all non-rt signals */
1135 : : int ret, i = 0, j, nr;
1136 : :
1137 [ + + ]: 2308 : pr_debug("Dump %s signals of %d\n", group ? "shared" : "private", tid);
1138 : :
1139 : 2308 : arg.nr = sizeof(siginfo) / sizeof(siginfo_t);
1140 : 2308 : arg.flags = 0;
1141 [ + + ]: 2308 : if (group)
1142 : 2327 : arg.flags |= PTRACE_PEEKSIGINFO_SHARED;
1143 : :
1144 : : for (; ; ) {
1145 : 2327 : arg.off = i;
1146 : :
1147 : 2327 : ret = ptrace(PTRACE_PEEKSIGINFO, tid, &arg, siginfo);
1148 [ - + ]: 2327 : if (ret < 0) {
1149 [ # # ]: 0 : if (errno == EIO) {
1150 : 0 : pr_warn("ptrace doesn't support PTRACE_PEEKSIGINFO\n");
1151 : : ret = 0;
1152 : : } else
1153 : 0 : pr_perror("ptrace");
1154 : : break;
1155 : : }
1156 : :
1157 [ + + ]: 2327 : if (ret == 0)
1158 : : break;
1159 : : nr = ret;
1160 : :
1161 [ + + ]: 302 : for (j = 0; j < nr; j++) {
1162 : 283 : SiginfoEntry sie = SIGINFO_ENTRY__INIT;
1163 : :
1164 : 283 : sie.siginfo.len = sizeof(siginfo_t);
1165 : 283 : sie.siginfo.data = (void *) (siginfo + j);
1166 : :
1167 : 283 : ret = pb_write_one(fd, &sie, PB_SIGINFO);
1168 [ + - ]: 283 : if (ret < 0)
1169 : : break;
1170 : 283 : i++;
1171 : : }
1172 : : }
1173 : :
1174 : 2308 : return ret;
1175 : : }
1176 : :
1177 : 1389 : static int dump_thread_signals(struct pid *tid)
1178 : : {
1179 : : int fd, ret;
1180 : :
1181 : 1389 : fd = open_image(CR_FD_PSIGNAL, O_DUMP, tid->virt);
1182 [ + - ]: 1389 : if (fd < 0)
1183 : : return -1;
1184 : 1389 : ret = dump_signal_queue(tid->real, fd, false);
1185 : 1389 : close(fd);
1186 : :
1187 : 1389 : return ret;
1188 : : }
1189 : :
1190 : 1838 : static int dump_task_signals(pid_t pid, struct pstree_item *item,
1191 : : struct cr_fdset *cr_fdset)
1192 : : {
1193 : : int i, ret;
1194 : :
1195 : 919 : ret = dump_signal_queue(pid, fdset_fd(cr_fdset, CR_FD_SIGNAL), true);
1196 [ + - ]: 919 : if (ret) {
1197 : 0 : pr_err("Can't dump pending signals (pid: %d)\n", pid);
1198 : : return -1;
1199 : : }
1200 : :
1201 [ + + ]: 2308 : for (i = 0; i < item->nr_threads; i++) {
1202 : 1389 : ret = dump_thread_signals(&item->threads[i]);
1203 [ + - ]: 1389 : if (ret)
1204 : : return -1;
1205 : : }
1206 : :
1207 : : return 0;
1208 : : }
1209 : :
1210 : : static struct proc_pid_stat pps_buf;
1211 : :
1212 : 919 : static int dump_task_threads(struct parasite_ctl *parasite_ctl,
1213 : 470 : const struct pstree_item *item)
1214 : : {
1215 : : int i;
1216 : :
1217 [ + + ]: 2308 : for (i = 0; i < item->nr_threads; i++) {
1218 : : /* Leader is already dumped */
1219 [ + + ]: 1389 : if (item->pid.real == item->threads[i].real) {
1220 : 919 : item->threads[i].virt = item->pid.virt;
1221 : 919 : continue;
1222 : : }
1223 [ + - ]: 470 : if (dump_task_thread(parasite_ctl, item, i))
1224 : : return -1;
1225 : : }
1226 : :
1227 : : return 0;
1228 : : }
1229 : :
1230 : : /*
1231 : : * What this routine does is just reads pid-s of dead
1232 : : * tasks in item's children list from item's ns proc.
1233 : : *
1234 : : * It does *not* find wihch real pid corresponds to
1235 : : * which virtual one, but it's not required -- all we
1236 : : * need to dump for zombie can be found in the same
1237 : : * ns proc.
1238 : : */
1239 : :
1240 : 4 : static int fill_zombies_pids(struct pstree_item *item)
1241 : : {
1242 : : struct pstree_item *child;
1243 : : int i, nr;
1244 : : pid_t *ch;
1245 : :
1246 [ + - ]: 4 : if (parse_children(item->pid.virt, &ch, &nr) < 0)
1247 : : return -1;
1248 : :
1249 [ + + ]: 14 : list_for_each_entry(child, &item->children, sibling) {
1250 [ - + ]: 10 : if (child->pid.virt < 0)
1251 : 10 : continue;
1252 [ # # ]: 0 : for (i = 0; i < nr; i++) {
1253 [ # # ]: 0 : if (ch[i] == child->pid.virt) {
1254 : 0 : ch[i] = -1;
1255 : 0 : break;
1256 : : }
1257 : : }
1258 : : }
1259 : :
1260 : : i = 0;
1261 [ + + ]: 14 : list_for_each_entry(child, &item->children, sibling) {
1262 [ + - ]: 10 : if (child->pid.virt > 0)
1263 : 0 : continue;
1264 [ + - ]: 16 : for (; i < nr; i++) {
1265 [ + + ]: 16 : if (ch[i] < 0)
1266 : 6 : continue;
1267 : 10 : child->pid.virt = ch[i];
1268 : 10 : ch[i] = -1;
1269 : 10 : break;
1270 : : }
1271 [ - + ]: 10 : BUG_ON(i == nr);
1272 : : }
1273 : :
1274 [ + - ]: 4 : xfree(ch);
1275 : :
1276 : : return 0;
1277 : : }
1278 : :
1279 : 448 : static int dump_zombies(void)
1280 : : {
1281 : : struct pstree_item *item;
1282 : : int ret = -1;
1283 : 448 : int pidns = root_ns_mask & CLONE_NEWPID;
1284 : :
1285 [ + + ][ + - ]: 448 : if (pidns && set_proc_fd(get_service_fd(CR_PROC_FD_OFF)))
1286 : : return -1;
1287 : :
1288 : : /*
1289 : : * We dump zombies separately becase for pid-ns case
1290 : : * we'd have to resolve their pids w/o parasite via
1291 : : * target ns' proc.
1292 : : */
1293 : :
1294 [ + + ]: 1388 : for_each_pstree_item(item) {
1295 [ + + ]: 940 : if (item->state != TASK_DEAD)
1296 : 919 : continue;
1297 : :
1298 [ + + ]: 21 : if (item->pid.virt < 0) {
1299 [ + + ]: 15 : if (!pidns)
1300 : 11 : item->pid.virt = item->pid.real;
1301 [ - + ]: 4 : else if (root_item == item) {
1302 : 0 : pr_err("A root task is dead\n");
1303 : 0 : goto err;
1304 [ + - ]: 4 : } else if (fill_zombies_pids(item->parent))
1305 : : goto err;
1306 : : }
1307 : :
1308 : 21 : pr_info("Obtaining zombie stat ... ");
1309 [ + - ]: 21 : if (parse_pid_stat(item->pid.virt, &pps_buf) < 0)
1310 : : goto err;
1311 : :
1312 : 21 : item->sid = pps_buf.sid;
1313 : 21 : item->pgid = pps_buf.pgid;
1314 : :
1315 [ - + ]: 21 : BUG_ON(!list_empty(&item->children));
1316 [ + - ]: 21 : if (dump_one_zombie(item, &pps_buf) < 0)
1317 : : goto err;
1318 : : }
1319 : :
1320 : : ret = 0;
1321 : : err:
1322 [ + + ]: 448 : if (pidns)
1323 : 210 : close_proc();
1324 : :
1325 : 448 : return ret;
1326 : : }
1327 : :
1328 : 2824 : static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
1329 : : {
1330 : 2824 : pid_t pid = item->pid.real;
1331 : : struct vm_area_list vmas;
1332 : : struct parasite_ctl *parasite_ctl;
1333 : : int ret = -1;
1334 : : struct parasite_dump_misc misc;
1335 : :
1336 : : INIT_LIST_HEAD(&vmas.h);
1337 : 2824 : vmas.nr = 0;
1338 : :
1339 : 2824 : pr_info("========================================\n");
1340 : 2824 : pr_info("Pre-dumping task (pid: %d)\n", pid);
1341 : 2824 : pr_info("========================================\n");
1342 : :
1343 [ + + ]: 2824 : if (item->state == TASK_STOPPED) {
1344 : 12 : pr_warn("Stopped tasks are not supported\n");
1345 : 12 : return 0;
1346 : : }
1347 : :
1348 [ + + ]: 2812 : if (item->state == TASK_DEAD)
1349 : : return 0;
1350 : :
1351 : 2745 : ret = collect_mappings(pid, &vmas);
1352 [ - + ]: 2745 : if (ret) {
1353 : 0 : pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret);
1354 : 0 : goto err;
1355 : : }
1356 : :
1357 : : ret = -1;
1358 : 2745 : parasite_ctl = parasite_infect_seized(pid, item, &vmas, NULL, 0);
1359 [ - + ]: 2745 : if (!parasite_ctl) {
1360 : 0 : pr_err("Can't infect (pid: %d) with parasite\n", pid);
1361 : 0 : goto err_free;
1362 : : }
1363 : :
1364 : 2745 : ret = parasite_fixup_vdso(parasite_ctl, pid, &vmas);
1365 [ - + ]: 2745 : if (ret) {
1366 : 0 : pr_err("Can't fixup vdso VMAs (pid: %d)\n", pid);
1367 : 0 : goto err_cure;
1368 : : }
1369 : :
1370 : 2745 : ret = parasite_dump_misc_seized(parasite_ctl, &misc);
1371 [ - + ]: 2745 : if (ret) {
1372 : 0 : pr_err("Can't dump misc (pid: %d)\n", pid);
1373 : 0 : goto err_cure;
1374 : : }
1375 : :
1376 : 2745 : ret = predump_task_files(pid);
1377 [ - + ]: 2745 : if (ret) {
1378 : 0 : pr_err("Pre-dumping files failed (pid: %d)\n", pid);
1379 : 0 : goto err_cure;
1380 : : }
1381 : :
1382 : 2745 : parasite_ctl->pid.virt = item->pid.virt = misc.pid;
1383 : :
1384 : 2745 : ret = parasite_dump_pages_seized(parasite_ctl, &vmas, ¶site_ctl->mem_pp);
1385 [ + - ]: 2745 : if (ret)
1386 : : goto err_cure;
1387 : :
1388 [ - + ]: 2745 : if (parasite_cure_remote(parasite_ctl))
1389 : 0 : pr_err("Can't cure (pid: %d) from parasite\n", pid);
1390 : 2745 : list_add_tail(¶site_ctl->pre_list, ctls);
1391 : : err_free:
1392 : 2745 : free_mappings(&vmas);
1393 : : err:
1394 : 2745 : return ret;
1395 : :
1396 : : err_cure:
1397 [ # # ]: 0 : if (parasite_cure_seized(parasite_ctl))
1398 : 0 : pr_err("Can't cure (pid: %d) from parasite\n", pid);
1399 : : goto err_free;
1400 : : }
1401 : :
1402 : 940 : static int dump_one_task(struct pstree_item *item)
1403 : : {
1404 : 940 : pid_t pid = item->pid.real;
1405 : : struct vm_area_list vmas;
1406 : : struct parasite_ctl *parasite_ctl;
1407 : : int ret = -1;
1408 : : struct parasite_dump_misc misc;
1409 : 940 : struct cr_fdset *cr_fdset = NULL;
1410 : : struct parasite_drain_fd *dfds = NULL;
1411 : : struct proc_posix_timers_stat proc_args;
1412 : : struct proc_status_creds cr;
1413 : :
1414 : : INIT_LIST_HEAD(&vmas.h);
1415 : 940 : vmas.nr = 0;
1416 : :
1417 : 940 : pr_info("========================================\n");
1418 : 940 : pr_info("Dumping task (pid: %d)\n", pid);
1419 : 940 : pr_info("========================================\n");
1420 : :
1421 [ + + ]: 940 : if (item->state == TASK_DEAD)
1422 : : /*
1423 : : * zombies are dumped separately in dump_zombies()
1424 : : */
1425 : : return 0;
1426 : :
1427 : 919 : pr_info("Obtaining task stat ... ");
1428 : 919 : ret = parse_pid_stat(pid, &pps_buf);
1429 [ + - ]: 919 : if (ret < 0)
1430 : : goto err;
1431 : :
1432 : 919 : ret = parse_pid_status(pid, &cr);
1433 [ + - ]: 919 : if (ret)
1434 : : goto err;
1435 : :
1436 [ - + ]: 919 : if (!may_dump(&cr)) {
1437 : : ret = -1;
1438 : 0 : pr_err("Check uid (pid: %d) failed\n", pid);
1439 : 0 : goto err;
1440 : : }
1441 : :
1442 : 919 : ret = collect_mappings(pid, &vmas);
1443 [ - + ]: 919 : if (ret) {
1444 : 0 : pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret);
1445 : 0 : goto err;
1446 : : }
1447 : :
1448 [ - + ]: 919 : dfds = xmalloc(sizeof(*dfds));
1449 [ + - ]: 919 : if (!dfds)
1450 : : goto err;
1451 : :
1452 : 919 : ret = collect_fds(pid, dfds);
1453 [ - + ]: 919 : if (ret) {
1454 : 0 : pr_err("Collect fds (pid: %d) failed with %d\n", pid, ret);
1455 : 0 : goto err;
1456 : : }
1457 : :
1458 : 919 : ret = parse_posix_timers(pid, &proc_args);
1459 [ - + ]: 919 : if (ret < 0) {
1460 : 0 : pr_err("Can't read posix timers file (pid: %d)\n", pid);
1461 : 0 : goto err;
1462 : : }
1463 : :
1464 : : ret = -1;
1465 : 919 : parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds, proc_args.timer_n);
1466 [ - + ]: 919 : if (!parasite_ctl) {
1467 : 0 : pr_err("Can't infect (pid: %d) with parasite\n", pid);
1468 : 0 : goto err;
1469 : : }
1470 : :
1471 [ + + ][ + + ]: 919 : if (root_ns_mask & CLONE_NEWPID && root_item == item) {
1472 : : int pfd;
1473 : :
1474 : 210 : pfd = parasite_get_proc_fd_seized(parasite_ctl);
1475 [ - + ]: 210 : if (pfd < 0) {
1476 : 0 : pr_err("Can't get proc fd (pid: %d)\n", pid);
1477 : 0 : goto err_cure_fdset;
1478 : : }
1479 : :
1480 [ + - ]: 210 : if (install_service_fd(CR_PROC_FD_OFF, pfd) < 0)
1481 : : goto err_cure_fdset;
1482 : :
1483 : 210 : close(pfd);
1484 : : }
1485 : :
1486 : 919 : ret = parasite_fixup_vdso(parasite_ctl, pid, &vmas);
1487 [ - + ]: 919 : if (ret) {
1488 : 0 : pr_err("Can't fixup vdso VMAs (pid: %d)\n", pid);
1489 : 0 : goto err_cure_fdset;
1490 : : }
1491 : :
1492 : 919 : ret = parasite_dump_misc_seized(parasite_ctl, &misc);
1493 [ - + ]: 919 : if (ret) {
1494 : 0 : pr_err("Can't dump misc (pid: %d)\n", pid);
1495 : 0 : goto err_cure_fdset;
1496 : : }
1497 : :
1498 : 919 : parasite_ctl->pid.virt = item->pid.virt = misc.pid;
1499 : 919 : item->sid = misc.sid;
1500 : 919 : item->pgid = misc.pgid;
1501 : :
1502 : 919 : pr_info("sid=%d pgid=%d pid=%d\n",
1503 : : item->sid, item->pgid, item->pid.virt);
1504 : :
1505 [ - + ]: 919 : if (item->sid == 0) {
1506 : 0 : pr_err("A session leader of %d(%d) is outside of its pid namespace\n",
1507 : : item->pid.real, item->pid.virt);
1508 : : ret = -1;
1509 : 0 : goto err_cure;
1510 : : }
1511 : :
1512 : : ret = -1;
1513 : 919 : cr_fdset = cr_task_fdset_open(item->pid.virt, O_DUMP);
1514 [ + - ]: 919 : if (!cr_fdset)
1515 : : goto err_cure;
1516 : :
1517 : 919 : ret = dump_task_ids(item, cr_fdset);
1518 [ - + ]: 919 : if (ret) {
1519 : 0 : pr_err("Dump ids (pid: %d) failed with %d\n", pid, ret);
1520 : 0 : goto err_cure;
1521 : : }
1522 : :
1523 [ + + ]: 919 : if (!shared_fdtable(item)) {
1524 : 907 : ret = dump_task_files_seized(parasite_ctl, item, dfds);
1525 [ - + ]: 907 : if (ret) {
1526 : 0 : pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
1527 : 0 : goto err_cure;
1528 : : }
1529 : : }
1530 : :
1531 [ + - ]: 919 : if (opts.handle_file_locks) {
1532 : 919 : ret = dump_task_file_locks(parasite_ctl, cr_fdset, dfds);
1533 [ - + ]: 919 : if (ret) {
1534 : 0 : pr_err("Dump file locks (pid: %d) failed with %d\n",
1535 : : pid, ret);
1536 : 0 : goto err_cure;
1537 : : }
1538 : : }
1539 : :
1540 : 919 : ret = parasite_dump_pages_seized(parasite_ctl, &vmas, NULL);
1541 [ + - ]: 919 : if (ret)
1542 : : goto err_cure;
1543 : :
1544 : 919 : ret = parasite_dump_sigacts_seized(parasite_ctl, cr_fdset);
1545 [ - + ]: 919 : if (ret) {
1546 : 0 : pr_err("Can't dump sigactions (pid: %d) with parasite\n", pid);
1547 : 0 : goto err_cure;
1548 : : }
1549 : :
1550 : 919 : ret = parasite_dump_itimers_seized(parasite_ctl, item);
1551 [ - + ]: 919 : if (ret) {
1552 : 0 : pr_err("Can't dump itimers (pid: %d)\n", pid);
1553 : 0 : goto err_cure;
1554 : : }
1555 : :
1556 : 919 : ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, item);
1557 [ - + ]: 919 : if (ret) {
1558 : 0 : pr_err("Can't dump posix timers (pid: %d)\n", pid);
1559 : 0 : goto err_cure;
1560 : : }
1561 : :
1562 : 919 : ret = dump_task_core_all(item, &pps_buf, &misc, cr_fdset);
1563 [ - + ]: 919 : if (ret) {
1564 : 0 : pr_err("Dump core (pid: %d) failed with %d\n", pid, ret);
1565 : 0 : goto err_cure;
1566 : : }
1567 : :
1568 : 919 : ret = dump_task_threads(parasite_ctl, item);
1569 [ - + ]: 919 : if (ret) {
1570 : 0 : pr_err("Can't dump threads\n");
1571 : 0 : goto err_cure;
1572 : : }
1573 : :
1574 : 919 : ret = dump_task_creds(parasite_ctl, cr_fdset, &cr);
1575 [ - + ]: 919 : if (ret) {
1576 : 0 : pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
1577 : 0 : goto err;
1578 : : }
1579 : :
1580 : 919 : ret = parasite_cure_seized(parasite_ctl);
1581 [ - + ]: 919 : if (ret) {
1582 : 0 : pr_err("Can't cure (pid: %d) from parasite\n", pid);
1583 : 0 : goto err;
1584 : : }
1585 : :
1586 : 919 : ret = dump_task_mm(pid, &pps_buf, &misc, &vmas, cr_fdset);
1587 [ - + ]: 919 : if (ret) {
1588 : 0 : pr_err("Dump mappings (pid: %d) failed with %d\n", pid, ret);
1589 : 0 : goto err;
1590 : : }
1591 : :
1592 : 919 : ret = dump_task_fs(pid, &misc, cr_fdset);
1593 [ - + ]: 919 : if (ret) {
1594 : 0 : pr_err("Dump fs (pid: %d) failed with %d\n", pid, ret);
1595 : 0 : goto err;
1596 : : }
1597 : :
1598 : 919 : ret = dump_task_signals(pid, item, cr_fdset);
1599 [ - + ]: 919 : if (ret) {
1600 : 0 : pr_err("Dump %d signals failed %d\n", pid, ret);
1601 : 0 : goto err;
1602 : : }
1603 : :
1604 : 919 : close_cr_fdset(&cr_fdset);
1605 : : err:
1606 : 919 : close_pid_proc();
1607 : 919 : free_mappings(&vmas);
1608 [ + - ]: 919 : xfree(dfds);
1609 : 919 : return ret;
1610 : :
1611 : : err_cure:
1612 : 0 : close_cr_fdset(&cr_fdset);
1613 : : err_cure_fdset:
1614 : 0 : parasite_cure_seized(parasite_ctl);
1615 : 0 : goto err;
1616 : : }
1617 : :
1618 : 1344 : int cr_pre_dump_tasks(pid_t pid)
1619 : : {
1620 : : struct pstree_item *item;
1621 : : int ret = -1;
1622 : 1344 : LIST_HEAD(ctls);
1623 : : struct parasite_ctl *ctl, *n;
1624 : :
1625 [ - + ]: 1344 : if (!opts.track_mem) {
1626 : 0 : pr_info("Enforcing memory tracking for pre-dump.\n");
1627 : 0 : opts.track_mem = true;
1628 : : }
1629 : :
1630 [ - + ]: 1344 : if (opts.final_state == TASK_DEAD) {
1631 : 0 : pr_info("Enforcing tasks run after pre-dump.\n");
1632 : 0 : opts.final_state = TASK_ALIVE;
1633 : : }
1634 : :
1635 [ + - ]: 1344 : if (init_stats(DUMP_STATS))
1636 : : goto err;
1637 : :
1638 [ + - ]: 1344 : if (kerndat_init())
1639 : : goto err;
1640 : :
1641 [ + - ]: 1344 : if (irmap_load_cache())
1642 : : goto err;
1643 : :
1644 [ + - ]: 1344 : if (cpu_init())
1645 : : goto err;
1646 : :
1647 [ + - ]: 1344 : if (vdso_init())
1648 : : goto err;
1649 : :
1650 [ + - ]: 1344 : if (connect_to_page_server())
1651 : : goto err;
1652 : :
1653 [ + - ]: 1344 : if (collect_pstree(pid))
1654 : : goto err;
1655 : :
1656 [ + - ]: 1344 : if (gen_predump_ns_mask())
1657 : : goto err;
1658 : :
1659 [ + - ]: 1344 : if (collect_mnt_namespaces() < 0)
1660 : : goto err;
1661 : :
1662 [ + + ]: 4168 : for_each_pstree_item(item)
1663 [ + - ]: 2824 : if (pre_dump_one_task(item, &ctls))
1664 : : goto err;
1665 : :
1666 : : ret = 0;
1667 : : err:
1668 [ + - ]: 1344 : pstree_switch_state(root_item,
1669 : : ret ? TASK_ALIVE : opts.final_state);
1670 : 1344 : free_pstree(root_item);
1671 : :
1672 : 1344 : timing_stop(TIME_FROZEN);
1673 : :
1674 : 1344 : pr_info("Pre-dumping tasks' memory\n");
1675 [ + + ]: 4089 : list_for_each_entry_safe(ctl, n, &ctls, pre_list) {
1676 : : struct page_xfer xfer;
1677 : :
1678 : 2745 : pr_info("\tPre-dumping %d\n", ctl->pid.virt);
1679 : 2745 : timing_start(TIME_MEMWRITE);
1680 : 2745 : ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, ctl->pid.virt);
1681 [ + - ]: 2745 : if (ret < 0)
1682 : : break;
1683 : :
1684 : 2745 : ret = page_xfer_dump_pages(&xfer, ctl->mem_pp, 0);
1685 : :
1686 : 2745 : xfer.close(&xfer);
1687 : :
1688 [ + - ]: 2745 : if (ret)
1689 : : break;
1690 : :
1691 : 2745 : timing_stop(TIME_MEMWRITE);
1692 : :
1693 : 2745 : destroy_page_pipe(ctl->mem_pp);
1694 : : list_del(&ctl->pre_list);
1695 : 2745 : parasite_cure_local(ctl);
1696 : : }
1697 : :
1698 [ - + ]: 1344 : if (irmap_predump_run())
1699 : : ret = -1;
1700 : :
1701 [ - + ]: 1344 : if (disconnect_from_page_server())
1702 : : ret = -1;
1703 : :
1704 [ - + ]: 1344 : if (ret)
1705 : 0 : pr_err("Pre-dumping FAILED.\n");
1706 : : else {
1707 : 1344 : write_stats(DUMP_STATS);
1708 : 1344 : pr_info("Pre-dumping finished successfully\n");
1709 : : }
1710 : :
1711 : 1344 : return ret;
1712 : : }
1713 : :
1714 : 448 : int cr_dump_tasks(pid_t pid)
1715 : : {
1716 : : struct pstree_item *item;
1717 : : int post_dump_ret = 0;
1718 : : int ret = -1;
1719 : :
1720 : 448 : pr_info("========================================\n");
1721 : 448 : pr_info("Dumping processes (pid: %d)\n", pid);
1722 : 448 : pr_info("========================================\n");
1723 : :
1724 [ + - ]: 448 : if (init_stats(DUMP_STATS))
1725 : : goto err;
1726 : :
1727 [ + - ]: 448 : if (cr_plugin_init())
1728 : : goto err;
1729 : :
1730 [ + - ]: 448 : if (kerndat_init())
1731 : : goto err;
1732 : :
1733 [ + - ]: 448 : if (irmap_load_cache())
1734 : : goto err;
1735 : :
1736 [ + - ]: 448 : if (cpu_init())
1737 : : goto err;
1738 : :
1739 [ + - ]: 448 : if (vdso_init())
1740 : : goto err;
1741 : :
1742 [ + - ]: 448 : if (write_img_inventory())
1743 : : goto err;
1744 : :
1745 [ + - ]: 448 : if (connect_to_page_server())
1746 : : goto err;
1747 : :
1748 : : /*
1749 : : * The collect_pstree will also stop (PTRACE_SEIZE) the tasks
1750 : : * thus ensuring that they don't modify anything we collect
1751 : : * afterwards.
1752 : : */
1753 : :
1754 [ + - ]: 448 : if (collect_pstree(pid))
1755 : : goto err;
1756 : :
1757 [ + - ]: 448 : if (collect_pstree_ids())
1758 : : goto err;
1759 : :
1760 [ + - ]: 448 : if (network_lock())
1761 : : goto err;
1762 : :
1763 [ + - ]: 448 : if (collect_file_locks())
1764 : : goto err;
1765 : :
1766 [ + - ]: 448 : if (dump_mnt_namespaces() < 0)
1767 : : goto err;
1768 : :
1769 [ + - ]: 448 : if (collect_sockets(pid))
1770 : : goto err;
1771 : :
1772 : 448 : glob_fdset = cr_glob_fdset_open(O_DUMP);
1773 [ + - ]: 448 : if (!glob_fdset)
1774 : : goto err;
1775 : :
1776 [ + + ]: 1388 : for_each_pstree_item(item) {
1777 [ + - ]: 940 : if (dump_one_task(item))
1778 : : goto err;
1779 : : }
1780 : :
1781 [ + - ]: 448 : if (dump_verify_tty_sids())
1782 : : goto err;
1783 : :
1784 [ + - ]: 448 : if (dump_zombies())
1785 : : goto err;
1786 : :
1787 [ + - ]: 448 : if (dump_pstree(root_item))
1788 : : goto err;
1789 : :
1790 [ + + ]: 448 : if (root_ns_mask)
1791 [ + - ]: 226 : if (dump_namespaces(root_item, root_ns_mask) < 0)
1792 : : goto err;
1793 : :
1794 : 448 : ret = cr_dump_shmem();
1795 [ + - ]: 448 : if (ret)
1796 : : goto err;
1797 : :
1798 : 448 : ret = fix_external_unix_sockets();
1799 [ + - ]: 448 : if (ret)
1800 : : goto err;
1801 : :
1802 : 448 : ret = tty_verify_active_pairs();
1803 [ + - ]: 448 : if (ret)
1804 : : goto err;
1805 : :
1806 : 448 : fd_id_show_tree();
1807 : : err:
1808 [ - + ]: 448 : if (disconnect_from_page_server())
1809 : : ret = -1;
1810 : :
1811 : 448 : close_cr_fdset(&glob_fdset);
1812 : :
1813 : 448 : cr_plugin_fini();
1814 : :
1815 [ + - ]: 448 : if (!ret) {
1816 : : /*
1817 : : * It might be a migration case, where we're asked
1818 : : * to dump everything, then some script transfer
1819 : : * image on a new node and we're supposed to kill
1820 : : * dumpee because it continue running somewhere
1821 : : * else.
1822 : : *
1823 : : * Thus ask user via script if we're to break
1824 : : * checkpoint.
1825 : : */
1826 : 448 : post_dump_ret = run_scripts("post-dump");
1827 [ - + ]: 448 : if (post_dump_ret) {
1828 : 0 : post_dump_ret = WEXITSTATUS(post_dump_ret);
1829 : 0 : pr_info("Post dump script passed with %d\n", post_dump_ret);
1830 : : }
1831 : : }
1832 : :
1833 : : /*
1834 : : * Dump is complete at this stage. To choose what
1835 : : * to do next we need to consider the following
1836 : : * scenarios
1837 : : *
1838 : : * - error happened during checkpoint: just clean up
1839 : : * everything and continue execution of the dumpee;
1840 : : *
1841 : : * - dump successed but post-dump script returned
1842 : : * some ret code: same as in previous scenario --
1843 : : * just clean up everything and continue execution,
1844 : : * we will return script ret code back to criu caller
1845 : : * and it's up to a caller what to do with running instance
1846 : : * of the dumpee -- either kill it, or continue running;
1847 : : *
1848 : : * - dump successed but -R option passed, pointing that
1849 : : * we're asked to continue execution of the dumpee. It's
1850 : : * assumed that a user will use post-dump script to keep
1851 : : * consistency of the FS and other resources, we simply
1852 : : * start rollback procedure and cleanup everyhting.
1853 : : */
1854 [ + - ][ - + ]: 448 : if (ret || post_dump_ret || opts.final_state == TASK_ALIVE) {
1855 : 0 : network_unlock();
1856 : 0 : delete_link_remaps();
1857 : : }
1858 [ + - ]: 448 : pstree_switch_state(root_item,
1859 : : (ret || post_dump_ret) ?
1860 : : TASK_ALIVE : opts.final_state);
1861 : 448 : timing_stop(TIME_FROZEN);
1862 : 448 : free_pstree(root_item);
1863 : 448 : free_file_locks();
1864 : 448 : free_link_remaps();
1865 : :
1866 : 448 : close_service_fd(CR_PROC_FD_OFF);
1867 : :
1868 [ - + ]: 448 : if (ret) {
1869 : 0 : kill_inventory();
1870 : 0 : pr_err("Dumping FAILED.\n");
1871 : : } else {
1872 : 448 : write_stats(DUMP_STATS);
1873 : 448 : pr_info("Dumping finished successfully\n");
1874 : : }
1875 : :
1876 [ + - ]: 448 : return post_dump_ret ? : (ret != 0);
1877 : : }
|