Optional: auto exec, run plugins from any noexec drive (no setup)

Recommended for a noexec drive. MPC cannot load a plugin from a drive mounted noexec (SSD, USB stick, SD card): it is listed but only shows Load Plugin. This makes the Synths folder of every noexec drive executable through a small boot-time service, with nothing to choose; the drives stay noexec. Tried on a Force with two USB sticks, a plugin loaded and survived a power cycle (not yet tried: an eject without its release command); 0.3.1 also starts after a reboot when an overlay is mounted on /usr (tried on a second Force, two reboots), and 0.3.2 finds drives with a space in the name. Apply updates an installed 0.3.0 or 0.3.1 in place. Replaces drive exec.

Device-verified 2026-10-14 on a Force Gen1 with two USB sticks: install, a plugin loaded from the stick, a power cycle, release. Not yet tried: the SSD, an eject without release. This replaces drive exec (../drive_exec, one named drive), which stays only so it can be uninstalled. Offline tests: tools/test_auto_exec.py.

What the device does (device-verified 2026-10-14, NOTES)

On a Force Gen1 the mount daemon edisksd mounts external drives nosuid,nodev,noexec (a USB stick showed it; the SSD report earlier). It has no config option for that, and MPC shares the shell's mount namespace. So the patch does not change how drives are mounted.

What the patch does

A systemd timer (5 s after boot, then every 5 s) looks at the mounts. For every drive mounted noexec directly under /media (not the internal storage) that has a Synths folder, it makes a private bind mount of that folder and remounts only it with exec. The drive stays noexec. A drive that is already executable, has no Synths folder, or already has a foreign mount there is left alone. Drives plugged in later are picked up on the next pass; a drive that is gone is cleaned up. No folder is ever created. A backup of the mount table and unit files goes to /data/mpc-vst-plugins/backups. MPC is not restarted; fstab and MPC.settings are not touched.

Use

scp tools/mpc_patch/auto_exec/auto-exec-patch.sh root@<device-ip>:/tmp/
ssh root@<device-ip>
sh /tmp/auto-exec-patch.sh status      # changes nothing
sh /tmp/auto-exec-patch.sh install     # asks you to type PATCH
sh /tmp/auto-exec-patch.sh verify      # does MPC itself see the executable folders; lists plugin folders
sh /tmp/auto-exec-patch.sh release     # before ejecting a drive
sh /tmp/auto-exec-patch.sh uninstall   # asks you to type REMOVE

Plugins go into a drive's Synths folder (the installer app: Create Synths folder, then Install to). The verify last line is VERIFY result=ok|not-installed|not-active|mpc-blind|mpc-stopped|no-plugins.

Limits

Files

src/ has the files that get installed; build_script.py embeds them into script.template.sh and writes auto-exec-patch.sh. Tests: sudo python3 tools/test_auto_exec.py (or DEX_IN_NS=1 unshare -rm --propagation private python3 tools/test_auto_exec.py as a normal user).

All device patches