Fix for empty app-mounted directories (CifsManager, etc.) in Android 4.2

Search This thread
D

Deleted member 4845507

Guest
If the app is restricting itself to subdirectories of /storage, you can try:
Code:
mount -wo remount /
mkdir /mnt/cifs
ln -s /mnt/cifs /storage/cifs
mount -ro remount /
Then mount to /mnt/cifs, and I think it should be visible at /storage/cifs.

hey mkasick, says merged on gerrit. Next cm 10.1 nightly ? maybe ? btw thanks for your efforts fixing this issue. :good:

no on else tried or at least pointed out that was going to take a look at this issue. I really hope it works, google screwd things and you fixed.

good work!
 

Aerowinder

Senior Member
Aug 11, 2012
3,322
1,329
There are two 20120127 nightlies (at least for d2tmo). The newer one has this change merged. Tested and working.
 
D

Deleted member 4845507

Guest
Installed latest nightly on I9300, its working. I was able to mount under /mnt/obb/My_Directory. I can't mount under any other directory in /mnt.

Thank you, for me at least. It's fixed.
 
Last edited by a moderator:

lopez1_de

Senior Member
Jun 14, 2007
205
4
If the app is restricting itself to subdirectories of /storage, you can try:
Code:
mount -wo remount /
mkdir /mnt/cifs
ln -s /mnt/cifs /storage/cifs
mount -ro remount /
Then mount to /mnt/cifs, and I think it should be visible at /storage/cifs.

The cifs folder was created, but had insufficiend permissions. I set chmod 777 on /mnt/cifs but had no luck to get it running. After a reboot, the folder /mnt/cifs was gone. :confused: But /storage/emulated/0/cifs is still there and I can't delete it. :eek:


Is there any way to get md4.ko and nls_utf8.ko?
 
Last edited:
D

Deleted member 4845507

Guest
The cifs folder was created, but had insufficiend permissions. I set chmod 777 on /mnt/cifs but had no luck to get it running. After a reboot, the folder /mnt/cifs was gone. :confused: But /storage/emulated/0/cifs is still there and I can't delete it. :eek:

Is there any way to get md4.ko and nls_utf8.ko?

I dont know about your problem, but about folder going missing after reboot. I got a solution for you:

Copy these content and save as CHOOSE_A_NAME.sh on /etc/init.d:

#!/system/bin/sh
#
# Create and Mount Dir
#
sleep 70
su
mount -wo remount /
mkdir /mnt/cifs
mkdir /storage/cifs
chmod 777 /mnt/cifs
chmod 777 /storage/cifs
ln -s /mnt/cifs /storage/cifs
mount -ro remount /

Now everytime you reboot your phone those folders/permissions and links will be created. That sleep 70, i put that option there because i dont know if there's any side effect using mount command after system boot. So it will take 70 secs to run those commands.

Im not a specialist on android but im using this script to create my mount point under /mnt/obb/Cypher and it's working pretty well.
 
Last edited by a moderator:

ozgreg

Senior Member
Apr 25, 2010
336
37
Is there any way to get md4.ko and nls_utf8.ko?

You be better off installing a custom kernel with those modules (or compile your own) as I do not believe the standard CM 10.1 kernel has those modules..

---------- Post added at 10:29 AM ---------- Previous post was at 10:26 AM ----------

FYI any custom directory under /mnt will be deleted as /mnt is re-created during the init.d boot process. CM 10.1 has a custom init script that you should be able to use to re-create the missing directories..
 

lopez1_de

Senior Member
Jun 14, 2007
205
4
You be better off installing a custom kernel with those modules (or compile your own) as I do not believe the standard CM 10.1 kernel has those modules..

Thanks. But do I need this two modules? I'm a german user. I know for what I need UTF8, but I don't know for what reasons I used md4.ko before. And on CM9 & 10 both where placed in /system/lib/modules. I insmod them manually.

Is it supported to use another kernel with CM10.1?

Or should I better try to compile it for my own? I'm a Windows programmer. But where do I find the source code for 3.4.0-perf-g3186d08?

Thanks for all this great help. :good:
 
Last edited:

ozgreg

Senior Member
Apr 25, 2010
336
37
If you are using a N7 you can give motley Kernel a try as it has CIFS/UTF8, NFS, NTFS r/w, TUN - built-in so just flash the kernel and you will not need any additional modules.. I been using it with CM 10.1 and it has proven for me to be very rock solid via CIFS Manager..
 
  • Like
Reactions: xdadevnube

lopez1_de

Senior Member
Jun 14, 2007
205
4
If you are using a N7 you can give motley Kernel a try as it has CIFS/UTF8, NFS, NTFS r/w, TUN - built-in so just flash the kernel and you will not need any additional modules.. I been using it with CM 10.1 and it has proven for me to be very rock solid via CIFS Manager..

I found the kernel for my Nexus 4 and flashed it.
http://xdaforums.com/showthread.php?t=2021437

But had no luck with cifs again. I know that the share I use is ok, because "File Manager" can browse it. I will ask my questions in the motley thread now. Thanks.
 

moncojoe

New member
Jan 31, 2013
3
0
Fix for empty app-mounted directories

Any news from Google about this issue?
Also, great job on patching.
 
Last edited:

dw7017

New member
Feb 7, 2013
1
3
It would be really awesome if a fix or hack to this issue (empty directories if app is not launched before mounting) could be found without requiring a kernel patch.

I tried the debuggerd method supposedly used by StickMount and found that it didn't work: app still sees empty mount if its process is started after mount.

Btw, app sees mounts if its process is started before because mounts are propagated in that case. They are just not inherited on process creation due to how zygote spawn app processes and initializes their mounts.

I never understood how hacking debuggerd could work to fix this issue as this is not much different to me than running a shell script invoking adb shell in loopback mode (requires root), since debuggerd and adbd run with identical priviledges:

The debuggerd method worked well for my use case, which was simply to mount my home movie (samba) server at /sdcard/Movies/cifs. I am using a Nexus 4 running Faux kernel, but with stock Android 4.2.1 ROM (JOP40D). Here is my flow :

- Replace debuggerd with your own script that performs the mount then runs the renamed original debuggerd (debuggerd.bin below). Android starts the debuggerd service at boot, and at that point the mount will fail as wireless is not connected. However, Android will automatically restart debuggerd if it is killed. So we create another script that kills debuggerd and use a ScriptManager widget to call that script at the click of a button. Assuming wireless is connected, the mount will succeed when debuggerd is rerun by Android.

1. /system/bin/debuggerd
Code:
#!/system/bin/sh
/system/bin/mount_movies.sh
exec /system/bin/debuggerd.bin "$@"

2. /system/bin/mount_movies.sh
Code:
#!/system/bin/sh
/system/xbin/busybox umount /sdcard/Movies/cifs
/system/xbin/busybox mount -t cifs -o ip=<ip_address>,unc=\\\\<ip_address>\\shared,user=<username>,pass=<password> //<ip_address>/shared /sdcard/Movies/cifs

3. /system/xbin/kill_debuggerd.sh
Code:
#!/system/bin/sh
mypid=$(/system/xbin/busybox ps -o pid,comm | /system/xbin/busybox grep 'debuggerd' | /system/xbin/busybox awk 'NR == 1 {print $1}')
/system/bin/kill $mypid

I then used SManager app and added kill_debuggerd.sh to its favourites. Then used SMWidget to add a button to launcher that runs this script when clicking the button.

[There is nothing special about debuggerd, you can choose to replace any process that is started by init.rc and doesn't specify oneshot. The important thing is that Android will rerun your script when the its process is killed :)]
 

lopez1_de

Senior Member
Jun 14, 2007
205
4
The debuggerd method worked well for my use case, which was simply to mount my home movie (samba) server at /sdcard/Movies/cifs. I am using a Nexus 4 running Faux kernel, but with stock Android 4.2.1 ROM (JOP40D). Here is my flow :

- Replace debuggerd with your own script that performs the mount then runs the renamed original debuggerd (debuggerd.bin below). Android starts the debuggerd service at boot, and at that point the mount will fail as wireless is not connected. However, Android will automatically restart debuggerd if it is killed. So we create another script that kills debuggerd and use a ScriptManager widget to call that script at the click of a button. Assuming wireless is connected, the mount will succeed when debuggerd is rerun by Android.

1. /system/bin/debuggerd
Code:
#!/system/bin/sh
/system/bin/mount_movies.sh
exec /system/bin/debuggerd.bin "$@"

2. /system/bin/mount_movies.sh
Code:
#!/system/bin/sh
/system/xbin/busybox umount /sdcard/Movies/cifs
/system/xbin/busybox mount -t cifs -o ip=<ip_address>,unc=\\\\<ip_address>\\shared,user=<username>,pass=<password> //<ip_address>/shared /sdcard/Movies/cifs

3. /system/xbin/kill_debuggerd.sh
Code:
#!/system/bin/sh
mypid=$(/system/xbin/busybox ps -o pid,comm | /system/xbin/busybox grep 'debuggerd' | /system/xbin/busybox awk 'NR == 1 {print $1}')
/system/bin/kill $mypid

I then used SManager app and added kill_debuggerd.sh to its favourites. Then used SMWidget to add a button to launcher that runs this script when clicking the button.

[There is nothing special about debuggerd, you can choose to replace any process that is started by init.rc and doesn't specify oneshot. The important thing is that Android will rerun your script when the its process is killed :)]

Thanks! This is the first solution that works for me on default Cm10.1 Nexus 10. I invested so many hours to get it running. Without Cifs the tablet is almost useless for my personal use.

Too bad that the cyanogenmod team does not compile a nls_utf8.ko. :'( As a german user I need it for any file with a special character. And I have a lot of this files.

---------- Post added at 03:44 PM ---------- Previous post was at 03:20 PM ----------

But finally, the app has to be started before mounting again. I updated to today's version of CM. Never ending story. ;)
 

sjf53t8i

Member
Apr 2, 2011
22
2
- Replace debuggerd with your own script that performs the mount then runs the renamed original debuggerd (debuggerd.bin below). Android starts the debuggerd service at boot, and at that point the mount will fail as wireless is not connected. However, Android will automatically restart debuggerd if it is killed. So we create another script that kills debuggerd and use a ScriptManager widget to call that script at the click of a button. Assuming wireless is connected, the mount will succeed when debuggerd is rerun by Android.

1. /system/bin/debuggerd
Code:
#!/system/bin/sh
/system/bin/mount_movies.sh
exec /system/bin/debuggerd.bin "$@"

2. /system/bin/mount_movies.sh
Code:
#!/system/bin/sh
/system/xbin/busybox umount /sdcard/Movies/cifs
/system/xbin/busybox mount -t cifs -o ip=<ip_address>,unc=\\\\<ip_address>\\shared,user=<username>,pass=<password> //<ip_address>/shared /sdcard/Movies/cifs

3. /system/xbin/kill_debuggerd.sh
Code:
#!/system/bin/sh
mypid=$(/system/xbin/busybox ps -o pid,comm | /system/xbin/busybox grep 'debuggerd' | /system/xbin/busybox awk 'NR == 1 {print $1}')
/system/bin/kill $mypid

Tried it on Galaxy Nexus with stock Android 4.2.1. Process works and folder gets mounted but mount point content still isn't visible to other apps. But I do see the content in 'adb shell'.

Any other ideas or recommendations I could try?
 

bubbleguuum

Senior Member
Dec 23, 2010
7,016
2,745
Since Android 4.2.2 and the adb RSA change, it is not possible anymore to execute "adb shell mount...", as adb will always report the device as offline when connected to localhost. This breaks any script dealing with mounting, which worked previously fine.

I've opened an android issue for it. If you feel this is important, please star this issue.

It makes mounting without modified kernels even more difficult.

I tried to workaround it by replacing adb/adbd binaries of a 4.2.2 install by 4.2.1 binaries, but it didn't work (device still offline).
Maybe I missed something though.

It would be nice if a workaround could be found to restore the ability to run "adb shell" in loopback mode (eg on device).
 

Top Liked Posts

  • There are no posts matching your filters.
  • 43
    Android 4.2 breaks Dalvik-apps that mount file systems to be shared with other apps. This includes CifsManager, Mount Manager, essentially anything that mounts cifs shares, FUSE file sytems, etc. The symptom is that the mounted contents appear fine to app that peforms the mount operation (assuming the app itself provides the ability to browse the contents), but every other app only sees an empty directory at the mount point.

    It turns out that this problem is a side-effect of the approach used to implement multi-user storage in Android 4.2. I've explained the problem in detail in the commit log for a Gerrit issue we're reviewing for CyanogenMod 10.1 that addresses the problem:
    Zygote patch commit message said:
    Zygote: Restrict slave mountspace so Dalvik apps can mount system-wide volumes

    Android 4.2 implements multi-user storage using per-process mount namespaces. Originally, everything under "/" (the entire filesystem hierarchy) is marked as a recursive-slave mountspace for all zygote instances. This is done so that user-storage sandbox mounts under /storage/emulated are hidden from other apps and users.

    Unfortunately this means that any Dalvik app (actually, any program whose clone/fork ancestry includes a Dalvik zygote, which is everything except services spawned directly from init) cannot mount system-wide volumes. Thus, apps like CifsManager are effectively broken in Android 4.2, since its cifs mounts are only visible to the CifsManager app itself. All other apps see empty mountpoints instead of the mounted volume. Furthermore, Linux provides no provision for a process to "escape" a recursive-slave mountspace in versions prior to Linux 3.8 (setns syscall).

    Here, we restrict the slave mountspace to /storage (and, due to a possible kernel bug, /mnt/shell/emulated) so that Dalvik apps can mount system-wide volumes elsewhere (with appropriate permission, as in earlier versions of Android), while retaining full multi-user storage compatibility.

    This change requires that a tmpfs volume is mounted as /storage in init.rc. If this volume is unavailable, then Zygote falls back to the previous behavior of marking the entire filesystem hierarchy as slave. It also implicitly requires that EMULATED_STORAGE_TARGET is path-prefixed by (part of the subhierarchy of) ANDROID_STORAGE, which is the typical case.

    Ideally, any 4.2 ROM can provide support for CifsManager by applying a change to Dalvik, and a second change to the boot ramdisk's init.rc:
    Alternatively, ROMs that can't/prefer not to use a source-build Dalvik (libdvm), I've also provided a kernel patch that implements a similar workaround within the kernel. It also requires the above init.rc modification:
    With either of the above two fixes, CifsManager et al. should work when using a mountpoint outside /storage (and /mnt/shell/emulated). I'd recommend using "/mnt/cifs" or something similar. Attempting to mount inside /storage retains the previous behavior where the mount can not be seen by other apps.

    Note that ROMs only need one of the above two fixes, although they are compatible with each other and will function correctly if both are present. The Dalvik approach is preferred over the kernel workaround where feasible. Attached are the three patches referenced in the issues/commits.
    3
    Use /data/media/0

    And what if we want to overlay something inside the slave mountpoints? I'm trying to figure out how to overlay my obb folder in init.d.

    Code:
    mount -o bind /storage/sdcard1/obb /mnt/shell/emulated/0/Android/obb

    Short: Mount inside /data/media/0

    Long:
    1. You can't use for bind mountpoints inside /storage. Use some other place, like /.
    2. Mount inside /data/media/0

    Example for your example:
    Code:
    mount -o bind /mounts/sdcard1/obb /data/media/0/Android/obb

    This should make your files available inside /mnt/sdcard and all other virtual mountpoints. Android redirects this somehow.

    But I don't know if the games are also working with this. You need to test this.
    3
    You misunderstood. I have Stickmount, and it works fine.

    I want to carry cache games on the external flash drive with the command "bind mount", but I can not. All of the Nexus 7 with 4.2.2 can not move the cache. So I wanted to use the patch "dalvik.diff", just do not know how to install it, the forum did not find information on installation .diff on android. Or is it not help?

    I'm actually working on an app that should do just that.

    Google for FolderMount here on xda.
    3
    D
    Deleted member 4845507
    The cifs folder was created, but had insufficiend permissions. I set chmod 777 on /mnt/cifs but had no luck to get it running. After a reboot, the folder /mnt/cifs was gone. :confused: But /storage/emulated/0/cifs is still there and I can't delete it. :eek:

    Is there any way to get md4.ko and nls_utf8.ko?

    I dont know about your problem, but about folder going missing after reboot. I got a solution for you:

    Copy these content and save as CHOOSE_A_NAME.sh on /etc/init.d:

    #!/system/bin/sh
    #
    # Create and Mount Dir
    #
    sleep 70
    su
    mount -wo remount /
    mkdir /mnt/cifs
    mkdir /storage/cifs
    chmod 777 /mnt/cifs
    chmod 777 /storage/cifs
    ln -s /mnt/cifs /storage/cifs
    mount -ro remount /

    Now everytime you reboot your phone those folders/permissions and links will be created. That sleep 70, i put that option there because i dont know if there's any side effect using mount command after system boot. So it will take 70 secs to run those commands.

    Im not a specialist on android but im using this script to create my mount point under /mnt/obb/Cypher and it's working pretty well.
    3
    It would be really awesome if a fix or hack to this issue (empty directories if app is not launched before mounting) could be found without requiring a kernel patch.

    I tried the debuggerd method supposedly used by StickMount and found that it didn't work: app still sees empty mount if its process is started after mount.

    Btw, app sees mounts if its process is started before because mounts are propagated in that case. They are just not inherited on process creation due to how zygote spawn app processes and initializes their mounts.

    I never understood how hacking debuggerd could work to fix this issue as this is not much different to me than running a shell script invoking adb shell in loopback mode (requires root), since debuggerd and adbd run with identical priviledges:

    The debuggerd method worked well for my use case, which was simply to mount my home movie (samba) server at /sdcard/Movies/cifs. I am using a Nexus 4 running Faux kernel, but with stock Android 4.2.1 ROM (JOP40D). Here is my flow :

    - Replace debuggerd with your own script that performs the mount then runs the renamed original debuggerd (debuggerd.bin below). Android starts the debuggerd service at boot, and at that point the mount will fail as wireless is not connected. However, Android will automatically restart debuggerd if it is killed. So we create another script that kills debuggerd and use a ScriptManager widget to call that script at the click of a button. Assuming wireless is connected, the mount will succeed when debuggerd is rerun by Android.

    1. /system/bin/debuggerd
    Code:
    #!/system/bin/sh
    /system/bin/mount_movies.sh
    exec /system/bin/debuggerd.bin "$@"

    2. /system/bin/mount_movies.sh
    Code:
    #!/system/bin/sh
    /system/xbin/busybox umount /sdcard/Movies/cifs
    /system/xbin/busybox mount -t cifs -o ip=<ip_address>,unc=\\\\<ip_address>\\shared,user=<username>,pass=<password> //<ip_address>/shared /sdcard/Movies/cifs

    3. /system/xbin/kill_debuggerd.sh
    Code:
    #!/system/bin/sh
    mypid=$(/system/xbin/busybox ps -o pid,comm | /system/xbin/busybox grep 'debuggerd' | /system/xbin/busybox awk 'NR == 1 {print $1}')
    /system/bin/kill $mypid

    I then used SManager app and added kill_debuggerd.sh to its favourites. Then used SMWidget to add a button to launcher that runs this script when clicking the button.

    [There is nothing special about debuggerd, you can choose to replace any process that is started by init.rc and doesn't specify oneshot. The important thing is that Android will rerun your script when the its process is killed :)]