android之VOLD:staging目录作用与ASEC文件 -总结

    转:http://blog.csdn.net/honour2sword/article/details/10858133

    /mnt/secure/staging

    来看一下mountVol代码

     int Volume::mountVol() {

        int rc = 0;

        char errmsg[255];

        const char *mountPath;

     

            char devicePath[255];

            

            sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(mDevNodeIndex),

                    MINOR(mDevNodeIndex));//得到设备节点,:/dev/block/vold/8:1

         

            SLOGI("%s being considered for volume %s ...major : %d minor: %d\n", devicePath, getLabel(),

             MAJOR(mDevNodeIndex),MINOR(mDevNodeIndex));

        

            errno = 0;

            setState(Volume::State_Checking);//设置状态为checking整型为3

        

            // TODO: find a way to read the filesystem ID

            bool isFatFs = true;

            bool isNtfsFS = true;

             //检查设备格式是否为Fat32

            if (Fat::check(devicePath)) {

                if (errno == ENODATA) {

                    SLOGW("%s does not contain a FAT filesystem\n", devicePath);

                    isFatFs = false;

                } else {

                  errno = EIO;

                  /* Badness - abort the mount */

                  SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));

                  setState(Volume::State_Idle);

                  return -1;

                }

            }

     

            //创建挂载目录

           // create mountpoint

            if (mkdir(getMountpoint(), 0755)) {

                if (errno != EEXIST) {

                    SLOGE("Failed to create mountpoint %s (%s)", getMountpoint(), strerror(errno));

                    return -1;

                }

            }

        

            /*

             * Mount the device on our internal staging mountpoint so we can

             * muck with it before exposing it to non priviledged users.

             */

            errno = 0;

            //如果为sdcard则挂载到/mnt/secure/staging,否则挂载到挂载点------------1 为什么?

             if(!strcmp(getLabel(),"sdcard"))

                mountPath="/mnt/secure/staging";

            else

                mountPath=getMountpoint();

             //接下来就是不同格式不同的挂载,这里支持两种格式:fat32,Ntfs

            if ( isFatFs ) {

                if (Fat::doMount(devicePath,mountPath, falsefalse100010150702true)) {

                    SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));

                    

                    isFatFs = false;

                }

                isNtfsFS = false;

            }

            

            if ( isNtfsFS ) {

                if (Ntfs::doMount(devicePath, mountPath, true)) {

                    SLOGE("%s failed to mount via NTFS (%s)\n", devicePath, strerror(errno));

                    isNtfsFS = false;

                }

            }

        

            if ( !isFatFs && !isNtfsFS ) {

                // unsupported filesystem

                return -1;

            }

            

            SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint());

            

            

            if ( !strcmp(getLabel(), "sdcard") ) {

                

                protectFromAutorunStupidity();

        

                if (createBindMounts()) {

    2.createBindMounts的作用有三点:

    1.确认android_secure目录存在;2.挂载tmpfs ,目的是把该目录变成一个虚拟的分区,达到隐藏android_secure目录的目的,(为什么tmpfs有这个作用,请查看linux tmpfs3)挂载/mnt/secure/staging/android_secure/mnt/secure/asec

     

                    SLOGE("Failed to create bindmounts (%s)", strerror(errno));

                    umount("/mnt/secure/staging");

                    setState(Volume::State_Idle);

                    return -1;

                }

            }

        

            /*---3.为什么现在才移到目标挂载目录?

             * Now that the bindmount trickery is done, atomically move the

             * whole subtree to expose it to non priviledged users.

             * 如果为sdcard则将/mnt/secure/staging 目录移动到挂载点,并将该目录unmount

             */

            if(!strcmp(getLabel(),"sdcard")){

              if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {

                  SLOGE("Failed to move mount (%s)", strerror(errno));

                  umount("/mnt/secure/staging");

                  setState(Volume::State_Idle);

                   return -1;

              }

           }

            setState(Volume::State_Mounted);//设置状态到MountService

            mCurrentlyMountedKdev = mDevNodeIndex;

                    

            return 0;

     

    1.VOLD:/mnt/secure/staging作用是什么?

    1)首先看android_secure的作用

    android的官方解释:

    "vold: Stage the mounting of media to hide the ASEC imagefile() directory

      In order to protect the '
    /android_secure' directory on VFAT removable media
    from being mucked with by 3rd party applications on the device, we hide the
    directory with a read-only, zero-sized tmpfs mounted on-top. A reference to the
    hidden directory is kept by a bind-mount which is mounted at a location which
    only root can access.
    "

    为了保护在VFAT可移动媒体上的/ android_secure目录,避免被在android设备上的第三方应用程序搞乱,我们隐藏一个只读的大小为零的tmpfs的目录安装在最上层。的参照隐藏目录保持绑定安装,安装在一个位置只有root可以访问

    "
    Staging consists ofStaging 的步骤):
      1. Mount checked media at a secure location (/mnt/secure/staging)

                挂载被检查过的存储媒体(也就是SDcard)到一个安全的位置(到/mnt/secure/staging

      2. Ensure /android_secure exists on the media, (creating if it doesnt)

              确保“/ android_secure”在存在该存储媒体(也就是SDcard)上(如果它不存在的,就创建它)

      3. Bind-mount /mnt/secure/staging/android_secure -> /mnt/secure/asec
         (where only root can access it)

    通过Volume::createBindMounts()

             绑定挂载的存储媒体(也就是SDcard)/mnt/secure/staging/android_secure/mnt/secure/asec 也就是(ASEC imagefile 

         (只有root可以访问它)

     

      4. Mount an RDONLY zero-sized tmpfs over /mnt/secure/staging/android_secure

          挂载一个RDONLY的,且零大小的tmpfs到/mnt/secure/staging/android_secure

    为什么要mount一个tempfs文件系统呢?因为tmpfs的优势:没有块设备,只存在内存,速度快

    也就是把该目录作为一个虚拟的分区(应为有了文件系统),后面就可以通过mount(SEC_STG_SECIMGDIR, SEC_ASECDIR, "", MS_BIND, NULL)

       /mnt/secure/staging/android_secure/mnt/secure/asec 

     

    5. Atomically move /mnt/secure/staging to the publicly accessable storage
         directory (/mnt/sdcard)

    原子移动doMoveMount/mnt/secure/staging到的可以让应用程序公开访问的存储目录(/mnt/sdcard

     

    "

    也就是临时目录staging的作用就是为了保护android_secure。

     

    2)其次 android_secure的来源是什么?也就是为什么要把保护它android_secure

    先来看看历史:

    Google Android手机的软件为了安全性和稳定性都是默认安装到手机内存里,但是手机内存有限,所以我们会做app2sd操作,来让我们安装的软件放到sd卡上,这个操作是需要rom的支持的。

        Android 2.2 可以将手机程序安装在外置的sd卡上,也就是我们平常所说的app2sd。但是,官方的app2sd非常鸡肋,需要软件自身支持安装在内存卡上才可以,也就是说用官方的app2sd,要把程序安装在内存卡上,并不是我们使用者说了算,而是软件开发者说了算。经测试安装60多个软件,其中仅有可怜的5个程序能使用官方的app2sd安装在内存卡上。所以,官方的这个app2sd就是忽悠人的。当然,现在很多第三方ROM都自带了第三方的app2sd,可以将任何程序都安装在sd卡上。

    -------应用程序相关的系统目录:

    /system 存放的是rom的信息;/system/app 存放rom本身附带的软件即系统软件;/system/data 存放/system/app 中核心系统软件的数据文件信息。

     /data 存放的是用户的软件信息(非自带rom安装的软件);

    /data/app 存放用户安装的软件;

    /data/data 存放所有软件(包括/system/app  /data/app  /mnt/asec中装的软件)的一些libxml文件等数据信息;

    /data/dalvik-cache 存放程序的缓存文件,这里的文件都是可以删除的。

    ---------应用程序相关的数据目录:

    那么app2sd 的应用程序数据需要哪些关键的文件夹来保存呢?

    用户程序安装到到sd卡上后,其内容可能分散到:/mnt/asec , /mnt/secure , /data/data

    我们最关注“/mnt/asec 目录和 /mnt/secure 目录。所以当SD卡挂载于手机时,/mnt/sdcard/.android_secure 目录会被映射到/mnt/asec 目录和 /mnt/secure 目录。其中/mnt/asec 目录中主要是程序的安装目录,包括其执行文件和lib文件等;而/mnt/secure 目录中就存放程序加密后的档案。 ”例如:


    解密档案:

    android之VOLD:staging目录作用与ASEC文件 -总结_第1张图片

     

    另外注意:

    就是说,在/mnt路径下看到的/mnt/asec目录和/mnt/secure目录并不是真正存在在手机内存或者sd卡的分区挂载目录,他们本省只是根文件系统初始化的时候创建的两个目录,它们只是/mnt/sdcard/.android_secure目录的一个影像而已(也就是挂载点)

    怎么看出来呢? 很简单,打开手机的mass storage。如下:

    android之VOLD:staging目录作用与ASEC文件 -总结_第2张图片

    在通过ADB查看/mnt/asec目录和/mnt/secure 就发现是空的目录:

    android之VOLD:staging目录作用与ASEC文件 -总结_第3张图片

     

    3)什么时候Bind-mount /mnt/secure/staging/android_secure -> /mnt/secure/asec

    也就是/mnt/secure/staging/android_secure 会被mount/mnt/secure/asec

    const char *Volume::SEC_STG_SECIMGDIR = "/mnt/secure/staging/android_secure";
    + * Path to where *only* root can access asec imagefiles
    +const char *Volume::SEC_ASECDIR       = "/mnt/secure/asec";

     

    通过Volume::createBindMounts

    {

    …………...

    /*
    +     * Bind mount /mnt/secure/staging/android_secure -> /mnt/secure/asec so we'll
    +     * have a root only accessable mountpoint for it.
    +     */
    +    if (mount(SEC_STG_SECIMGDIR, SEC_ASECDIR, "", MS_BIND, NULL)) {
    +        LOGE("Failed to bind mount points %s -> %s (%s)",
    +                SEC_STG_SECIMGDIR, SEC_ASECDIR, strerror(errno));
    +        return -1;
    +    }

     

    …………………

    }

    执行完之后:sdcard/.android_secure目录下的*.asec文件就被mount/mnt/secure/asec:如下

    android之VOLD:staging目录作用与ASEC文件 -总结_第4张图片

     

    4mount完之后/mnt/secure/asec的文件如何解析到/mnt/asec

    int VolumeManager::mountAsec(const char *idconst char *keyint ownerUid) {
    607    char asecFileName[255];
    608    char mountPoint[255];
    609
    610    snprintf(asecFileNamesizeof(asecFileName), "%s/%s.asec"Volume::SEC_ASECDIR,id);//SEC_ASECDIR=/mnt/secure/asec
    611    snprintf(mountPointsizeof(mountPoint), "%s/%s"Volume::ASECDIRid);//ASECDIR=/mnt/asec

    …..

     

     

    总结为什么药先mount sdcard/mnt/secure/staging/原因:,

    “那也就是说android_secure存放的是安装在SDcard的应用程序的的加密档案。那么在挂载的过程需要被保护起来,避免在挂载过程,应用程序访问该档案而被破坏,我觉得就是一个读写的互斥问题。”

     

     

    2.关于 ASEC文件

    What is an asec File?

    Filetype Android Secure Application File

    "

    File used by Froyo, the version 2.2 release of the Android mobile operating system; stores mobile application data using proprietary encryption; saved to the.android_secure folder of a device's SD card; can be run with the Android SDKemulator.

    The secure ASEC format allows applications to exist on mobile devices without being modified or corrupted by other programs.

    "

    References

  1. filefacts.net Files with the .asec file e...
  2. fileinfo.com File used by Froyo, the ver...

    How to Open .ASEC Files? Program(s) that open .ASEC files

    Mac OS:

    Google Android SDK download

    Windows:

    Google Android SDK download

    via fileinfo.com

     

    源文档 <http://asec.filebio.com/asec-file-extension>

你可能感兴趣的:(android之VOLD:staging目录作用与ASEC文件 -总结)