UML 파티션 마운트 2

16411 단어 UML

1. 프로세스


프로세스는 다음과 같습니다.
virtblk_probe(struct virtio_device *vdev)
             ------>set_disk_ro(vblk->disk, 1)
                        ------->set_disk_ro_uevent(disk, flag)
                                      ----->dev_uevent()
                                                ------->part_uevent()

2. 코드


2.1 virtblk_probe


파일drivers/block/virtioblk.c:
620 static int virtblk_probe(struct virtio_device *vdev)                            
621 {                                                                               
622         struct virtio_blk *vblk;                                                
623         struct request_queue *q;                                                
624         int err, index;                                                         
625                                                                                 
626         u64 cap;                                                                
627         u32 v, blk_size, sg_elems, opt_io_size;                                 
628         u16 min_io_size;                                                        
629         u8 physical_block_exp, alignment_offset;                                
630                                                                                 
631         if (!vdev->config->get) {                                               
632                 dev_err(&vdev->dev, "%s failure: config access disabled
", 633 __func__); 634 return -EINVAL; 635 } .......... 717 /* configure queue flush support */ 718 virtblk_update_cache_mode(vdev); 719 720 /* If disk is read-only in the host, the guest should obey */ 721 if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) 722 set_disk_ro(vblk->disk, 1); ..............

722 줄에서 set 호출disk_ro 함수 setdisk_ro(vblk->disk, 1).

2.2 set_disk_ro


파일 Block/genhd.c:
1474 void set_disk_ro(struct gendisk *disk, int flag)                                                                                                                                                       
1475 {                                                                               
1476         struct disk_part_iter piter;                                            
1477         struct hd_struct *part;                                                 
1478                                                                                 
1479         if (disk->part0.policy != flag) {                                       
1480                 set_disk_ro_uevent(disk, flag);                                 
1481                 disk->part0.policy = flag;                                      
1482         }                                                                       
1483                                                                                 
1484         disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);               
1485         while ((part = disk_part_iter_next(&piter)))                            
1486                 part->policy = flag;                                            
1487         disk_part_iter_exit(&piter);                                            
1488 }    

1480 줄에서 함수 set 호출disk_ro_uevent(disk, flag).

2.3 set_disk_ro_uevent


파일 Block/genhd.c 중.
1457 static void set_disk_ro_uevent(struct gendisk *gd, int ro)                                                                                                                                             
1458 {                                                                               
1459         char event[] = "DISK_RO=1";                                             
1460         char *envp[] = { event, NULL };                                         
1461                                                                                 
1462         if (!ro)                                                                
1463                 event[8] = '0';                                                 
1464         kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);          
1465 }   

1464 줄에서 함수 호출 kobjectuevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp).

2.4 kobject_uevent_env

327 int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,        
328                        char *envp_ext[])                                        
329 {                                                                               
330         struct kobj_uevent_env *env;                                                                                                                                                                    
331         const char *action_string = kobject_actions[action];  
............
409         /* default keys */                                                      
410         retval = add_uevent_var(env, "ACTION=%s", action_string);               
411         if (retval)                                                             
412                 goto exit;                                                      
413         retval = add_uevent_var(env, "DEVPATH=%s", devpath);                    
414         if (retval)                                                             
415                 goto exit;                                                      
416         retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);                
417         if (retval)                                                             
418                 goto exit;  

그러면 env->envp의 내용은 다음과 같다.
[    1.332974] tom F=kobject_uevent_env L=452 env1->envp[0]=ACTION=add
[    1.333570] tom F=kobject_uevent_env L=452 env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2
[    1.334239] tom F=kobject_uevent_env L=452 env1->envp[2]=SUBSYSTEM=block
420         /* keys passed in from the caller */                                    
421         if (envp_ext) {                                                         
422                 for (i = 0; envp_ext[i]; i++) {                                 
423                         retval = add_uevent_var(env, "%s", envp_ext[i]);        
424                         if (retval)                                             
425                                 goto exit;                                      
426                 }                                                               
427         }  

그러면 env->envp[3]의 내용은 다음과 같다.
[    1.346066] tom F=kobject_uevent_env L=462 env1->envp[3]=SYNTH_UUID=0
429         /* let the kset specific function add its stuff */                      
430         if (uevent_ops && uevent_ops->uevent) {                                 
431                 retval = uevent_ops->uevent(kset, kobj, env);                   
432                 if (retval) {                                                   
433                         pr_debug("kobject: '%s' (%p): %s: uevent() returned "   
434                                  "%d
", kobject_name(kobj), kobj, 435 __func__, retval); 436 goto exit; 437 } 438 }

431줄에서 uevent 호출ops->uevent(kset, kobj, env);

2.5 dev_uevent


drivers/base/core.c중 devuevent 함수:
 875 static int dev_uevent(struct kset *kset, struct kobject *kobj,                  
 876                       struct kobj_uevent_env *env)                              
 877 {                                                                               
 878         struct device *dev = kobj_to_dev(kobj);                                 
 879         int retval = 0;                                                         
 880                                                                                 
 881         /* add device node properties if present */                             
 882         if (MAJOR(dev->devt)) {                                                 
 883                 const char *tmp;                                                
 884                 const char *name;                                               
 885                 umode_t mode = 0;                                               
 886                 kuid_t uid = GLOBAL_ROOT_UID;                                   
 887                 kgid_t gid = GLOBAL_ROOT_GID;                                   
 888                                                                                 
 889                 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));              
 890                 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));              
 891                 name = device_get_devnode(dev, &mode, &uid, &gid, &tmp);        
 892                 if (name) {                                                     
 893                         add_uevent_var(env, "DEVNAME=%s", name);                
 894                         if (mode)                                               
 895                                 add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
 896                         if (!uid_eq(uid, GLOBAL_ROOT_UID))                      
 897                                 add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid));
 898                         if (!gid_eq(gid, GLOBAL_ROOT_GID))                      
 899                                 add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid));
 900                         kfree(tmp);                                             
 901                 }                                                               
 902         }   
  903                                                                                 
 904         if (dev->type && dev->type->name)                                       
 905                 add_uevent_var(env, "DEVTYPE=%s", dev->type->name);             
 906                                                                                 
 907         if (dev->driver)                                                        
 908                 add_uevent_var(env, "DRIVER=%s", dev->driver->name);            
 909                                                                                 
 910         /* Add common DT information about the device */                        
 911         of_device_uevent(dev, env);                                             
 912                                                                                 
 913         /* have the bus specific function add its stuff */                      
 914         if (dev->bus && dev->bus->uevent) {                                     
 915                 retval = dev->bus->uevent(dev, env);                            
 916                 if (retval)                                                     
 917                         pr_debug("device: '%s': %s: bus uevent() returned %d
", 918 dev_name(dev), __func__, retval); 919 } 920 921 /* have the class specific function add its stuff */ 922 if (dev->class && dev->class->dev_uevent) { 923 retval = dev->class->dev_uevent(dev, env); 924 if (retval) 925 pr_debug("device: '%s': %s: class uevent() " 926 "returned %d
", dev_name(dev), 927 __func__, retval); 928 } 929 930 /* have the device type specific function add its stuff */ 931 if (dev->type && dev->type->uevent) { 932 retval = dev->type->uevent(dev, env); 933 if (retval) 934 pr_debug("device: '%s': %s: dev_type uevent() " 935 "returned %d
", dev_name(dev), 936 __func__, retval); 937 } 938 939 return retval; 940 }

908 행까지 실행
[    1.346815] tom F=kobject_uevent_env L=462 env1->envp[4]=MAJOR=253
[    1.347566] tom F=kobject_uevent_env L=462 env1->envp[5]=MINOR=2
[    1.348232] tom F=kobject_uevent_env L=462 env1->envp[6]=DEVNAME=vda2
[    1.348963] tom F=kobject_uevent_env L=462 env1->envp[7]=DEVTYPE=partition

932행에서 retval = dev->type->uevent(dev,env)를 실행합니다.

2.5 part_uevent


파일 Block/partition-generic.c의 partuevent 함수:
231 static int part_uevent(struct device *dev, struct kobj_uevent_env *env)         
232 {                                                                               
233         struct hd_struct *part = dev_to_part(dev);                              
234                                                                                 
235         add_uevent_var(env, "PARTN=%u", part->partno);                          
236         if (part->info && part->info->volname[0])                               
237                 add_uevent_var(env, "PARTNAME=%s", part->info->volname);                                                                                                                                
238         return 0;                                                               
239 }                                                                               

함수 env->envp 수조를 실행했습니다.
[    1.349706] tom F=kobject_uevent_env L=462 env1->envp[8]=PARTN=2
[    1.350547] tom F=kobject_uevent_env L=462 env1->envp[9]=PARTNAME=super

3. 결론


sda1의 env->envp에 대한 문자열 값입니다.PARTNAME=super는 part->info->volname에서 값을 부여하는 것을 알 수 있습니다.다음 섹션은 part->info->volname의 값을 어떻게 부여하는지 보십시오.

좋은 웹페이지 즐겨찾기