Android4.2的多用户管理中关于SD卡的实现改动
2013-05-29 18:05
316 查看
http://zzqhost.com/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1_Android_%E4%BB%A3%E7%A0%81%E7%A0%94%E7%A9%B6_Android4.2%E7%9A%84%E5%A4%9A%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86%E4%B8%AD%E5%85%B3%E4%BA%8ESD%E5%8D%A1%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%94%B9%E5%8A%A8.html
1.
问题
2.
Android4.2中对SD卡Mount的实现
2.1.
在init.rc中创建挂载点路径,及定义环境变量
2.2.
进程内的不共享的挂载点
3.
多用户访问SD卡实现模式
4.
遗留问题
5.
最终答案
6.
参考链接
MediaServer不能访问这样的路径. /storage/emulated/0/
libstagefright中原先可以正常读写的SD卡路径,现在由于以上原因不能用了.
另外: 还有一个权限问题,本文不进行讨论,但它是现实存在的,由于它的存在,导致即使程序中写死实际的挂载点,它也会提示没有权限.
其中创建的两个如下目录
/mnt/shell/emulated/ 是实际要挂载sdcard的目录
/storage/emulated/ 是每个用户为它们自己挂载sdcard的目录.
SD卡实际挂载到的是 /mnt/shell/emulated/0, 其它的 /storage/emulated/legacy, /sdcard/, /mnt/sdcard/, /storage/emulated/legacy都是它的链接.
dalvik_system_Zygote.cpp中的mountEmulatedStorage()函数. 会在Zygote创建一个新的java进程时运行, 先应用 unshare , 然后再以 MS_BIND参数把 /mnt/shell/emulated/0 再挂载到 /storage/emulated/0 下. (dalvik/vm/native)
其中的0是用户ID, 计算方法是 UID/100000, 代码在 system/core/libcutils/multiuser.c中. 所以在这里的多用户,即是给每个用户一个UID段, 0 即为主用户. 新建的用户往后排. 它们拥有各自的 UID 段.
在Environment中通过一样的方法计算得到 external storage路径, 即 /storeage/emulated/0. (/frameworks/base/core/java/android/os)
在应用程序创建时,会创建一个它自己能访问的SD卡挂载点 /storeage/emulated/[userid].
Mediaserver等不是通过Zygote创建的native程序, 不会创建 /storage/emulated/* 挂载点,所以就不能直接访问应用程序传下来的SD路径.
adb shell 也不是通过 Zygote 来创建的, 也没有此挂载点, 所以不能访问 /storage/emulated/*
为什么MediaServer会没有读写 /storage/emulated/legacy/的权限呢?
为什么通过adb shell看不到 /storage/emulated/0 这个目录呢,即使它没有挂载也应该有一个空目录啊?
答案
文件 android4.2/dalvik/vm/Init.cpp 中的 initZygote() 函数
文件android4.2/dalvik/vm/native/dalvik_system_Zygote.cpp的 mountEmulatedStorage(uid_t uid, u4 mountMode)函数,上边已经说了,这里就不再说了.
在上述两个地方主要做了三件事
先调用了一个 unsahre(), 使本进程的mount点不与其它的进程共享.
再对目录 /storage/emulated/ 做了一个 tmpfs 的挂载. 请参考tmpfs是什么
然后又以参数MS_BIND调用了mount, 把 /mnt/shell/emulated/0 又挂载到了 /storage/emulated/0/下.
释疑
/mnt/shell/目录的权限是 700, 用户是shell, 一般的进程都不可能是这个用户,所以一般的进程都没有权限对它进行读写.
Android4.2的多用户管理中关于SD卡的实现改动
Android4.2的多用户管理中关于SD卡的实现改动1.
问题
2.
Android4.2中对SD卡Mount的实现
2.1.
在init.rc中创建挂载点路径,及定义环境变量
2.2.
进程内的不共享的挂载点
3.
多用户访问SD卡实现模式
4.
遗留问题
5.
最终答案
6.
参考链接
1. 问题
Android4.2中,通过类得到的SD卡路径类似 /storage/emulated/0 在adb shell中看不到,也不能访问.MediaServer不能访问这样的路径. /storage/emulated/0/
libstagefright中原先可以正常读写的SD卡路径,现在由于以上原因不能用了.
另外: 还有一个权限问题,本文不进行讨论,但它是现实存在的,由于它的存在,导致即使程序中写死实际的挂载点,它也会提示没有权限.
2. Android4.2中对SD卡Mount的实现
2.1. 在init.rc中创建挂载点路径,及定义环境变量
mkdir /mnt/shell/emulated 0700 shell shell mkdir /storage/emulated 0555 root root export EXTERNAL_STORAGE /storage/emulated/legacy export EMULATED_STORAGE_SOURCE /mnt/shell/emulated export EMULATED_STORAGE_TARGET /storage/emulated # Support legacy paths symlink /storage/emulated/legacy /sdcard symlink /storage/emulated/legacy /mnt/sdcard symlink /storage/emulated/legacy /storage/sdcard0 symlink /mnt/shell/emulated/0 /storage/emulated/legacy
其中创建的两个如下目录
/mnt/shell/emulated/ 是实际要挂载sdcard的目录
/storage/emulated/ 是每个用户为它们自己挂载sdcard的目录.
SD卡实际挂载到的是 /mnt/shell/emulated/0, 其它的 /storage/emulated/legacy, /sdcard/, /mnt/sdcard/, /storage/emulated/legacy都是它的链接.
2.2. 进程内的不共享的挂载点
linux 内核命名空间, 在Linux 2.6之后引入了一个新的技术 unshare, 它可以使某个应用程序创建的挂载点等不共享,只有自己可见.dalvik_system_Zygote.cpp中的mountEmulatedStorage()函数. 会在Zygote创建一个新的java进程时运行, 先应用 unshare , 然后再以 MS_BIND参数把 /mnt/shell/emulated/0 再挂载到 /storage/emulated/0 下. (dalvik/vm/native)
其中的0是用户ID, 计算方法是 UID/100000, 代码在 system/core/libcutils/multiuser.c中. 所以在这里的多用户,即是给每个用户一个UID段, 0 即为主用户. 新建的用户往后排. 它们拥有各自的 UID 段.
在Environment中通过一样的方法计算得到 external storage路径, 即 /storeage/emulated/0. (/frameworks/base/core/java/android/os)
3. 多用户访问SD卡实现模式
每个用户拥有各自的应用程序, 第二个用户想安装想同的应用时, 系统会进行模拟安装 (来源自网上介绍文章)在应用程序创建时,会创建一个它自己能访问的SD卡挂载点 /storeage/emulated/[userid].
Mediaserver等不是通过Zygote创建的native程序, 不会创建 /storage/emulated/* 挂载点,所以就不能直接访问应用程序传下来的SD路径.
adb shell 也不是通过 Zygote 来创建的, 也没有此挂载点, 所以不能访问 /storage/emulated/*
4. 遗留问题
应用程序创建的 /storage/emulated/0 路径(空路径,未挂载的目录) 为什么通过 adb shell 看不到呢, 通过什么手段隐藏的?5. 最终答案
在这里将要解答前面不知道的两个问题为什么MediaServer会没有读写 /storage/emulated/legacy/的权限呢?
为什么通过adb shell看不到 /storage/emulated/0 这个目录呢,即使它没有挂载也应该有一个空目录啊?
答案
文件 android4.2/dalvik/vm/Init.cpp 中的 initZygote() 函数
static bool initZygote() { /* zygote goes into its own process group */ setpgid(0,0); // See storage config details at http://source.android.com/tech/storage/ // Create private mount namespace shared by all children if (unshare(CLONE_NEWNS) == -1) { SLOGE("Failed to unshare(): %s", strerror(errno)); return -1; } // Mark rootfs as being a slave so that changes from default // namespace only flow into our children. if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) { SLOGE("Failed to mount() rootfs as MS_SLAVE: %s", strerror(errno)); return -1; } // Create a staging tmpfs that is shared by our children; they will // bind mount storage into their respective private namespaces, which // are isolated from each other. const char* target_base = getenv("EMULATED_STORAGE_TARGET"); if (target_base != NULL) { if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV, "uid=0,gid=1028,mode=0050") == -1) { SLOGE("Failed to mount tmpfs to %s: %s", target_base, strerror(errno)); return -1; } } return true; }
文件android4.2/dalvik/vm/native/dalvik_system_Zygote.cpp的 mountEmulatedStorage(uid_t uid, u4 mountMode)函数,上边已经说了,这里就不再说了.
在上述两个地方主要做了三件事
先调用了一个 unsahre(), 使本进程的mount点不与其它的进程共享.
再对目录 /storage/emulated/ 做了一个 tmpfs 的挂载. 请参考tmpfs是什么
然后又以参数MS_BIND调用了mount, 把 /mnt/shell/emulated/0 又挂载到了 /storage/emulated/0/下.
释疑
/mnt/shell/目录的权限是 700, 用户是shell, 一般的进程都不可能是这个用户,所以一般的进程都没有权限对它进行读写.
相关文章推荐
- Android4.2的多用户管理中关于SD卡的实现改动
- Android4.2的多用户管理中关于SD卡的实现改动
- Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)
- Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)
- Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)
- 关于android 4.2版本后的多用户目录结构分析(二)- /storage/sdcard0设定铃声失败
- Android项目之---ListView实现论坛管理效果
- Android 4.2 通过修改FrameWork源码实现动态隐藏导航栏,实现全屏
- dwr实现用户管理demo
- JSP系统开发学习之四关于用户登录界面的补充——通过request页面传值&wel.jsp的MVC的实现
- 关于google地图服务在android上的实现的几个链接
- android 成长日记 3.关于Activity的用户体验提升办法和使用技巧说明
- Android实现读取SD卡下所有TXT文件名并用listView显示出来的方法
- android开发关于标题栏的一些改动
- Android+PHP+Mysql实现用户反馈功能
- Android实现ListView异步加载图片+缓存+线程池管理
- 实现业务系统中的用户权限管理
- 关于Android写LOG日志到SD卡文件之microlog4android使用
- 实现业务系统中的用户权限管理--设计篇
- 关于LINUX的管理用户