UML之分区挂载

1.概述

UML中的分区暂时无法挂载。

2. 挂载流程

函数调用流程:

InitRequiredDevices()--->uevent_callback()--->UeventCallback()

在init/first_stage_mount.cpp中

415 ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) {          
416     // Ignores everything that is not a block device.                           
417     if (uevent.subsystem != "block") {                                          
418         return ListenerAction::kContinue;                                       
419     }                                                                           
420                                                                                 
421     if (!uevent.partition_name.empty()) {                                       
422         if ( (uevent.partition_name == "super") || (uevent.partition_name == "vbmeta")) {
423             LOG(INFO) << "tom action=" << uevent.action<<" path="<<uevent.path<<" subsystem="<<uevent.subsystem;
424             LOG(INFO) << "tom firmware=" << uevent.firmware<<" p_name="<<uevent.partition_name;
425             LOG(INFO) << "tom device_name=" << uevent.device_name<<" modifies="<<uevent.modalias;
426             LOG(INFO) << "tom partition_num=" << uevent.partition_num<<" major="<<uevent.major<<" minor="<<uevent.minor;
427         }                                                                       
428         return HandleBlockDevice(uevent.partition_name, uevent);                
429     } else {                                                                    
430         size_t base_idx = uevent.path.rfind('/');                               
431         if (base_idx != std::string::npos) {                                    
432             return HandleBlockDevice(uevent.path.substr(base_idx + 1), uevent); 
433         }                                                                                                                                                                                                      
434     }                                                                           
435     // Not found a partition or find an unneeded partition, continue to find others.
436     return ListenerAction::kContinue;                                           
437 }   

打印信息:

[    1.370375] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2 subsystem=block
[    1.372134] init: tom firmware= p_name=super
[    1.372457] init: tom device_name=vda2 modifies=
[    1.372838] init: tom partition_num=2 major=253 minor=2
[    1.373596] tom F=kobject_uevent_env subsystem=block
[    1.373597] tom F=kobject_uevent_env devpath=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1
[    1.374069] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1 subsystem=block
[    1.375689] init: tom firmware= p_name=vbmeta
[    1.376047] init: tom device_name=vda1 modifies=
[    1.376420] init: tom partition_num=1 major=253 minor=1

分析,在uevent事件中,接受到partion_name的super和vbmeta时候,就加载system分区。

启动信息如下:

[    0.000000] Command line: qemu=1 no_timer_check androidboot.hardware=ranchu androidboot.serialno=EMULATOR29X0X1X0 clocksource=pit no-kvmclock console=ttyS0,38400 android.qemud=1 android.checkjni=1 qemu.gles=1 qemu.settings.system.screen_off_timeout=2147483647 qemu.encrypt=1 qemu.opengles.version=196609 qemu.uirenderer=skiagl cma=262M@0-4G qemu.wifi=1 mac80211_hwsim.channels=2 loop.max_part=7 androidboot.vbmeta.size=4352 androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.digest=de63a9b7482880698b68084b079c251fb974d1c7f06d588865f1ddd5a866008c androidboot.boot_devices=pci0000:00/0000:00:03.0 ramoops.mem_address=0xff018000 ramoops.mem_size=0x10000 memmap=0x10000$0xff018000 qemu.dalvik.vm.heapsize=192m mac80211_hwsim.mac_prefix=5554

可以看出b

3. 问题

1)这个uevent消息是谁发出的?
2)init进程接受的uevent消息中partition_name是kernel的uevent发送?
3) kernel的uevent根据什么发送?

4. uevent的partition_name

在uevent_listener.cpp中,通过ReadUevent函数,给msg赋值,调用 ParseEvent(msg, uevent)。

 98 bool UeventListener::ReadUevent(Uevent* uevent) const {                         
 99     char msg[UEVENT_MSG_LEN + 2];                                               
100     int n = uevent_kernel_multicast_recv(device_fd_, msg, UEVENT_MSG_LEN);      
101     if (n <= 0) {                                                               
102         if (errno != EAGAIN && errno != EWOULDBLOCK) {                          
103             LOG(ERROR) << "Error reading from Uevent Fd";                       
104         }                                                                       
105         return false;                                                           
106     }                                                                                                                                                                                                          
107     if (n >= UEVENT_MSG_LEN) {                                                  
108         LOG(ERROR) << "Uevent overflowed buffer, discarding";                   
109         // Return true here even if we discard as we may have more uevents pending and we
110         // want to keep processing them.                                        
111         return true;                                                            
112     }                                                                           
113                                                                                 
114     msg[n] = '\0';                                                              
115     msg[n + 1] = '\0';                                                          
116                                                                                 
117     ParseEvent(msg, uevent);                                                    
118                                                                                 
119     return true;                                                                
120 } 

函数uevent_kernel_multicast_recv中,调用uevent_kernel_multicast_uid_recv,主要看buffer的赋值。

 35 ssize_t uevent_kernel_multicast_recv(int socket, void* buffer, size_t length) {                                                                                                                                
 36     uid_t uid = -1;                                                             
 37     return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);      
 38 }

uevent_kernel_multicast_uid_recv函数:

 49 ssize_t uevent_kernel_multicast_uid_recv(int socket, void* buffer, size_t length, uid_t* uid) {
 50     return uevent_kernel_recv(socket, buffer, length, true, uid);                                                     
 51 } 

函数uevent_kernel_recv的定义如下:

 53 ssize_t uevent_kernel_recv(int socket, void* buffer, size_t length, bool require_group, uid_t* uid) {
 54     struct iovec iov = {buffer, length};                                        
 55     struct sockaddr_nl addr;                                                    
 56     char control[CMSG_SPACE(sizeof(struct ucred))];                             
 57     struct msghdr hdr = {                                                       
 58         &addr, sizeof(addr), &iov, 1, control, sizeof(control), 0,              
 59     };                                                                          
 60     struct ucred* cred;                                                         
 61                                                                                 
 62     *uid = -1;                                                                  
 63     ssize_t n = recvmsg(socket, &hdr, 0);                                       
 64     if (n <= 0) {                                                               
 65         return n;                                                               
 66     }                                                                           
 67                                                                                 
 68     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);                                 
 69     if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {                   
 70         /* ignoring netlink message with no sender credentials */               
 71         goto out;                                                               
 72     }                                                                           
 73                                                                                 
 74     cred = (struct ucred*)CMSG_DATA(cmsg);                                      
 75     *uid = cred->uid;                                                           
 76                                                                                 
 77     if (addr.nl_pid != 0) {                                                     
 78         /* ignore non-kernel */                                                 
 79         goto out;                                                               
 80     }                                                                           
 81     if (require_group && addr.nl_groups == 0) {                                 
 82         /* ignore unicast messages when requested */                            
 83         goto out;                                                               
 84     }                                                                           
 85                                                                                 
 86     return n;                                                                   
 87                                                                                 
 88 out:                                                                            
 89     /* clear residual potentially malicious data */                             
 90     bzero(buffer, length);                                                      
 91     errno = EIO;                                                                
 92     return -1;                                                                                                        
 93 }  

在uevent_listener.cpp中:


在文件lib/kobject_uevent.c的kobject_uevent_env的函数中:

481         list_for_each_entry(ue_sk, &uevent_sock_list, list) {                   
482                 struct sock *uevent_sock = ue_sk->sk;                           
483                 struct sk_buff *skb;                                            
484                 size_t len;                                                     
485                                                                                 
486                 if (!netlink_has_listeners(uevent_sock, 1))                     
487                         continue;                                               
488                                                                                 
489                 /* allocate message with the maximum possible size */           
490                 len = strlen(action_string) + strlen(devpath) + 2;              
491                 skb = alloc_skb(len + env->buflen, GFP_KERNEL);                 
492                 if (skb) {                                                      
493                         char *scratch;                                          
494                                                                                 
495                         /* add header */                                        
496                         scratch = skb_put(skb, len);                            
497                         sprintf(scratch, "%s@%s", action_string, devpath);      
498                                                                                 
499                         /* copy keys to our continuous event payload buffer */  
500                         for (i = 0; i < env->envp_idx; i++) {                   
501                                 len = strlen(env->envp[i]) + 1;                 
502                                 scratch = skb_put(skb, len);                    
503                                 strcpy(scratch, env->envp[i]);                  
504                                 if(!strncmp(subsystem,"block",5)) {             
505                                     printk(KERN_ERR "tom F=%s env1->envp[%d]=%s",__FUNCTION__,i,env->envp[i]);
506                                 }                                               
507                         }                                                       
508                                                                                 
509                         NETLINK_CB(skb).dst_group = 1;                          
510                         retval = netlink_broadcast_filtered(uevent_sock, skb,   
511                                 0, 1, GFP_KERNEL,                               
512                                 kobj_bcast_filter,                              
513                                 kobj);                                          
514                         /* ENOBUFS should be handled in userspace */            
515                         if (retval == -ENOBUFS || retval == -ESRCH)             
516                                 retval = 0;                                                                           
517                 } else                                                          
518                         retval = -ENOMEM;                                       
519         }    

调试记录:

[    1.391153] tom F=kobject_uevent_env env1->envp[0]=ACTION=add
[    1.391630] tom F=kobject_uevent_env env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2
[    1.392211] tom F=kobject_uevent_env env1->envp[2]=SUBSYSTEM=block
[    1.393073] tom F=kobject_uevent_env env1->envp[3]=SYNTH_UUID=0
[    1.393574] tom F=kobject_uevent_env env1->envp[4]=MAJOR=253
[    1.394135] tom F=kobject_uevent_env env1->envp[5]=MINOR=2
[    1.394748] tom F=kobject_uevent_env env1->envp[6]=DEVNAME=vda2
[    1.395193] tom F=kobject_uevent_env env1->envp[7]=DEVTYPE=partition
[    1.395670] tom F=kobject_uevent_env env1->envp[8]=PARTN=2
[    1.396199] tom F=kobject_uevent_env env1->envp[9]=PARTNAME=super
[    1.396732] tom F=kobject_uevent_env env1->envp[10]=SEQNUM=1035
[    1.397385] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2 subsystem=block
[    1.398695] init: tom firmware= p_name=super
[    1.399152] init: tom device_name=vda2 modifies=
[    1.399540] init: tom partition_num=2 major=253 minor=2
[    1.400378] tom F=kobject_uevent_env subsystem=block
[    1.400379] tom F=kobject_uevent_env devpath=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1
[    1.400864] tom F=kobject_uevent_env envp=SYNTH_UUID=0
[    1.401666] tom F=kobject_uevent_env env1->envp[0]=ACTION=add
[    1.402088] tom F=kobject_uevent_env env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1
[    1.402559] tom F=kobject_uevent_env env1->envp[2]=SUBSYSTEM=block
[    1.403382] tom F=kobject_uevent_env env1->envp[3]=SYNTH_UUID=0
[    1.403995] tom F=kobject_uevent_env env1->envp[4]=MAJOR=253
[    1.404501] tom F=kobject_uevent_env env1->envp[5]=MINOR=1
[    1.404957] tom F=kobject_uevent_env env1->envp[6]=DEVNAME=vda1
[    1.405399] tom F=kobject_uevent_env env1->envp[7]=DEVTYPE=partition
[    1.405878] tom F=kobject_uevent_env env1->envp[8]=PARTN=1
[    1.406393] tom F=kobject_uevent_env env1->envp[9]=PARTNAME=vbmeta
[    1.406838] tom F=kobject_uevent_env env1->envp[10]=SEQNUM=1036
[    1.407369] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1 subsystem=block
[    1.408748] init: tom firmware= p_name=vbmeta
[    1.409110] init: tom device_name=vda1 modifies=
[    1.409495] init: tom partition_num=1 major=253 minor=1

调试纪录:
可以看出,在kernel中传递了PARTNAME、DEVPATH和DEVTYPE等变量.

在core/init/uevent_listener.cpp的ParseEvent函数中:

 32 static void ParseEvent(const char* msg, Uevent* uevent) {                       
 33     uevent->partition_num = -1;                                                 
 34     uevent->major = -1;                                                         
 35     uevent->minor = -1;                                                         
 36     uevent->action.clear();                                                     
 37     uevent->path.clear();                                                       
 38     uevent->subsystem.clear();                                                  
 39     uevent->firmware.clear();                                                   
 40     uevent->partition_name.clear();                                             
 41     uevent->device_name.clear();                                                
 42     uevent->modalias.clear();                                                   
 43     // currently ignoring SEQNUM                                                
 44     while (*msg) {                                                              
 45         if (!strncmp(msg, "ACTION=", 7)) {                                      
 46             msg += 7;                                                           
 47             uevent->action = msg;                                               
 48         } else if (!strncmp(msg, "DEVPATH=", 8)) {                              
 49             msg += 8;                                                           
 50             uevent->path = msg;                                                 
 51         } else if (!strncmp(msg, "SUBSYSTEM=", 10)) {                           
 52             msg += 10;                                                          
 53             uevent->subsystem = msg;                                            
 54         } else if (!strncmp(msg, "FIRMWARE=", 9)) {                             
 55             msg += 9;                                                           
 56             uevent->firmware = msg;                                             
 57         } else if (!strncmp(msg, "MAJOR=", 6)) {                                
 58             msg += 6;                                                           
 59             uevent->major = atoi(msg);                                          
 60         } else if (!strncmp(msg, "MINOR=", 6)) {                                
 61             msg += 6;                                                           
 62             uevent->minor = atoi(msg);                                          
 63         } else if (!strncmp(msg, "PARTN=", 6)) {                                
 64             msg += 6;                                                           
 65             uevent->partition_num = atoi(msg);                                  
 66         } else if (!strncmp(msg, "PARTNAME=", 9)) {                             
 67             msg += 9;                                                           
 68             uevent->partition_name = msg;                                       
 69         } else if (!strncmp(msg, "DEVNAME=", 8)) {                              
 70             msg += 8;                                                           
 71             uevent->device_name = msg;                                          
 72         } else if (!strncmp(msg, "MODALIAS=", 9)) {                             
 73             msg += 9;                                                           
 74             uevent->modalias = msg;                                             
 75         }                                                                       
 76                                                                                 
 77         // advance to after the next \0                                         
 78         while (*msg++)                                                          
 79             ;                                                                                                                                                                                                  
 80     }  

结论是: init进程接收的partname是由kernel中传递的。

日志的LOG如下:

 210 [    1.226856] tom virtio_blk_init                                              
 211 [    1.227226] random: crng init done                                           
 212 [    1.229048] tom F=set_disk_ro_uevent L=1464                                  
 213 [    1.230329] vda: vda1 vda2                                                   
 214 [    1.239918] tom F=set_disk_ro_uevent L=1464        

 322 [    1.386757] init: [libfs_mgr]ReadFstabFromDt(): failed to read fstab from dt 
 323 [    1.387494] init: [libfs_mgr]ReadDefaultFstab L=749 default_fstab_path=/fstab.ranchu
 324 [    1.388292] init: [libfs_mgr]tom L=476 line=# Android fstab file for ramdisk tom -3
 325 [    1.389028] init:                                                            
 326 [    1.389212] init: [libfs_mgr]tom L=476 line=#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
 327 [    1.389993] init:                                                            
 328 [    1.390272] init: [libfs_mgr]tom L=476 line=system   /system     ext4    ro,barrier=1     wait,logical,avb=vbmeta,first_stage_mount
 329 [    1.391230] init:                                                            
 330 [    1.391430] init: [libfs_mgr]tom L=476 line=vendor   /vendor     ext4    ro,barrier=1     wait,logical,first_stage_mount

                                                                                                                                                 
 215 [    1.242200] vde: vde1    
 375 [    1.421904] tom F=kobject_uevent_env env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda
 376 [    1.422365] tom F=kobject_uevent_env env1->envp[2]=SUBSYSTEM=block           
 377 [    1.423161] tom F=kobject_uevent_env env1->envp[3]=SYNTH_UUID=0              
 378 [    1.423652] tom F=kobject_uevent_env env1->envp[4]=MAJOR=253                 
 379 [    1.424122] tom F=kobject_uevent_env env1->envp[5]=MINOR=0                   
 380 [    1.424568] tom F=kobject_uevent_env env1->envp[6]=DEVNAME=vda               
 381 [    1.425009] tom F=kobject_uevent_env env1->envp[7]=DEVTYPE=disk              
 382 [    1.425468] tom F=kobject_uevent_env env1->envp[8]=SEQNUM=1034               
 383 [    1.426090] tom F=kobject_uevent_env subsystem=block                         
 384 [    1.426592] tom F=kobject_uevent_env devpath=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2
 385 [    1.427128] tom F=kobject_uevent_env envp=SYNTH_UUID=0                       
 386 [    1.427899] tom F=kobject_uevent_env env1->envp[0]=ACTION=add                
 387 [    1.428308] tom F=kobject_uevent_env env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2
 388 [    1.428760] tom F=kobject_uevent_env env1->envp[2]=SUBSYSTEM=block           
 389 [    1.429575] tom F=kobject_uevent_env env1->envp[3]=SYNTH_UUID=0              
 390 [    1.430091] tom F=kobject_uevent_env env1->envp[4]=MAJOR=253                 
 391 [    1.430557] tom F=kobject_uevent_env env1->envp[5]=MINOR=2                   
 392 [    1.431003] tom F=kobject_uevent_env env1->envp[6]=DEVNAME=vda2              
 393 [    1.431438] tom F=kobject_uevent_env env1->envp[7]=DEVTYPE=partition         
 394 [    1.431903] tom F=kobject_uevent_env env1->envp[8]=PARTN=2                   
 395 [    1.432401] tom F=kobject_uevent_env env1->envp[9]=PARTNAME=super            
 396 [    1.432837] tom F=kobject_uevent_env env1->envp[10]=SEQNUM=1035              
 397 [    1.433422] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda2 subsystem=block
 398 [    1.434670] init: tom firmware= p_name=super                                 
 399 [    1.435018] init: tom device_name=vda2 modifies=                             
 400 [    1.435408] init: tom partition_num=2 major=253 minor=2                      
 401 [    1.436173] tom F=kobject_uevent_env subsystem=block                         
 402 [    1.436174] tom F=kobject_uevent_env devpath=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1
 403 [    1.436565] tom F=kobject_uevent_env envp=SYNTH_UUID=0                       
 404 [    1.437265] tom F=kobject_uevent_env env1->envp[0]=ACTION=add                
 405 [    1.437662] tom F=kobject_uevent_env env1->envp[1]=DEVPATH=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1
 406 [    1.438103] tom F=kobject_uevent_env env1->envp[2]=SUBSYSTEM=block           
 407 [    1.438881] tom F=kobject_uevent_env env1->envp[3]=SYNTH_UUID=0              
 408 [    1.439347] tom F=kobject_uevent_env env1->envp[4]=MAJOR=253                 
 409 [    1.439805] tom F=kobject_uevent_env env1->envp[5]=MINOR=1                   
 410 [    1.440362] tom F=kobject_uevent_env env1->envp[6]=DEVNAME=vda1              
 411 [    1.440793] tom F=kobject_uevent_env env1->envp[7]=DEVTYPE=partition         
 412 [    1.441329] tom F=kobject_uevent_env env1->envp[8]=PARTN=1                   
 413 [    1.441874] tom F=kobject_uevent_env env1->envp[9]=PARTNAME=vbmeta           
 414 [    1.442316] tom F=kobject_uevent_env env1->envp[10]=SEQNUM=1036              
 415 [    1.442835] init: tom action=add path=/devices/pci0000:00/0000:00:03.0/virtio0/block/vda/vda1 subsystem=block
 416 [    1.444161] init: tom firmware= p_name=vbmeta                                
 417 [    1.444510] init: tom device_name=vda1 modifies=                             
 418 [    1.444898] init: tom partition_num=1 major=253 minor=1    

函数 定义如下:

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];                    
332         const char *devpath = NULL;                                             
333         const char *subsystem;                                                  
334         struct kobject *top_kobj;                                               
335         struct kset *kset;                                                      
336         const struct kset_uevent_ops *uevent_ops;                               
337         int i = 0;                                                              
338         int retval = 0;                                                         
339 #ifdef CONFIG_NET                                                               
340         struct uevent_sock *ue_sk;                                              
341         u32 dst_nl_group = 0;                                                   
342 #endif                                                                          
343                                                                                 
344         /*                                                                      
345          * Mark "remove" event done regardless of result, for some subsystems   
346          * do not want to re-trigger "remove" event via automatic cleanup.      
347          */                                                                     
348         if (action == KOBJ_REMOVE)                                              
349                 kobj->state_remove_uevent_sent = 1;                             
350                                                                                 
351         pr_debug("kobject: '%s' (%p): %s\n",                                    
352                  kobject_name(kobj), kobj, __func__);                           
353                                                                                 
354         /* search the kset we belong to */                                      
355         top_kobj = kobj;                                                        
356         while (!top_kobj->kset && top_kobj->parent)                             
357                 top_kobj = top_kobj->parent;                                    
358                                                                                 
359         if (!top_kobj->kset) {                                                  
360                 pr_debug("kobject: '%s' (%p): %s: attempted to send uevent "    
361                          "without kset!\n", kobject_name(kobj), kobj,           
362                          __func__);                                             
363                 return -EINVAL;                                                 
364         }                                                                       
365                                                                                 
366         kset = top_kobj->kset;                                                  
367         uevent_ops = kset->uevent_ops;                                          
368                                                                                 
369         /* skip the event, if uevent_suppress is set*/                          
370         if (kobj->uevent_suppress) {                                            
371                 pr_debug("kobject: '%s' (%p): %s: uevent_suppress "             
372                                  "caused the event to drop!\n",                 
373                                  kobject_name(kobj), kobj, __func__);           
374                 return 0;                                                       
375         }                                                                       
376         /* skip the event, if the filter returns zero. */                       
377         if (uevent_ops && uevent_ops->filter)                                   
378                 if (!uevent_ops->filter(kset, kobj)) {                          
379                         pr_debug("kobject: '%s' (%p): %s: filter function "     
380                                  "caused the event to drop!\n",                 
381                                  kobject_name(kobj), kobj, __func__);           
382                         return 0;                                               
383                 }                                                               
384                                                                                 
385         /* originating subsystem */                                             
386         if (uevent_ops && uevent_ops->name)                                     
387                 subsystem = uevent_ops->name(kset, kobj);                       
388         else                                                                    
389                 subsystem = kobject_name(&kset->kobj);                          
390         if (!subsystem) {                                                       
391                 pr_debug("kobject: '%s' (%p): %s: unset subsystem caused the "  
392                          "event to drop!\n", kobject_name(kobj), kobj,          
393                          __func__);                                             
394                 return 0;                                                       
395         }                                                                       
396                                                                                 
397                                                                                 
398         /* environment buffer */                                                
399         env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);              
400         if (!env)                                                               
401                 return -ENOMEM;                                                 
402                                                                                 
403         /* complete object path */                                              
404         devpath = kobject_get_path(kobj, GFP_KERNEL);                           
405         if (!devpath) {                                                         
406                 retval = -ENOENT;                                               
407                 goto exit;                                                      
408         }                                                                       
409                                                                                 
410         /* default keys */                                                      
411         retval = add_uevent_var(env, "ACTION=%s", action_string);               
412         if (retval)                                                                                                                                                                                     
413                 goto exit;                                                      
414         retval = add_uevent_var(env, "DEVPATH=%s", devpath);                    
415         if (retval)                                                             
416                 goto exit;                                                      
417         retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);                
418         if (retval)                                                             
419                 goto exit;                                                      
420                                                                                 
421         if(!strncmp(subsystem,"block",5))                                       
422             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
423                                                                                 
424         /* keys passed in from the caller */                                    
425         if (envp_ext) {                                                         
426                 for (i = 0; envp_ext[i]; i++) {                                 
427                         retval = add_uevent_var(env, "%s", envp_ext[i]);        
428                                                                                 
429                                                                                 
430                         if (retval)                                             
431                                 goto exit;                                      
432                 }                                                               
433         }                                                                       
434                                                                                 
435         if(!strncmp(subsystem,"block",5))                                       
436             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
437                                                                                 
438         /* let the kset specific function add its stuff */                      
439         if (uevent_ops && uevent_ops->uevent) {                                 
440                 retval = uevent_ops->uevent(kset, kobj, env);                   
441                                                                                 
442                 if(!strncmp(subsystem,"block",5))                               
443                     printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
444                                                                                 
445                 if (retval) {                                                   
446                         pr_debug("kobject: '%s' (%p): %s: uevent() returned "   
447                                  "%d\n", kobject_name(kobj), kobj,              
448                                  __func__, retval);                             
449                         goto exit;                                              
450                 }                                                               
451         }                                                                       
452                                                                                 
453         if(!strncmp(subsystem,"block",5))                                       
454             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
455                                                                                 
456         switch (action) {                                                       
457         case KOBJ_ADD:                                                          
458                 /*                                                              
459                  * Mark "add" event so we can make sure we deliver "remove"                                                                                                                             
460                  * event to userspace during automatic cleanup. If              
461                  * the object did send an "add" event, "remove" will            
462                  * automatically generated by the core, if not already done     
463                  * by the caller.                                               
464                  */                                                             
465                 kobj->state_add_uevent_sent = 1;                                
466                 break;                                                          
467                                                                                 
468         case KOBJ_UNBIND:                                                       
469                 zap_modalias_env(env);                                          
470                 break;                                                          
471                                                                                 
472         default:                                                                
473                 break;                                                          
474         }                                                                       
475                                                                                 
476         if(!strncmp(subsystem,"block",5))                                       
477             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
478         mutex_lock(&uevent_sock_mutex);                                         
479         /* we will send an event, so request a new sequence number */           
480         retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
481         if (retval) {                                                           
482                 mutex_unlock(&uevent_sock_mutex);                               
483                 goto exit;                                                      
484         }                                                                       
485                                                                                 
486                                                                                 
487        /* for (i = 0; i < env->envp_idx; i++) {*/                               
488             /*if(!strncmp(subsystem,"block",5))*/                               
489                 /*printk(KERN_ERR "tom-111 F=%s env1->envp[%d]=%s",__FUNCTION__,i,env->envp[i]);*/
490         /*}*/                                                                   
491                                                                                 
492         if(!strncmp(subsystem,"block",5))                                       
493             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
494                                                                                 
495 #if defined(CONFIG_NET)                                                         
496         dst_nl_group =                                                          
497                 (strcmp(subsystem, "power_supply") == 0) ? (1u << 16) : 0;      
498                                                                                 
499         /* send netlink message */                                              
500         list_for_each_entry(ue_sk, &uevent_sock_list, list) {                   
501                 struct sock *uevent_sock = ue_sk->sk;                           
502                 struct sk_buff *skb;                                            
503                 size_t len;                                                     
504                                                                                 
505                 if (!netlink_has_listeners(uevent_sock, 1))                     
506                         continue;                                               
507                                                                                 
508                 /* allocate message with the maximum possible size */           
509                 len = strlen(action_string) + strlen(devpath) + 2;                                                                                                                                      
510                 skb = alloc_skb(len + env->buflen, GFP_KERNEL);                 
511                 if (skb) {                                                      
512                         char *scratch;                                          
513                                                                                 
514                         /* add header */                                        
515                         scratch = skb_put(skb, len);                            
516                         sprintf(scratch, "%s@%s", action_string, devpath);      
517                                                                                 
518                         /* copy keys to our continuous event payload buffer */  
519                         for (i = 0; i < env->envp_idx; i++) {                   
520                                 len = strlen(env->envp[i]) + 1;                 
521                                 scratch = skb_put(skb, len);                    
522                                 strcpy(scratch, env->envp[i]);                  
523                                 if(!strncmp(subsystem,"block",5)) {             
524                                     printk(KERN_ERR "tom F=%s env1->envp[%d]=%s",__FUNCTION__,i,env->envp[i]);
525                                 }                                               
526                         }                                                       
527                                                                                 
528                         NETLINK_CB(skb).dst_group = 1;                          
529                         retval = netlink_broadcast_filtered(uevent_sock, skb,   
530                                 0, 1, GFP_KERNEL,                               
531                                 kobj_bcast_filter,                              
532                                 kobj);                                          
533                         /* ENOBUFS should be handled in userspace */            
534                         if (retval == -ENOBUFS || retval == -ESRCH)             
535                                 retval = 0;                                     
536                 } else                                                          
537                         retval = -ENOMEM;                                       
538         }                                                                       
539         if(!strncmp(subsystem,"block",5))                                       
540             printk(KERN_ERR "tom F=%s L=%d env->envp_idx=%d",__FUNCTION__,__LINE__,env->envp_idx);
541                                                                                 
542         if (dst_nl_group) {                                                     
543                 /* send netlink message */                                      
544                 list_for_each_entry(ue_sk, &uevent_sock_list, list) {           
545                         struct sock *uevent_sock = ue_sk->sk;                   
546                         struct sk_buff *skb;                                    
547                         size_t len;                                             
548                                                                                 
549                         if (!netlink_has_listeners(uevent_sock, dst_nl_group))  
550                                 continue;                                       
551                                                                                 
552                         /* allocate message with the maximum possible size */   
553                         len = strlen(action_string) + strlen(devpath) + 2;      
554                         skb = alloc_skb(len + env->buflen, GFP_KERNEL);                                                                                                                                 
555                         if (skb) {                                              
556                                 char *scratch;                                  
557                                                                                 
558                                 /* add header */                                
559                                 scratch = skb_put(skb, len);                    
560                                 sprintf(scratch, "%s@%s", action_string,        
561                                         devpath);                               
562                                                                                 
563                                 /* copy keys to our continuous event payload    
564                                  * buffer                                       
565                                  */                                             
566                                 for (i = 0; i < env->envp_idx; i++) {           
567                                         len = strlen(env->envp[i]) + 1;         
568                                         scratch = skb_put(skb, len);            
569                                         strcpy(scratch, env->envp[i]);          
570                                         if(!strncmp(subsystem,"block",5)) {     
571                                             printk(KERN_ERR "tom F=%s env2->envp[%d]=%s",__FUNCTION__,i,env->envp[i]);
572                                         }                                       
573                                 }                                               
574                                                                                 
575                                                                                 
576                         if(!strncmp(subsystem,"block",5)) {                     
577                             printk(KERN_ERR "tom F=%s subsystem=%s",__FUNCTION__,subsystem);
578                             printk(KERN_ERR "tom F=%s devpath=%s",__FUNCTION__,devpath);
579                             printk(KERN_ERR "tom F=%s envp=%s",__FUNCTION__,envp_ext[i]);
580                         }                                                       
581                                                                                 
582                                                                                 
583                                 NETLINK_CB(skb).dst_group = dst_nl_group;       
584                                 retval = netlink_broadcast_filtered(            
585                                         uevent_sock, skb,                       
586                                         0, dst_nl_group, GFP_KERNEL,            
587                                         kobj_bcast_filter,                      
588                                         kobj);                                  
589                                 /* ENOBUFS should be handled in userspace */    
590                                 if (retval == -ENOBUFS || retval == -ESRCH)     
591                                         retval = 0;                             
592                         } else                                                  
593                                 retval = -ENOMEM;                               
594                 }                                                               
595         }                                                                       
596 #endif                                                                          
597         mutex_unlock(&uevent_sock_mutex);                                       
598                                                                                 
599 #ifdef CONFIG_UEVENT_HELPER                                                     
600         /* call uevent_helper, usually only enabled during early boot */        
601         if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {                  
602                 struct subprocess_info *info;                                                                                                                                                           
603                                                                                 
604                 retval = add_uevent_var(env, "HOME=/");                         
605                 if (retval)                                                     
606                         goto exit;                                              
607                 retval = add_uevent_var(env,                                    
608                                         "PATH=/sbin:/bin:/usr/sbin:/usr/bin");  
609                 if (retval)                                                     
610                         goto exit;                                              
611                 retval = init_uevent_argv(env, subsystem);                      
612                 if (retval)                                                     
613                         goto exit;                                              
614                                                                                 
615                 retval = -ENOMEM;                                               
616                 info = call_usermodehelper_setup(env->argv[0], env->argv,       
617                                                  env->envp, GFP_KERNEL,         
618                                                  NULL, cleanup_uevent_env, env);
619                 if (info) {                                                     
620                         retval = call_usermodehelper_exec(info, UMH_NO_WAIT);   
621                         env = NULL;     /* freed by cleanup_uevent_env */       
622                 }                                                               
623         }                                                                       
624 #endif                                                                          
625                                                                                 
626 exit:                                                                           
627         kfree(devpath);                                                         
628         kfree(env);                                                             
629         return retval;                                                          
630 }                                                                
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值