@@ -111,6 +111,16 @@ public void executeInContainer(Context context, String rootfsDir, String command
111111 args .add ("-b" );
112112 args .add ("/sys" );
113113
114+ // ADFA-4435: Ansible strategy plugins use multiprocessing.Semaphore, which
115+ // needs a writable POSIX shared-memory mount. Android's /dev has no shm and
116+ // "-b /dev" shadows the guest's, so bind a writable host dir over /dev/shm
117+ // (a later, more specific bind overrides "-b /dev"). Without it the install
118+ // dies instantly: "Unable to use multiprocessing ... lack of access to /dev/shm".
119+ File prootShmHost = new File (context .getFilesDir (), "proot_shm" );
120+ if (!prootShmHost .exists ()) prootShmHost .mkdirs ();
121+ args .add ("-b" );
122+ args .add (prootShmHost .getCanonicalPath () + ":/dev/shm" );
123+
114124 File fakeProcDir = new File (canonicalRootfs , "proc" );
115125 File fUptime = new File (fakeProcDir , ".uptime" );
116126 File fVersion = new File (fakeProcDir , ".version" );
@@ -261,6 +271,16 @@ public void startInteractiveShell(Context context, String rootfsDir, OutputListe
261271 args .add ("-b" );
262272 args .add ("/sys" );
263273
274+ // ADFA-4435: Ansible strategy plugins use multiprocessing.Semaphore, which
275+ // needs a writable POSIX shared-memory mount. Android's /dev has no shm and
276+ // "-b /dev" shadows the guest's, so bind a writable host dir over /dev/shm
277+ // (a later, more specific bind overrides "-b /dev"). Without it the install
278+ // dies instantly: "Unable to use multiprocessing ... lack of access to /dev/shm".
279+ File prootShmHost = new File (context .getFilesDir (), "proot_shm" );
280+ if (!prootShmHost .exists ()) prootShmHost .mkdirs ();
281+ args .add ("-b" );
282+ args .add (prootShmHost .getCanonicalPath () + ":/dev/shm" );
283+
264284 File sdcard = android .os .Environment .getExternalStorageDirectory ();
265285 args .add ("-b" );
266286 args .add (sdcard .getAbsolutePath () + ":/sdcard" );
0 commit comments