Want to make micro sdcard storage as EXTERNALSTORAGE in Jally bean MR1

1,894 views
Skip to first unread message

Maunik Shah

unread,
Jan 11, 2013, 5:13:51 AM1/11/13
to android-...@googlegroups.com
Hi Android frameworks developer,


I want to know that, Is it possible to make micro sdcard storage as EXTERNALSTORAGE in Jally bean MR1 release?

I'm facing problem when I dont have internal storage on device as EXTERNAL_STORAGE, all the application is gives me like "No External Storage found" and exits.

What is the solution in this situation?


Thanks,
Maunik

Jeff Sharkey

unread,
Jan 11, 2013, 1:48:01 PM1/11/13
to android-...@googlegroups.com
Yep, it's still possible for physical media to be the primary external
storage for a device. Here's an example of how this is setup for
Nexus S:

https://android.googlesource.com/device/samsung/crespo/+/master/init.herring.rc
https://android.googlesource.com/device/samsung/crespo/+/master/vold.fstab
https://android.googlesource.com/device/samsung/crespo/+/master/overlay/frameworks/base/core/res/res/xml/storage_list.xml

The errors you mentioned might be occurring if you've defined
EMULATED_STORAGE_SOURCE/TARGET, which are only used on multi-user
capable devices.

There are more details on external storage configuration here:

https://android.googlesource.com/platform/docs/source.android.com/+/master/src/tech/storage/index.md

Hope this helps.

j
> --
> You received this message because you are subscribed to the Google Groups
> "android-platform" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/android-platform/-/fxQYytFXkEgJ.
> To post to this group, send email to android-...@googlegroups.com.
> To unsubscribe from this group, send email to
> android-platfo...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/android-platform?hl=en.



--
Jeff Sharkey
jsha...@android.com

Jeff Sharkey

unread,
Jan 17, 2013, 2:33:28 PM1/17/13
to android-...@googlegroups.com
Could you confirm that your external storage path is correctly mounted
in an app process?

$ adb shell echo \$EXTERNAL_STORAGE
$ adb shell cat /proc/`pid android.process.media`/mountinfo

I'd also check this against the volumes that MountService thinks are mounted:

$ adb shell dumpsys mount

j

On Wed, Jan 16, 2013 at 5:54 PM, Keith <keith.p...@gmail.com> wrote:
> I tried an almost identical setup to this today and when I open Gallery2 I
> get the following logcat output:
>
> 01-02 05:12:26.765 W/ApplicationContext( 1156): Unable to create external
> cache directory
>
> And gallery reports that there is no external storage.
>
> This is work based on Jelly Bean 4.2. Can you provide any further insight
> as to why I would be getting these permission issue still?
>
> Thanks,
> --
> Keith
> https://groups.google.com/d/msg/android-platform/-/m4anepYGHBoJ.

Keith

unread,
Jan 17, 2013, 4:04:22 PM1/17/13
to android-...@googlegroups.com
Jeff,

One interesting thing to note is that I am running on a very slow FPGA-emulated system.  I'm wondering if there might be some race conditions or some kind of timeout.  I've pasted the output below as requested.  It looks like my media service is crashing and I've pasted the error at the bottom.  Do you know what the error means?

> $ adb shell echo \$EXTERNAL_STORAGE 
/storage/sdcard0

> $ adb shell cat /proc/`pid android.process.media`/mountinfo 

There is no process by that name. :-/  The zygote process mountinfo is shown below:
34 33 0:14 / /dev rw,nosuid,relatime - tmpfs tmpfs rw,mode=755
35 34 0:9 / /dev/pts rw,relatime - devpts devpts rw,mode=600
36 33 0:3 / /proc rw,relatime - proc proc rw
37 33 0:10 / /sys rw,relatime - sysfs sysfs rw
38 33 0:15 / /mnt/secure rw,relatime - tmpfs tmpfs rw,mode=700
39 33 0:16 / /mnt/asec rw,relatime - tmpfs tmpfs rw,mode=755,gid=1000
40 33 0:17 / /mnt/obb rw,relatime - tmpfs tmpfs rw,mode=755,gid=1000

> $ adb shell dumpsys mount 

$ dumpsys mount
  mObbMounts:

  mObbPathToStateMap:

  mVolumes:
    StorageVolume [mStorageId=65537 mPath=/storage/sdcard0 mDescriptionId=17040614 mPrimary=true mRemovable=true mEmulated=false mMtpReserveSpace=0 mAllowMassStorage=true mMaxFileSize=4294967296 mOwner=null]

  mConnection:
00:02:30 - SND -> {1 volume list}
00:02:30 - RCV <- {110 1 sdcard /storage/sdcard0 1}
00:02:32 - RMV <- {110 1 sdcard /storage/sdcard0 1}
00:02:32 - RCV <- {200 1 Volumes listed.}
00:02:32 - RMV <- {200 1 Volumes listed.}
00:02:32 - NDC Command {1 volume list} took too long (2728ms)
00:02:32 - SND -> {2 asec list}
00:02:33 - RCV <- {200 2 asec operation succeeded}
00:02:33 - RMV <- {200 2 asec operation succeeded}
00:02:33 - NDC Command {2 asec list} took too long (653ms)
00:03:16 - SND -> {3 volume mount /storage/sdcard0}
00:03:16 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 1 (Idle-Unmounted) to 3 (Checking)}
00:03:24 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 3 (Checking) to 4 (Mounted)}
00:03:24 - RCV <- {200 3 volume operation succeeded}
00:03:24 - RMV <- {200 3 volume operation succeeded}
00:03:24 - NDC Command {3 volume mount /storage/sdcard0} took too long (8326ms)
00:03:25 - SND -> {4 asec list}
00:03:28 - RCV <- {200 4 asec operation succeeded}
00:03:28 - RMV <- {200 4 asec operation succeeded}
00:03:28 - NDC Command {4 asec list} took too long (3573ms)

android.process.media crash output:

01-02 00:07:01.406 E/AndroidRuntime( 1237): FATAL EXCEPTION: main
01-02 00:07:01.406 E/AndroidRuntime( 1237): java.lang.RuntimeException: Unable to get provider com.android.providers.media.MediaProvider: java.lang.IllegalArgumentException: Can't obtain external volume ID for external volume.
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.installProvider(ActivityThread.java:4820)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.installContentProviders(ActivityThread.java:4430)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4372)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.access$1300(ActivityThread.java:141)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1294)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.os.Looper.loop(Looper.java:137)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.main(ActivityThread.java:5039)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at java.lang.reflect.Method.invoke(Method.java:511)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at dalvik.system.NativeStart.main(Native Method)
01-02 00:07:01.406 E/AndroidRuntime( 1237): Caused by: java.lang.IllegalArgumentException: Can't obtain external volume ID for external volume.
01-02 00:07:01.406 E/AndroidRuntime( 1237): at com.android.providers.media.MediaProvider.attachVolume(MediaProvider.java:4968)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at com.android.providers.media.MediaProvider.onCreate(MediaProvider.java:580)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.content.ContentProvider.attachInfo(ContentProvider.java:1058)
01-02 00:07:01.406 E/AndroidRuntime( 1237): at android.app.ActivityThread.installProvider(ActivityThread.java:4817)
01-02 00:07:01.406 E/AndroidRuntime( 1237): ... 12 more
01-02 00:07:01.796 W/ActivityManager(  708): Process android.process.media has crashed too many times: killing!

Keith

unread,
Jan 22, 2013, 2:20:30 PM1/22/13
to android-...@googlegroups.com
Jeff,

I've been able to get the media service to stay resident now but the external storage is still not available for applications.  I can look at files on the command line now with "ls." It looks like either the ioctl to get the volume id is not being called or it is failing right away.  Have you seen something like this before?  I've put my relevant logcat info below.  I'm going to continue investigating how far I can get in the getFatVolumeId() call stack before it fails.

 Here's the proc filesystem's mountinfo from the media service:

$ adb shell cat /proc/`pid android.process.media`/mountinfo
34 33 0:14 / /dev rw,nosuid,relatime - tmpfs tmpfs rw,mode=755
35 34 0:9 / /dev/pts rw,relatime - devpts devpts rw,mode=600
36 33 0:3 / /proc rw,relatime - proc proc rw
37 33 0:10 / /sys rw,relatime - sysfs sysfs rw
38 33 0:15 / /mnt/secure rw,relatime - tmpfs tmpfs rw,mode=700
39 33 0:16 / /mnt/asec rw,relatime - tmpfs tmpfs rw,mode=755,gid=1000
40 33 0:17 / /mnt/obb rw,relatime - tmpfs tmpfs rw,mode=755,gid=1000

Here's the relevant (verbose) logcat output when I insert the SD card:

D(  105) Volume sdcard state changing 0 (No-Media) -> 2 (Pending)  (Vold)
D(  105) Volume sdcard state changing 2 (Pending) -> 1 (Idle-Unmounted)  (Vold)
I( 1596) onEvent:: raw= 605 Volume sdcard /storage/sdcard0 state changed from 0 (No-Media) to 2 (Pending) cooked =  605 Volume sdcard /storage/sdcard0 state changed from 0 (No-Media) to 2 (Pending)  (MountService)
I( 1596) notifyVolumeStateChange::removed  (MountService)
I( 1596) onEvent:: raw= 605 Volume sdcard /storage/sdcard0 state changed from 2 (Pending) to 1 (Idle-Unmounted) cooked =  605 Volume sdcard /storage/sdcard0 state changed from 2 (Pending) to 1 (Idle-Unmounted)  (MountService)
I( 1596) notifyVolumeStateChange::removed  (MountService)
I( 1596) updating volume state for media bad removal nofs and unmountable  (MountService)
D( 1596) volume state changed for /storage/sdcard0 (removed -> unmounted)  (MountService)
I( 1596) Updating external media status from unmounted to unmounted  (PackageManager)
I( 1656) Media {/storage/sdcard0} state changed from {removed} -> {unmounted}  (StorageNotification)
D( 1596) sendStorageIntent Intent { act=android.intent.action.MEDIA_UNMOUNTED dat=file:///storage/sdcard0 (has extras) } to UserHandle{-1}  (MountService)
I( 1596) onEvent:: raw= 630 Volume sdcard /storage/sdcard0 disk inserted (179:48) cooked =  630 Volume sdcard /storage/sdcard0 disk inserted (179:48)  (MountService)
I( 1596) doMountVolume: Mouting /storage/sdcard0  (MountService)
D(  105) volume shared /storage/sdcard0 ums  (VoldCmdListener)
D(  105) volume mount /storage/sdcard0  (VoldCmdListener)
D( 1995) action: android.intent.action.MEDIA_UNMOUNTED path: /storage/sdcard0  (MediaScannerReceiver)
I(  105) /dev/block/vold/179:49 being considered for volume sdcard  (Vold)
D(  105) Volume sdcard state changing 1 (Idle-Unmounted) -> 3 (Checking)  (Vold)
I( 1596) onEvent:: raw= 605 Volume sdcard /storage/sdcard0 state changed from 1 (Idle-Unmounted) to 3 (Checking) cooked =  605 Volume sdcard /storage/sdcard0 state changed from 1 (Idle-Unmounted) to 3 (Checking)  (MountService)
I( 1596) notifyVolumeStateChange::unmounted  (MountService)
I( 1596) updating volume state checking  (MountService)
D( 1596) volume state changed for /storage/sdcard0 (unmounted -> checking)  (MountService)
I(  105) ** /dev/block/vold/179:49  (/system/bin/fsck_msdos)
I(  105) ** Phase 1 - Read and Compare FATs  (/system/bin/fsck_msdos)
I(  105) Attempting to allocate 972 KB for FAT  (/system/bin/fsck_msdos)
D( 1596) sendStorageIntent Intent { act=android.intent.action.MEDIA_CHECKING dat=file:///storage/sdcard0 (has extras) } to UserHandle{-1}  (MountService)
I( 1656) Media {/storage/sdcard0} state changed from {unmounted} -> {checking}  (StorageNotification)
I(  105) Attempting to allocate 972 KB for FAT  (/system/bin/fsck_msdos)
I( 1656) Skipped 40 frames!  The application may be doing too much work on its main thread.  (Choreographer)
I(  105) ** Phase 2 - Check Cluster Chains  (/system/bin/fsck_msdos)
I(  105) ** Phase 3 - Checking Directories  (/system/bin/fsck_msdos)
I(  105) ** Phase 4 - Checking for Lost Files  (/system/bin/fsck_msdos)
I(  105) 5 files, 987324 free (246831 clusters)  (/system/bin/fsck_msdos)
I(  105) Filesystem check completed OK  (Vold)
I(  105) Device /dev/block/vold/179:49, target /storage/sdcard0 mounted @ /mnt/secure/staging  (Vold)
D(  105) Volume sdcard state changing 3 (Checking) -> 4 (Mounted)  (Vold)
I( 1596) onEvent:: raw= 605 Volume sdcard /storage/sdcard0 state changed from 3 (Checking) to 4 (Mounted) cooked =  605 Volume sdcard /storage/sdcard0 state changed from 3 (Checking) to 4 (Mounted)  (MountService)
I( 1596) notifyVolumeStateChange::checking  (MountService)
I( 1596) updating volume state mounted  (MountService)
I( 1596) Updating external media status from unmounted to mounted  (PackageManager)
D( 1596) volume state changed for /storage/sdcard0 (checking -> mounted)  (MountService)
D( 1596) sendStorageIntent Intent { act=android.intent.action.MEDIA_MOUNTED dat=file:///storage/sdcard0 (has extras) } to UserHandle{-1}  (MountService)
D( 1995) action: android.intent.action.MEDIA_MOUNTED path: /storage/sdcard0  (MediaScannerReceiver)
D(  105) asec list  (VoldCmdListener)
W( 1995) no database for scanned volume external  (MediaProvider)
I( 1656) Media {/storage/sdcard0} state changed from {checking} -> {mounted}  (StorageNotification)
E( 1995) Can't obtain external volume ID even though it's mounted.  (MediaProvider)
W( 1995) failed to open media database  (MediaScannerService)
I( 1596) No secure containers on sdcard  (PackageManager)
W( 1995) Error opening directory '/storage/sdcard0/', skipping: Permission denied.  (MediaScanner)
W( 1596) Unknown permission com.google.android.gallery3d.permission.PICASA_STORE in package com.android.dreams.phototable  (PackageManager)
V( 1995) pruneDeadThumbnailFiles... null  (MediaScanner)
V( 1995) /pruneDeadThumbnailFiles... null  (MediaScanner)
W( 1995) no database for scanned volume external  (MediaProvider)
W( 1596) Unknown permission com.google.android.googleapps.permission.GOOGLE_AUTH in package com.android.settings  (PackageManager)
W( 1596) Unknown permission com.google.android.googleapps.permission.GOOGLE_AUTH.mail in package com.android.contacts  (PackageManager)
W( 1596) Unknown permission android.permission.ADD_SYSTEM_SERVICE in package com.android.phone  (PackageManager)
W( 1596) Unknown permission com.android.smspush.WAPPUSH_MANAGER_BIND in package com.android.phone  (PackageManager)
W( 1596) Unknown permission com.google.android.googleapps.permission.GOOGLE_AUTH in package com.android.providers.calendar  (PackageManager)
W( 1596) Unknown permission com.google.android.googleapps.permission.GOOGLE_AUTH.cl in package com.android.providers.calendar  (PackageManager)
W( 1596) Unknown permission com.google.android.googleapps.permission.GOOGLE_AUTH.mail in package com.android.calendar  (PackageManager)
W( 1596) Not granting permission android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS to package com.android.browser (protectionLevel=2 flags=0x89be45)  (PackageManager)
D( 1596) GC_CONCURRENT freed 336K, 8% free 5661K/6112K, paused 92ms+127ms, total 1144ms  (dalvikvm)

Keith

unread,
Jan 22, 2013, 3:00:44 PM1/22/13
to android-...@googlegroups.com
I've verified that the "open" call in the JNI layer is failing.  I added some log output to the file utils JNI code:

01-02 19:48:39.867 W/FileUtils( 1198): GET FAT VOLUME Path=/storage/sdcard0
01-02 19:48:39.882 W/FileUtils( 1198): GET FAT VOLUME open result=-1
01-02 19:48:39.914 W/FileUtils( 1198): GET FAT VOLUME returning result=-1


Just to be sure I ran the commands you requested again:

$  adb shell echo \$EXTERNAL_STORAGE 
/storage/sdcard0

$ adb shell dumpsys mount
  mObbMounts:

  mObbPathToStateMap:

  mVolumes:
    StorageVolume [mStorageId=65537 mPath=/storage/sdcard0 mDescriptionId=17040614 mPrimary=true mRemovable=true mEmulated=false mMtpReserveSpace=0 mAllowMassStorage=true mMaxFileSize=4294967296 mOwner=null]

  mConnection:
19:42:07 - SND -> {1 volume list}
19:42:08 - RCV <- {110 1 sdcard /storage/sdcard0 0}
19:42:08 - RCV <- {200 1 Volumes listed.}
19:42:08 - RMV <- {110 1 sdcard /storage/sdcard0 0}
19:42:08 - RMV <- {200 1 Volumes listed.}
19:42:08 - SND -> {2 asec list}
19:42:08 - RCV <- {200 2 asec operation succeeded}
19:42:08 - RMV <- {200 2 asec operation succeeded}
19:48:28 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 0 (No-Media) to 2 (Pending)}
19:48:28 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 2 (Pending) to 1 (Idle-Unmounted)}
19:48:28 - RCV <- {630 Volume sdcard /storage/sdcard0 disk inserted (179:48)}
19:48:28 - SND -> {3 volume shared /storage/sdcard0 ums}
19:48:29 - RCV <- {212 3 Share disabled}
19:48:29 - SND -> {4 volume mount /storage/sdcard0}
19:48:29 - RMV <- {212 3 Share disabled}
19:48:29 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 1 (Idle-Unmounted) to 3 (Checking)}
19:48:35 - RCV <- {605 Volume sdcard /storage/sdcard0 state changed from 3 (Checking) to 4 (Mounted)}
19:48:35 - RCV <- {200 4 volume operation succeeded}
19:48:35 - RMV <- {200 4 volume operation succeeded}
19:48:35 - SND -> {5 asec list}
19:48:39 - RCV <- {200 5 asec operation succeeded}
19:48:39 - RMV <- {200 5 asec operation succeeded}

Pending requests:

Keith

unread,
Feb 27, 2013, 3:17:28 PM2/27/13
to android-...@googlegroups.com
Update on my status for anyone who cares about the topic of this thread:

We have discovered that in Jellybean, the Zygote process uses the unshare(CLONE_NEWNS) to create a private copy of the default mount namespace (a mount namespace is a kernel data structure that contains a linked list of filesystem mounts). What this means is that Zygote (and thus its children) inherit information about all mounts that have occurred in the system at the time the Zygote process is first cloned, but subsequently won't see any mount operations performed by other processes (such as the vold process) unless explicit steps are taken to configure "mount propagation," a Linux feature that allows limited, controlled sharing of mount operations between designated mount namespaces to be specified. The Jellybean init.rc file attempts to set up mount propagation for the entire root directory tree, by executing the command "mount rootfs rootfs / share rec" from within a process using the default mount namespace. However, this mount command silently fails due to the way that we boot Android on our system. Specifically, the fact that we mount the JB root filesystem at a subdirectory of the kernel tree, and then "hide" this fact by booting using chroot, rather than following the standard practice of mounting the JB root filesystem in the kernel's root directory, is causing this mount operation to fail. As a result of this failure, when the vold process, which uses the default mount namespace, mounts the external SD card to the /mnt/sdcard directory, this mount is not propagated into the mount namespace of Zygote or its children.

If we reconfigure to mount the Android rootfs at the kernel / directory, the "mount rootfs rootfs / share rec" runs successfully during start up, and the SD card shows up properly in the mount namespace of Zygote and its children.

Keith A. Prickett

unread,
Apr 22, 2013, 12:20:39 PM4/22/13
to android-...@googlegroups.com
Kevin,

We had a unique setup where we booted the Linux kernel from TFTP and then loaded Android onto an SD card in a subdirectory (i.e. "/android/....").  Most systems we have seen put Android in the top-level directory with no subdirectories (i.e. "/...").


--
Keith A. Prickett


On Thu, Apr 11, 2013 at 12:03 AM, 林晨滨 <nich...@gmail.com> wrote:
Hi Keith,

What do you mean "reconfigure to mount the Android rootfs at the kernel / directory"?
And how can I check the command "mount rootfs rootfs / share rec" success or failed? Is it a feature we need to enable some config in kernel?

I encounter the same issue while running processes don't get propagated on new mount operations.

Thanks,
Kevin


在 2013年2月28日星期四UTC+8上午4时17分28秒,Keith写道:
Update on my status for anyone who cares about the topic of this thread:

We have discovered that in Jellybean, the Zygote process uses the unshare(CLONE_NEWNS) to create a private copy of the default mount namespace (a mount namespace is a kernel data structure that contains a linked list of filesystem mounts). What this means is that Zygote (and thus its children) inherit information about all mounts that have occurred in the system at the time the Zygote process is first cloned, but subsequently won't see any mount operations performed by other processes (such as the vold process) unless explicit steps are taken to configure "mount propagation," a Linux feature that allows limited, controlled sharing of mount operations between designated mount namespaces to be specified. The Jellybean init.rc file attempts to set up mount propagation for the entire root directory tree, by executing the command "mount rootfs rootfs / share rec" from within a process using the default mount namespace. However, this mount command silently fails due to the way that we boot Android on our system. Specifically, the fact that we mount the JB root filesystem at a subdirectory of the kernel tree, and then "hide" this fact by booting using chroot, rather than following the standard practice of mounting the JB root filesystem in the kernel's root directory, is causing this mount operation to fail. As a result of this failure, when the vold process, which uses the default mount namespace, mounts the external SD card to the /mnt/sdcard directory, this mount is not propagated into the mount namespace of Zygote or its children.

If we reconfigure to mount the Android rootfs at the kernel / directory, the "mount rootfs rootfs / share rec" runs successfully during start up, and the SD card shows up properly in the mount namespace of Zygote and its children.



--
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/c_dG3O8xfHs/unsubscribe?hl=en.
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.
Reply all
Reply to author
Forward
0 new messages