@@ -329,7 +329,8 @@ uint32_t make_gen_id(uint32_t st_dev, uint32_t st_ino, uint64_t pos)
329
329
return st_dev ^ st_ino ^ pos_hi ^ pos_low ;
330
330
}
331
331
332
- int do_dump_gen_file (struct fd_parms * p , int lfd , const struct fdtype_ops * ops , FdinfoEntry * e )
332
+ int do_dump_gen_file (struct fd_parms * p , int lfd ,
333
+ const struct fdtype_ops * ops , FdinfoEntry * e , bool force )
333
334
{
334
335
int ret = -1 ;
335
336
@@ -339,7 +340,7 @@ int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops,
339
340
e -> flags = p -> fd_flags ;
340
341
341
342
ret = fd_id_generate (p -> pid , e , p );
342
- if (ret == 1 ) /* new ID generated */
343
+ if (ret == 1 || force ) /* new ID generated */
343
344
ret = ops -> dump (lfd , e -> id , p );
344
345
else
345
346
/* Remove locks generated by the fd before going to the next */
@@ -484,19 +485,19 @@ static int dump_chrdev(struct fd_parms *p, int lfd, FdinfoEntry *e)
484
485
}
485
486
486
487
sprintf (more , "%d:%d" , maj , minor (p -> stat .st_rdev ));
487
- err = dump_unsupp_fd (p , lfd , "chr" , more , e );
488
+ err = dump_unsupp_fd (p , lfd , "chr" , more , e , false );
488
489
p -> link = link_old ;
489
490
return err ;
490
491
}
491
492
}
492
493
493
- err = do_dump_gen_file (p , lfd , ops , e );
494
+ err = do_dump_gen_file (p , lfd , ops , e , false );
494
495
p -> link = link_old ;
495
496
return err ;
496
497
}
497
498
498
499
static int dump_one_file (struct pid * pid , int fd , int lfd , struct fd_opts * opts , struct parasite_ctl * ctl ,
499
- FdinfoEntry * e , struct parasite_drain_fd * dfds )
500
+ FdinfoEntry * e , struct parasite_drain_fd * dfds , bool force )
500
501
{
501
502
struct fd_parms p = FD_PARMS_INIT ;
502
503
const struct fdtype_ops * ops ;
@@ -552,14 +553,14 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
552
553
ops = & bpfmap_dump_ops ;
553
554
#endif
554
555
else
555
- return dump_unsupp_fd (& p , lfd , "anon" , link , e );
556
+ return dump_unsupp_fd (& p , lfd , "anon" , link , e , force );
556
557
557
- return do_dump_gen_file (& p , lfd , ops , e );
558
+ return do_dump_gen_file (& p , lfd , ops , e , force );
558
559
}
559
560
560
561
if (p .fs_type == PID_FS_MAGIC ) {
561
562
ops = & pidfd_dump_ops ;
562
- return do_dump_gen_file (& p , lfd , ops , e );
563
+ return do_dump_gen_file (& p , lfd , ops , e , force );
563
564
}
564
565
565
566
if (S_ISREG (p .stat .st_mode ) || S_ISDIR (p .stat .st_mode ) || S_ISLNK (p .stat .st_mode )) {
@@ -576,9 +577,9 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
576
577
else if (check_ns_proc (& link ))
577
578
ops = & nsfile_dump_ops ;
578
579
else
579
- return dump_unsupp_fd (& p , lfd , "reg" , link .name + 1 , e );
580
+ return dump_unsupp_fd (& p , lfd , "reg" , link .name + 1 , e , force );
580
581
581
- return do_dump_gen_file (& p , lfd , ops , e );
582
+ return do_dump_gen_file (& p , lfd , ops , e , force );
582
583
}
583
584
584
585
if (S_ISFIFO (p .stat .st_mode )) {
@@ -587,7 +588,7 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
587
588
else
588
589
ops = & fifo_dump_ops ;
589
590
590
- return do_dump_gen_file (& p , lfd , ops , e );
591
+ return do_dump_gen_file (& p , lfd , ops , e , force );
591
592
}
592
593
593
594
/*
@@ -598,7 +599,7 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
598
599
if (fill_fdlink (lfd , & p , & link ))
599
600
memzero (& link , sizeof (link ));
600
601
601
- return dump_unsupp_fd (& p , lfd , "unknown" , link .name + 1 , e );
602
+ return dump_unsupp_fd (& p , lfd , "unknown" , link .name + 1 , e , force );
602
603
}
603
604
604
605
int dump_my_file (int lfd , u32 * id , int * type )
@@ -610,7 +611,7 @@ int dump_my_file(int lfd, u32 *id, int *type)
610
611
me .real = getpid ();
611
612
me .ns [0 ].virt = -1 ; /* FIXME */
612
613
613
- if (dump_one_file (& me , lfd , lfd , & fdo , NULL , & e , NULL ))
614
+ if (dump_one_file (& me , lfd , lfd , & fdo , NULL , & e , NULL , false ))
614
615
return -1 ;
615
616
616
617
* id = e .id ;
@@ -625,6 +626,8 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
625
626
struct fd_opts * opts = NULL ;
626
627
int i , ret = -1 ;
627
628
int off , nr_fds = min ((int )PARASITE_MAX_FDS , dfds -> nr_fds );
629
+ int * retry_indices = NULL ;
630
+ int retry_count = 0 ;
628
631
629
632
pr_info ("\n" );
630
633
pr_info ("Dumping opened files (pid: %d)\n" , item -> pid -> real );
@@ -642,6 +645,10 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
642
645
if (!img )
643
646
goto err ;
644
647
648
+ retry_indices = xmalloc (dfds -> nr_fds * sizeof (int )); /* Allocate memory for retry indices*/
649
+ if (!retry_indices )
650
+ goto err ;
651
+
645
652
ret = 0 ; /* Don't fail if nr_fds == 0 */
646
653
for (off = 0 ; ret == 0 && off < dfds -> nr_fds ; off += nr_fds ) {
647
654
if (nr_fds + off > dfds -> nr_fds )
@@ -654,9 +661,32 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
654
661
for (i = 0 ; i < nr_fds ; i ++ ) {
655
662
FdinfoEntry e = FDINFO_ENTRY__INIT ;
656
663
657
- ret = dump_one_file (item -> pid , dfds -> fds [i + off ], lfds [i ], opts + i , ctl , & e , dfds );
664
+ ret = dump_one_file (item -> pid , dfds -> fds [i + off ], lfds [i ], opts + i , ctl , & e , dfds , false);
665
+ if (ret == - EAGAIN ) {
666
+ retry_indices [retry_count ++ ] = i ;
667
+ ret = 0 ; //* Reset ret to continue the loop */
668
+ continue ;
669
+ } else if (ret )
670
+ break ;
671
+
672
+ ret = pb_write_one (img , & e , PB_FDINFO );
658
673
if (ret )
659
674
break ;
675
+ }
676
+ /* Dmabuf FDs cannot be dumped unless we have first dumped the device file that exported them.
677
+ * For that reason, retry dump of files that failed to dump the first time. Specifying force
678
+ * here makes the dump go through even if a file id has already been assigned.
679
+ */
680
+ for (i = 0 ; i < retry_count ; i ++ ) {
681
+ int idx = retry_indices [i ];
682
+ FdinfoEntry e = FDINFO_ENTRY__INIT ;
683
+
684
+ ret = dump_one_file (item -> pid , dfds -> fds [idx + off ], lfds [idx ],
685
+ opts + idx , ctl , & e , dfds , true);
686
+ if (ret ) {
687
+ pr_err ("Retry failed for fd index %d\n" , idx );
688
+ break ;
689
+ }
660
690
661
691
ret = pb_write_one (img , & e , PB_FDINFO );
662
692
if (ret )
@@ -673,6 +703,8 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
673
703
close_image (img );
674
704
xfree (opts );
675
705
xfree (lfds );
706
+ xfree (retry_indices );
707
+
676
708
return ret ;
677
709
}
678
710
0 commit comments