[Q] [REF] [Android 4.4] sdcard symlinks

136 posts
Thanks Meter: 29
By aguaz, Senior Member on 11th June 2014, 04:09 AM
Post Reply Subscribe to Thread Email Thread
I'm looking for a smooth way to use symlinks from/to both the emulated sdcard and an ext4 formatted external sdcard in order to easily redirect data between the two.
However the way those file systems are both mounted and linked on various locations in the directory tree isn't very straight forward:

Mount Points

The external sdcard gets mounted natively on /mnt/media_rw/sdcard1 ... and once again virtually with a fuse layer on top on /storage/sdcard1
root@cm-11:/ # mount | grep sdcard1
/dev/block/vold/179:33 on /mnt/media_rw/sdcard1 type ext4 (rw,dirsync,context=u:object_r:sdcard_external:s0,nosuid,nodev,noexec,noatime,data=ordered)
/dev/fuse on /storage/sdcard1 type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)

root@cm-11:/ # df -m | grep sdcard1
/dev/block/vold/179:33   14953       174     14627   1% /mnt/media_rw/sdcard1
/dev/fuse                14953       174     14627   1% /storage/sdcard1
The emulated sdcard (origin: /data/media/*) is virtually fuse mounted on /mnt/shell/emulated (and /storage/emulated/**)
root@cm-11:/ # mount | grep emulated | grep fuse                           
/dev/fuse on /mnt/shell/emulated type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)

/dev/fuse on /storage/emulated/0 type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)
/dev/fuse on /storage/emulated/0/Android/obb type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)
/dev/fuse on /storage/emulated/legacy type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)
/dev/fuse on /storage/emulated/legacy/Android/obb type fuse (rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other)

root@cm-11:/ # df -m | grep emulated | grep fuse                                       
/dev/fuse                 5465       164      5301   3% /mnt/shell/emulated

/dev/fuse                 5465       164      5301   3% /storage/emulated/0
/dev/fuse                 5465       164      5301   3% /storage/emulated/0/Android/obb
/dev/fuse                 5465       164      5301   3% /storage/emulated/legacy
/dev/fuse                 5465       164      5301   3% /storage/emulated/legacy/Android/obb


Existing symlinks pointing to sdcards:
/external_sd -> /storage/sdcard1
/mnt/external_sd -> /storage/sdcard1

/sdcard -> /storage/emulated/legacy
/mnt/sdcard -> /storage/emulated/legacy
/storage/sdcard0 -> /storage/emulated/legacy
/storage/emulated/legacy -> /mnt/shell/emulated/0

Symlink Creation

Fuse mount points don't allow for creation of symlinks:
root@cm-11:/ # ln -s /storage/sdcard0 /storage/sdcard1/link_to_sdcard0
ln: /storage/sdcard1/link_to_sdcard0: Function not implemented
But native mount points do:
root@cm-11:/ # ln -sv /storage/sdcard0 /mnt/media_rw/sdcard1/link_to_sdcard0
'/mnt/media_rw/sdcard1/link_to_sdcard0' -> '/storage/sdcard0'


drwx------		4 1023		1023		/mnt/media_rw
drwxr-xr-x		4 root		root		/mnt/media_rw/sdcard1**		# when mounted
drwx------		2 1023		1023		/mnt/media_rw/usbdisk		# when unmounted
drwxr-x--x		5 root		1028		/storage
drwxrwx--x		4 root		1028		/storage/sdcard1**		# when mounted
drwx------		2 root		root		/storage/usbdisk		# when unmounted

drwx------		3 shell		shell		/mnt/shell
drwxrwx--x		5 root		1028		/mnt/shell/emulated**		# only 0 populated (legacy, obb empty)
drwx------		2 shell   	shell		/mnt/shell/emulated		# when unmounted
drwxr-x--x		5 root		1028		/storage
dr-xr-xr-x 		2 root		root		/storage/emulated**


After applying these permission fixes to overcome external storage restrictions introduced in 4.4 the link becomes accessible in File Manager, but again only via the native mount point.

Storage Variables

Am I wrong assuming that apps rather use environment variables to determine storage paths than looking in the directory tree!? Well, obviously they point to the unwanted fuse mount points:
root@cm-11:/ # env | grep sdcard1

root@cm-11:/ # env | grep emulated


Here is some official information on how storage is used:

I've started messing around building a new ramdisk in order to gain control over the cards. Ideas so far are:
- remove fuse stuff from init.rc --> use bind mounts for the emulated sdcard?
- remove vold stuff from init.rc?
- setting up mount points manually in fstab
- changing variables to the native mount point in case of the external sdcard

Ideas for solutions causing the least headache?

/etc/init* script
/system/build.prop: persist.fuse_sdcard=false # emulated sdcard does not get mounted at all
Last edited by aguaz; 17th June 2014 at 04:27 AM. Reason: narrowing it down myself... :)
The Following User Says Thank You to aguaz For This Useful Post: [ View ]
9th September 2014, 12:47 AM |#2  
Thanks Meter: 18
I share your pain trying to get your head around how android 4.4 works.
The documentation is definately lacking...
Don't forget also that ALL shares are declared to the os through "framework-res.xml",
and this file is very pedantic with its "strings".
ie: the string-names are built-in. Things break if you change them.

In the end when I eventually got my head around it (sort of), it was easier to use the designed in methods to achieve/share what I wanted,
rather than try to modify android4.4 back to 4.1.

as my info cost me dozens of googling hours, and lots of experimentation, i'll add this hoping it will be useful....

Remember you actually can share: emulated storage, other internal storage, and plug-in usb storage, internally, and externally via mtp.
and it does work well.

The link you posted above contains nearly everything you need to get shares and mtp working nicely for you...

I needed this as well.
export PRIMARY_STORAGE /storage/emulated/legacy # RC note: gets around issues

I also had to relax/change the permissions to make it work properly:
mkdir /storage/emulated 0750 media_rw media_rw # RCmod: was 0555 root root

and here as well:
#External storage directories
mkdir /mnt/media_rw/sdcard1 0750 media_rw media_rw
mkdir /mnt/media_rw/sdcard2 0750 media_rw media_rw
mkdir /storage/usbdisk0 0750 media_rw media_rw

there were other things as well but hopefully you can use this as a starting point.
....and then there is Selinux
Last edited by Ri9000; 9th September 2014 at 01:42 AM. Reason: hope this will help
The Following User Says Thank You to Ri9000 For This Useful Post: [ View ]
11th August 2015, 02:16 AM |#3  
Junior Member
Thanks Meter: 0
So I was able to create a symlink to external sdcard on LG g3 running rooted stock kit Kat Rom. I successfully changed Groove's (formerly xboxmusic) offline storage to external sdcard.

The following command was successful in creating a link, but Groove was unable to download music to the directory presumably due to permissions on /mnt

cp -rp /data/media/0/Android/data/ /storage/external_sd
rm -r /data/media/0/Android/data/
ln -s /mnt/media_rw/external_sd/ /data/media/0/Android/data

After these commands, Groove was producing errors stating that there was not enough disk space. As said before, I believe this was due to it's lack of permissions to /mnt

Replacing the last command with the following worked and offline music is now downloaded to external sd card
ln -s /storage/external_sd/ /data/media/0/Android/data

Hope this helps.
Last edited by monkeyfncoconut; 12th August 2015 at 01:21 AM. Reason: autocorrect
Post Reply Subscribe to Thread

fuse, permissions, sdcard, symlink
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes