[Android Q&A, Help & Troubleshooting] aguaz:
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

Links

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'

Permissions

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**

1015=sdcard_rw
1023=media_rw
1028=sdcard_r

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
EXTERNAL_SD=/storage/sdcard1
SECONDARY_STORAGE=/storage/sdcard1:/storage/usbdisk

root@cm-11:/ # env | grep emulated
EMULATED_STORAGE_SOURCE=/mnt/shell/emulated
EMULATED_STORAGE_TARGET=/storage/emulated
EXTERNAL_STORAGE=/storage/emulated/legacy

Solution?

Here is some official information on how storage is used: http://source.android.com/devices/tech/storage/config-example.html

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?

---

Notes:

/etc/init* script

/system/build.prop: persist.fuse_sdcard=false # emulated sdcard does not get mounted at all