diff --git a/fs/filesystems.c b/fs/filesystems.c index f2728a4a03a1..931925d6aeed 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -221,6 +221,25 @@ int __init get_filesystem_list(char *buf) return len; } +#ifdef CONFIG_EARLY_SERVICES +int get_filesystem_list_runtime(char *buf) +{ + int len = 0; + struct file_system_type *tmp; + + read_lock(&file_systems_lock); + tmp = file_systems; + while (tmp && len < PAGE_SIZE - 80) { + len += scnprintf(buf+len, PAGE_SIZE, "%s\t%s\n", + (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev", + tmp->name); + tmp = tmp->next; + } + read_unlock(&file_systems_lock); + return len; +} +#endif + #ifdef CONFIG_PROC_FS static int filesystems_proc_show(struct seq_file *m, void *v) { diff --git a/include/linux/fs.h b/include/linux/fs.h index a9556d1115ef..9948a8fdde3f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3357,6 +3357,7 @@ int proc_nr_dentry(struct ctl_table *table, int write, int proc_nr_inodes(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); int __init get_filesystem_list(char *buf); +int get_filesystem_list_runtime(char *buf); #define __FMODE_EXEC ((__force int) FMODE_EXEC) #define __FMODE_NONOTIFY ((__force int) FMODE_NONOTIFY) diff --git a/include/linux/init.h b/include/linux/init.h index f00665ba66fc..a55e03e9703b 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -133,7 +133,10 @@ extern unsigned int reset_devices; /* used by init/main.c */ void setup_arch(char **); void prepare_namespace(void); -void __init launch_early_services(void); +void launch_early_services(void); +#ifdef CONFIG_EARLY_SERVICES +int get_early_services_status(void); +#endif void __init load_default_modules(void); int __init init_rootfs(void); diff --git a/init/do_mounts.c b/init/do_mounts.c index fa23cf487f4e..f1645f4ece5e 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -43,10 +43,11 @@ static char * __initdata root_device_name; static char __initdata saved_root_name[64]; static int root_wait; #ifdef CONFIG_EARLY_SERVICES -static char saved_modem_name[64] __initdata; -static char saved_early_userspace[64] __initdata; +static char saved_modem_name[64]; +static char saved_early_userspace[64]; static char init_prog[128] = "/early_services/init_early"; static char *init_prog_argv[2] = { init_prog, NULL }; +static int es_status; /*1= es mount is success 0= es failed to run*/ #define EARLY_SERVICES_MOUNT_POINT "/early_services" #endif dev_t ROOT_DEV; @@ -383,6 +384,26 @@ static void __init get_fs_names(char *page) *s = '\0'; } +#ifdef CONFIG_EARLY_SERVICES +static void get_fs_names_runtime(char *page) +{ + char *s = page; + int len = get_filesystem_list_runtime(page); + char *p, *next; + + page[len] = '\0'; + + for (p = page-1; p; p = next) { + next = strnchr(++p, len, '\n'); + if (*p++ != '\t') + continue; + while ((*s++ = *p++) != '\n') + ; + s[-1] = '\0'; + } + *s = '\0'; +} +#endif static int __init do_mount_root(char *name, char *fs, int flags, void *data) { struct super_block *s; @@ -410,7 +431,7 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) return 0; } #ifdef CONFIG_EARLY_SERVICES -static int __init do_mount_part(char *name, char *fs, int flags, +static int do_mount_part(char *name, char *fs, int flags, void *data, char *mnt_point) { int err; @@ -590,14 +611,24 @@ void __init mount_root(void) } #ifdef CONFIG_EARLY_SERVICES -static int __init mount_partition(char *part_name, char *mnt_point) +int get_early_services_status(void) +{ + return es_status; +} + +static int mount_partition(char *part_name, char *mnt_point) { struct page *page = alloc_page(GFP_KERNEL); char *fs_names = page_address(page); char *p; int err = -EPERM; - get_fs_names(fs_names); + if (!part_name[0]) { + pr_err("Unknown partition\n"); + return -ENOENT; + } + + get_fs_names_runtime(fs_names); for (p = fs_names; *p; p += strlen(p)+1) { err = do_mount_part(part_name, p, root_mountflags, NULL, mnt_point); @@ -608,12 +639,11 @@ static int __init mount_partition(char *part_name, char *mnt_point) case -EINVAL: continue; } - printk_all_partitions(); return err; } return err; } -void __init launch_early_services(void) +void launch_early_services(void) { int rc = 0; @@ -622,14 +652,15 @@ void __init launch_early_services(void) if (!rc) { place_marker("Early Services Partition ready"); rc = call_usermodehelper(init_prog, init_prog_argv, NULL, 0); - if (!rc) + if (!rc) { + es_status = 1; pr_info("early_init launched\n"); - else + } else pr_err("early_init failed\n"); } } #else -void __init launch_early_services(void) { } +void launch_early_services(void) { } #endif /* * Prepare the namespace - decide what/where to mount, load ramdisks, etc. diff --git a/init/main.c b/init/main.c index aed0801c3197..22f1c5b9e8e5 100644 --- a/init/main.c +++ b/init/main.c @@ -96,6 +96,8 @@ #include #include +#include "do_mounts.h" + static int kernel_init(void *); extern void init_IRQ(void); @@ -1019,7 +1021,9 @@ static inline void mark_readonly(void) static int __ref kernel_init(void *unused) { int ret; - +#ifdef CONFIG_EARLY_SERVICES + int status = get_early_services_status(); +#endif kernel_init_freeable(); /* need to finish all async __init code before freeing the memory */ async_synchronize_full(); @@ -1032,6 +1036,14 @@ static int __ref kernel_init(void *unused) rcu_end_inkernel_boot(); place_marker("M - DRIVER Kernel Boot Done"); +#ifdef CONFIG_EARLY_SERVICES + if (status) { + struct kstat stat; + /* Wait for early services SE policy load completion signal */ + while (vfs_stat("/dev/sedone", &stat) != 0) + ; + } +#endif if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret)