Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,732,072 Members 41,120 Now Online
XDA Developers Android and Mobile Development Forum

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

Tip us?
 
mkasick
Old
(Last edited by mkasick; 18th January 2013 at 10:48 PM.)
#1  
Recognized Developer - OP
Thanks Meter 826
Posts: 470
Join Date: Aug 2009
Default Fix for empty app-mounted directories (CifsManager, etc.) in Android 4.2

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:
Quote:
Originally Posted by Zygote patch commit message
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.
Attached Files
File Type: diff dalvik.diff - [Click for QR Code] (5.9 KB, 955 views)
File Type: diff initrc.diff - [Click for QR Code] (1.1 KB, 582 views)
File Type: diff kernel.diff - [Click for QR Code] (5.3 KB, 469 views)
The Following 44 Users Say Thank You to mkasick For This Useful Post: [ Click to Expand ]
 
wadimka
Old
#2  
Member
Thanks Meter 7
Posts: 45
Join Date: Aug 2011
So is it possible, for a noob like me, to get it working wihtout learning all that coding stuff etc.?
 
vorcers
Old
#3  
vorcers's Avatar
Senior Member
Thanks Meter 100
Posts: 130
Join Date: May 2012
I wanted to know if it really works - and it works!

I created a Nexus 7 wifi kernel and shared it. Thank you so much!
The Following User Says Thank You to vorcers For This Useful Post: [ Click to Expand ]
 
debully
Old
#4  
Senior Member
Thanks Meter 30
Posts: 531
Join Date: Dec 2005
Location: Worcester
Default Re: Fix for empty app-mounted directories (CifsManager, etc.) in Android 4.2

Can anyone noobproof this into a flash able zip?

PA is perfect for me except for no cifs.

Sent from my Nexus 7 using Tapatalk HD
 
timduru
Old
#5  
timduru's Avatar
Senior Member
Thanks Meter 8244
Posts: 1,528
Join Date: Apr 2011

 
DONATE TO ME
dalvik patch works great on TF101
I've integrated it into TeamEOS4 rom.
many thanks !
The Following 2 Users Say Thank You to timduru For This Useful Post: [ Click to Expand ]
 
bubbleguuum
Old
#6  
Senior Member
Thanks Meter 1346
Posts: 3,124
Join Date: Dec 2010
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:

Code:
setprop service.adb.tcp.port 5555
stop adbd
start adbd
adb connect localhost
adb shell mount ....
I've found a workaround that involves hijaking the obb directory by mounting whatever you want over /mnt/shell/emulated/obb. This directory is systematically bind mounted by the Zygote process in <external storage root>/Android/obb (see source code) when it spawns an app's process

Unfortunately this hack is not very usable because it has the side effect that any app expecting its data in the obb directory will not find it. And you can only mount one filesystem here.


Conclusion: with the new 4.2 multiuser support, Google made miserable all apps dealing with mounting.
The Following 2 Users Say Thank You to bubbleguuum For This Useful Post: [ Click to Expand ]
 
pjsports
Old
#7  
pjsports's Avatar
Member
Thanks Meter 514
Posts: 99
Join Date: Dec 2010
kernel patch works on acer picasso
many thanks !
JellyBean 4.3 for Acer A500

Paypal donation is disabled in my country, if you want to donate Click >> Donate to me
 
ayysir
Old
#8  
ayysir's Avatar
Recognized Developer
Thanks Meter 5846
Posts: 4,355
Join Date: Aug 2011
Location: Bronx, NY

 
DONATE TO ME
Added the patch on ramdisk and kernel level,

will compile and try this out!! thanks man!
Github
https://github.com/ayysir/


Projects:

AEI - Android Environment Installer - http://goo.gl/4TKdi

Kernel Build Script How To - http://goo.gl/admz2

AOSPA ROMS BELOW



 
xdadevnube
Old
#9  
xdadevnube's Avatar
Senior Member
Thanks Meter 90
Posts: 741
Join Date: Jun 2011
Just found this thread. This is seriously sweet! I had to roll back to 4.1.2 ROMs on the Nexus 7 because of the CIFS issue. Thanks for all the hard work creating this fix.
 
munhoz
Old
#10  
munhoz's Avatar
Senior Member
Thanks Meter 60
Posts: 143
Join Date: Sep 2012
Seems like it's Merged on CM 10.1, im right ? its says "Merged" on github. It happened today. Maybe on tomorrow nightly

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes