@@ -618,79 +618,63 @@ int device_get_devlink_priority(sd_device *device, int *ret) {
618618 return 0 ;
619619}
620620
621- static int device_shallow_clone (sd_device * device , sd_device * * ret ) {
621+ int device_clone_with_db (sd_device * device , sd_device * * ret ) {
622622 _cleanup_ (sd_device_unrefp ) sd_device * dest = NULL ;
623- const char * val = NULL ;
623+ const char * key , * val ;
624624 int r ;
625625
626626 assert (device );
627627 assert (ret );
628628
629+ /* The device may be already removed. Let's copy minimal set of information that was obtained through
630+ * netlink socket. */
631+
629632 r = device_new_aux (& dest );
630633 if (r < 0 )
631634 return r ;
632635
636+ /* Seal device to prevent reading the uevent file, as the device may have been already removed. */
637+ dest -> sealed = true;
638+
639+ /* Copy syspath, then also devname, sysname or sysnum can be obtained. */
633640 r = device_set_syspath (dest , device -> syspath , false);
634641 if (r < 0 )
635642 return r ;
636643
637- (void ) sd_device_get_subsystem (device , & val );
638- r = device_set_subsystem (dest , val );
639- if (r < 0 )
640- return r ;
641- if (streq_ptr (val , "drivers" )) {
642- r = free_and_strdup (& dest -> driver_subsystem , device -> driver_subsystem );
644+ /* Copy other information stored in database. Here, do not use FOREACH_DEVICE_PROPERTY() and
645+ * sd_device_get_property_value(), as they calls device_properties_prepare() ->
646+ * device_read_uevent_file(), but as commented in the above, the device may be already removed and
647+ * reading uevent file may fail. */
648+ ORDERED_HASHMAP_FOREACH_KEY (val , key , device -> properties ) {
649+ if (streq (key , "MINOR" ))
650+ continue ;
651+
652+ if (streq (key , "MAJOR" )) {
653+ const char * minor = NULL ;
654+
655+ minor = ordered_hashmap_get (device -> properties , "MINOR" );
656+ r = device_set_devnum (dest , val , minor );
657+ } else
658+ r = device_amend (dest , key , val );
643659 if (r < 0 )
644660 return r ;
645- }
646-
647- /* The device may be already removed. Let's copy minimal set of information to make
648- * device_get_device_id() work without uevent file. */
649661
650- if (sd_device_get_property_value (device , "IFINDEX" , & val ) >= 0 ) {
651- r = device_set_ifindex (dest , val );
652- if (r < 0 )
653- return r ;
654- }
655-
656- if (sd_device_get_property_value (device , "MAJOR" , & val ) >= 0 ) {
657- const char * minor = NULL ;
658-
659- (void ) sd_device_get_property_value (device , "MINOR" , & minor );
660- r = device_set_devnum (dest , val , minor );
661- if (r < 0 )
662- return r ;
662+ if (streq (key , "SUBSYSTEM" ) && streq (val , "drivers" )) {
663+ r = free_and_strdup (& dest -> driver_subsystem , device -> driver_subsystem );
664+ if (r < 0 )
665+ return r ;
666+ }
663667 }
664668
665- r = device_read_uevent_file (dest );
669+ /* Finally, read the udev database. */
670+ r = device_read_db_internal (dest , /* force = */ true);
666671 if (r < 0 )
667672 return r ;
668673
669674 * ret = TAKE_PTR (dest );
670675 return 0 ;
671676}
672677
673- int device_clone_with_db (sd_device * device , sd_device * * ret ) {
674- _cleanup_ (sd_device_unrefp ) sd_device * dest = NULL ;
675- int r ;
676-
677- assert (device );
678- assert (ret );
679-
680- r = device_shallow_clone (device , & dest );
681- if (r < 0 )
682- return r ;
683-
684- r = device_read_db (dest );
685- if (r < 0 )
686- return r ;
687-
688- dest -> sealed = true;
689-
690- * ret = TAKE_PTR (dest );
691- return 0 ;
692- }
693-
694678void device_cleanup_tags (sd_device * device ) {
695679 assert (device );
696680
0 commit comments