Patch that allows binfmt_misc to be compiled and used on embedded devices (such as Android) where the kernel itself can't trivially be changed. A brief explanation of the actual problem can be found below: <[machine]> so basically the mount point for binfmt_misc doesn't get made in the module on load, oh no, it gets made in the "main" kernel code, but only if the module is enabled when that code is compiled.. so if you compile /just/ the module later, no mount point... and well, if you use proc_mkdir to fix that, you end up with 2 /proc/sys's (the real one plus a shadow).. eventually i sussed this and then found sysctl stuff which allows you to define a table which becomes /proc/sys (and add to it) <[machine]> there is no way a normal user is going to bother with that This patch is based on kernel_2.6.35_nvidia_base as used by VegaComb. Patch is below: diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index fd0cc0b..97cb99b 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -60,6 +61,8 @@ static struct file_system_type bm_fs_type; static struct vfsmount *bm_mnt; static int entry_count; +static struct ctl_table_header *binfmt_misc_sysctl_header; + /* * Check if we support the binfmt * if we do, return the node, else NULL @@ -708,6 +711,31 @@ static int bm_get_sb(struct file_system_type *fs_type, return get_sb_single(fs_type, flags, data, bm_fill_super, mnt); } +static ctl_table binfmt_misc_table[] = { + { + } +}; + +static ctl_table binfmt_misc_fs_table[] = { + { + .procname = "binfmt_misc", + .mode = 0555, + .child = binfmt_misc_table + }, + { + } +}; + +static ctl_table binfmt_misc_root_table[] = { + { + .procname = "fs", + .mode = 0555, + .child = binfmt_misc_fs_table + }, + { + } +}; + static struct linux_binfmt misc_format = { .module = THIS_MODULE, .load_binary = load_misc_binary, @@ -722,17 +750,20 @@ static struct file_system_type bm_fs_type = { static int __init init_misc_binfmt(void) { + binfmt_misc_sysctl_header = register_sysctl_table(binfmt_misc_root_table); int err = register_filesystem(&bm_fs_type); if (!err) { err = insert_binfmt(&misc_format); - if (err) + if (err) { unregister_filesystem(&bm_fs_type); + } } return err; } static void __exit exit_misc_binfmt(void) { + unregister_sysctl_table(binfmt_misc_sysctl_header); unregister_binfmt(&misc_format); unregister_filesystem(&bm_fs_type); }