/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, false, false, 1000, 1015, 0702, true)) {
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 tmpfs)3)挂载/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 of(Staging 的步骤): 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中装的软件)的一些lib和xml文件等数据信息;
/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 目录中就存放程序加密后的档案。 ”例如:
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:如下
4)mount完之后/mnt/secure/asec的文件如何解析到/mnt/asec?intVolumeManager::mountAsec(constchar *id, constchar *key, intownerUid) {
607 charasecFileName[255];
608 charmountPoint[255];
609
610 snprintf(asecFileName, sizeof(asecFileName), “%s/%s.asec”, Volume::SEC_ASECDIR, id);//SEC_ASECDIR=/mnt/secure/asec
611 snprintf(mountPoint, sizeof(mountPoint), “%s/%s”, Volume::ASECDIR, id);//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
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。