~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/init/do_mounts_initrd.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <linux/unistd.h>
  3 #include <linux/kernel.h>
  4 #include <linux/fs.h>
  5 #include <linux/minix_fs.h>
  6 #include <linux/romfs_fs.h>
  7 #include <linux/initrd.h>
  8 #include <linux/sched.h>
  9 #include <linux/freezer.h>
 10 #include <linux/kmod.h>
 11 #include <uapi/linux/mount.h>
 12 
 13 #include "do_mounts.h"
 14 
 15 unsigned long initrd_start, initrd_end;
 16 int initrd_below_start_ok;
 17 static unsigned int real_root_dev;      /* do_proc_dointvec cannot handle kdev_t */
 18 static int __initdata mount_initrd = 1;
 19 
 20 phys_addr_t phys_initrd_start __initdata;
 21 unsigned long phys_initrd_size __initdata;
 22 
 23 #ifdef CONFIG_SYSCTL
 24 static struct ctl_table kern_do_mounts_initrd_table[] = {
 25         {
 26                 .procname       = "real-root-dev",
 27                 .data           = &real_root_dev,
 28                 .maxlen         = sizeof(int),
 29                 .mode           = 0644,
 30                 .proc_handler   = proc_dointvec,
 31         },
 32 };
 33 
 34 static __init int kernel_do_mounts_initrd_sysctls_init(void)
 35 {
 36         register_sysctl_init("kernel", kern_do_mounts_initrd_table);
 37         return 0;
 38 }
 39 late_initcall(kernel_do_mounts_initrd_sysctls_init);
 40 #endif /* CONFIG_SYSCTL */
 41 
 42 static int __init no_initrd(char *str)
 43 {
 44         mount_initrd = 0;
 45         return 1;
 46 }
 47 
 48 __setup("noinitrd", no_initrd);
 49 
 50 static int __init early_initrdmem(char *p)
 51 {
 52         phys_addr_t start;
 53         unsigned long size;
 54         char *endp;
 55 
 56         start = memparse(p, &endp);
 57         if (*endp == ',') {
 58                 size = memparse(endp + 1, NULL);
 59 
 60                 phys_initrd_start = start;
 61                 phys_initrd_size = size;
 62         }
 63         return 0;
 64 }
 65 early_param("initrdmem", early_initrdmem);
 66 
 67 static int __init early_initrd(char *p)
 68 {
 69         return early_initrdmem(p);
 70 }
 71 early_param("initrd", early_initrd);
 72 
 73 static int __init init_linuxrc(struct subprocess_info *info, struct cred *new)
 74 {
 75         ksys_unshare(CLONE_FS | CLONE_FILES);
 76         console_on_rootfs();
 77         /* move initrd over / and chdir/chroot in initrd root */
 78         init_chdir("/root");
 79         init_mount(".", "/", NULL, MS_MOVE, NULL);
 80         init_chroot(".");
 81         ksys_setsid();
 82         return 0;
 83 }
 84 
 85 static void __init handle_initrd(char *root_device_name)
 86 {
 87         struct subprocess_info *info;
 88         static char *argv[] = { "linuxrc", NULL, };
 89         extern char *envp_init[];
 90         int error;
 91 
 92         pr_warn("using deprecated initrd support, will be removed in 2021.\n");
 93 
 94         real_root_dev = new_encode_dev(ROOT_DEV);
 95         create_dev("/dev/root.old", Root_RAM0);
 96         /* mount initrd on rootfs' /root */
 97         mount_root_generic("/dev/root.old", root_device_name,
 98                            root_mountflags & ~MS_RDONLY);
 99         init_mkdir("/old", 0700);
100         init_chdir("/old");
101 
102         info = call_usermodehelper_setup("/linuxrc", argv, envp_init,
103                                          GFP_KERNEL, init_linuxrc, NULL, NULL);
104         if (!info)
105                 return;
106         call_usermodehelper_exec(info, UMH_WAIT_PROC|UMH_FREEZABLE);
107 
108         /* move initrd to rootfs' /old */
109         init_mount("..", ".", NULL, MS_MOVE, NULL);
110         /* switch root and cwd back to / of rootfs */
111         init_chroot("..");
112 
113         if (new_decode_dev(real_root_dev) == Root_RAM0) {
114                 init_chdir("/old");
115                 return;
116         }
117 
118         init_chdir("/");
119         ROOT_DEV = new_decode_dev(real_root_dev);
120         mount_root(root_device_name);
121 
122         printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
123         error = init_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
124         if (!error)
125                 printk("okay\n");
126         else {
127                 if (error == -ENOENT)
128                         printk("/initrd does not exist. Ignored.\n");
129                 else
130                         printk("failed\n");
131                 printk(KERN_NOTICE "Unmounting old root\n");
132                 init_umount("/old", MNT_DETACH);
133         }
134 }
135 
136 bool __init initrd_load(char *root_device_name)
137 {
138         if (mount_initrd) {
139                 create_dev("/dev/ram", Root_RAM0);
140                 /*
141                  * Load the initrd data into /dev/ram0. Execute it as initrd
142                  * unless /dev/ram0 is supposed to be our actual root device,
143                  * in that case the ram disk is just set up here, and gets
144                  * mounted in the normal path.
145                  */
146                 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
147                         init_unlink("/initrd.image");
148                         handle_initrd(root_device_name);
149                         return true;
150                 }
151         }
152         init_unlink("/initrd.image");
153         return false;
154 }
155 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php