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