Creation of emulated storage directory

727 views
Skip to first unread message

Roman Mazur

unread,
Sep 16, 2014, 3:10:32 AM9/16/14
to android-...@googlegroups.com
I'm trying to understand what a component is responsible for creation of /mnt/shell/emulated/{userId} directory. 
Sometimes this directory is not created after a new user is added. As a result we get Zygote crashing since it cannot mountEmulatedStorage().

Thanks!

Roman Mazur

unread,
Sep 17, 2014, 1:29:12 AM9/17/14
to android-...@googlegroups.com

So now I see that such directories are created by zygote (by a forked process) with fs_prepare_dir call.
And then it is mounted to /storage/emulated/{userId}.

However, sometimes fs_prepare_dir fails with an error message

cutils  : Failed to chmod(/mnt/shell/emulated/10, 0): No such file or directory 

Interestingly, chmod is always performed either after a corresponding directory is created with mkdir or if already exists (checked with lstat). Hence, failure with an error message mentioned above might indicate some multi-process issues (and this seems to be plausible since all these operations on directories are performed by forked processes).

However, all the directory operations (lstatmkdirchmod) are wrapped with TEMP_FAILURE_RETRYmacro, and I'm not sure whether it should save us from issues that might happen with concurrent access to directories from multiple processes...

Roman Mazur

unread,
Sep 19, 2014, 4:36:43 AM9/19/14
to android-...@googlegroups.com
Interestingly, all the application processes crash on a newly created user. This means that this directory existence is checked multiple times from different processes and attempts to create this directory (if they happen) are also done multiple times from multiple policies.

So all the processes are stuck in a situation when lstat or mkdir consistently gives false positive. 
Does anybody have toughts about such a situation?

Roman Mazur

unread,
Sep 22, 2014, 4:58:26 AM9/22/14
to android-...@googlegroups.com

I do not understand how but the device gets stuck in a situation where mkdir reports that directory is already created but it's really not.

shell@flo:/mnt/shell/emulated # ls -la
drwxrwx--x root     sdcard_r          2014-09-18 01:53 0
drwxrwx--x root     sdcard_r          2014-09-18 01:53 legacy
drwxrwx--x root     sdcard_r          2014-09-18 01:52 obb
shell@flo:/mnt/shell/emulated # mkdir 10
mkdir failed for 10, File exists
255|shell@flo:/mnt/shell/emulated # ls -la
drwxrwx--x root     sdcard_r          2014-09-18 01:53 0
drwxrwx--x root     sdcard_r          2014-09-18 01:53 legacy
drwxrwx--x root     sdcard_r          2014-09-18 01:52 obb

trevd ( Steve Jones )

unread,
Sep 22, 2014, 5:40:56 PM9/22/14
to android-...@googlegroups.com
Hi 

This looks interesting. Yours and others undrstanding may well be enhanced by looking at logcat and dmesg. I'd also check the mount points because IIRC the user storage
uses kernel namespaces that are uid dependent


thanks
trevd

Roman Mazur

unread,
Sep 23, 2014, 10:37:16 AM9/23/14
to android-...@googlegroups.com

I seem to have found what is the reason of such a state.

Android framework reuses user IDs. For example if you create a user with id 10, then remove it, this id will be used again after user is considered to be completely removed.
Completely removed means stopped by activity manager (processes are killed), all the data directories (/data/user/{id}/data/system/users/{id}/mnt/shell/emulated/{id}) are deleted.

However, sometimes there is a process left running for this user id 10 after user is removed. The process can be rather random. Once it was gallery3d, another time com.google.android.googlequicksearchbox:search, yet another time our own launcher app. But it seem to be an app the uses external storage. In bugreport logs I see it sometimes keeping an open file at/storage/emulated/10/ where our /mnt/shell/emulated/10 is bind mounted. But keeping an open file is not necessary. It's sufficient to have a bind mounted directory.

As soon as this process is killed, apps for a newly created user with id 10 can be started.

The interesting thing is that files opened by this process are marked as (deleted) in lsof output if they are located at /data/user/{id}. But files at /storage/emulated/{id} are not marked as deleted.

So, activity manager seems to be guilty for not killing a process for a stopped user or allowing this process to be started after user is stopped.


--
You received this message because you are subscribed to a topic in the Google Groups "android-platform" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/android-platform/8BbzoSd2rAI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to android-platfo...@googlegroups.com.
To post to this group, send email to android-...@googlegroups.com.
Visit this group at http://groups.google.com/group/android-platform.
For more options, visit https://groups.google.com/d/optout.



--
Best regards,
Roman Mazur 

Software engineer at Stanfy (http://stanfy.com.ua)
Skype: roman.mazur.f

Roman Mazur

unread,
Oct 21, 2014, 7:18:52 AM10/21/14
to android-...@googlegroups.com
To unsubscribe from this group and all its topics, send an email to android-platform+unsubscribe@googlegroups.com.
To post to this group, send email to android-platform@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages