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/virtio_blk.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\n",     
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函数 set_disk_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行调用函数kobject_uevent_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\n", 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中dev_uevent函数:

 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\n",
 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\n", 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\n", 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中的part_uevent函数:

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怎么赋值。

你可能感兴趣的:(UML)