vold.fstab DirectVolume

来源:互联网 发布:幼儿园网络培训意义 编辑:程序博客网 时间:2024/06/10 12:36

/etc/vold.fstab,相当于Linux下的/etc/fstab

系统启动起来,分析该配置文件,挂载相应的分区

  1. /********************************************************************************** 
  2. **该函数用来解析/etc/vold.fstab配置文件,文本的处理; 
  3. **可能不同的源码版本,有点差异; 
  4. **strsep是字符串的分割函数,可以看出该函数是以" \t"来分割(\t前面有一空格),分割空格 
  5. **或制表格,所以配置文件里面空格与tab键来分割都行; 
  6. **strsep不是ANSI C的函数,但它用来取代strtok函数,strtok是线程不安全的函数。 
  7. **********************************************************************************/  
  8. static int process_config(VolumeManager *vm) {  
  9.     FILE *fp;  
  10.     int n = 0;  
  11.     char line[255];  
  12.   
  13.     if (!(fp = fopen("/etc/vold.fstab""r"))) {  
  14.             return -1;  
  15.     }  
  16.   
  17.     while(fgets(line, sizeof(line), fp)) {  
  18.         char *next = line;  
  19.         char *type, *label, *mount_point;  
  20.   
  21.         n++;  
  22.         line[strlen(line)-1] = '\0';  
  23.   
  24.         if (line[0] == '#' || line[0] == '\0')  
  25.                 continue;  
  26.   
  27.         if (!(type = strsep(&next, " \t"))) {  
  28.                 SLOGE("Error parsing type");  
  29.                 goto out_syntax;  
  30.         }  
  31.         if (!(label = strsep(&next, " \t"))) {  
  32.                 SLOGE("Error parsing label");  
  33.                 goto out_syntax;  
  34.         }  
  35.         if (!(mount_point = strsep(&next, " \t"))) {  
  36.                 SLOGE("Error parsing mount point");  
  37.                 goto out_syntax;  
  38.         }  
  39.   
  40.         if (!strcmp(type, "dev_mount")) {  
  41.             DirectVolume *dv = NULL;  
  42.             char *part, *sysfs_path;  
  43.   
  44.             if (!(part = strsep(&next, " \t"))) {  
  45.                     SLOGE("Error parsing partition");  
  46.                     goto out_syntax;  
  47.             }  
  48.             if (strcmp(part, "auto") && atoi(part) == 0) {  
  49.                     SLOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part);  
  50.                     goto out_syntax;  
  51.             }  
  52.             /********************************************************************************** 
  53.             **如果配置文件指定为auto,则为自动挂载存储设备,在实例化DirectVolume的对象,传递-1 
  54.             **进去,否则将分区序数part传进去; 
  55.             **********************************************************************************/  
  56.             if (!strcmp(part, "auto")) {  
  57.                     dv = new DirectVolume(vm, label, mount_point, -1);  
  58.             } else {  
  59.                     dv = new DirectVolume(vm, label, mount_point, atoi(part));  
  60.             }  
  61.   
  62.             while((sysfs_path = strsep(&next, " \t"))) {  
  63.                 /********************************************************************************** 
  64.                 **将存储设备在/sys/对应的路径添加进PathCollection容器,该容器为“char *”类型; 
  65.                 **在/sys/里面可以获取到存储设备的热插拔事件,所以DirectVolume类的主要工作就是针对 
  66.                 **这里去获取uevent事件的; 
  67.                 **DirectVolume::handleBlockEvent(NetlinkEvent *evt)函数去得到这些事件,主要还是 
  68.                 **NetlinkListener类从内核捕获到的。 
  69.                 **********************************************************************************/  
  70.                 if (dv->addPath(sysfs_path)) {  
  71.                         SLOGE("Failed to add devpath %s to volume %s", sysfs_path,  
  72.                                  label);  
  73.                         goto out_fail;  
  74.                 }  
  75.             }  
  76.             /********************************************************************************** 
  77.             **如果在配置文件有找到正确的挂载参数,那么就会将DirectVolume的对象添加到VolumeCollection 
  78.             **容器中,该容器存放着Volume*类型的数据,VolumeManager的对象vm是用来管理这些存储设备的; 
  79.             **一块存储设备就会实例化一个Volume对象,但对于手机来说,一般只能识别到一张SD卡。 
  80.             **********************************************************************************/  
  81.             vm->addVolume(dv);  
  82.         } else if (!strcmp(type, "map_mount")) {  
  83.         } else {  
  84.                 SLOGE("Unknown type '%s'", type);  
  85.                 goto out_syntax;  
  86.         }  
  87.     }  
  88.   
  89.     fclose(fp);  
  90.     return 0;  
  91.   
  92. /********************************************************************************** 
  93. **从这个函数的出错处理可以看出,系统源码经常使用到这种高效性的goto技巧,goto在 
  94. **系统中的出错处理用得很频繁,可以说几乎每个文件都使用到了goto跳转函数; 
  95. **很多文章或者教材,经常反面性的批判goto的不规则,但从这些外国的开源代码可以看出, 
  96. **那些牛人都很喜欢用goto,利用了goto来处理出错情况的技巧,显得很漂亮; 
  97. **我觉得,要从实用性的角度来评论这些语言的优缺点,并不能用否认的说法来解释,这样才能 
  98. **不断地进步; 
  99. **所以,如果在出错处理非常多的情况下,使用goto是使代码更可读,减少重复的出错判断的 
  100. **代码量。 
  101. **********************************************************************************/  
  102. out_syntax:  
  103.         SLOGE("Syntax error on config line %d", n);  
  104.         errno = -EINVAL;  
  105. out_fail:  
  106.         fclose(fp);  
  107.         return -1;     
  108. }  

DirectVolume