1 #include <linux/module.h> 2 #include <linux/sched.h> 3 #include <linux/ctype.h> 4 #include <linux/fd.h> 5 #include <linux/tty.h> 6 #include <linux/suspend.h> 7 #include <linux/root_dev.h> 8 #include <linux/security.h> 9 #include <linux/delay.h> 10 #include <linux/mount.h> 11 12 #include <linux/nfs_fs.h> 13 #include <linux/nfs_fs_sb.h> 14 #include <linux/nfs_mount.h> 15 16 #include "do_mounts.h" 17 18 extern int get_filesystem_list(char * buf); 19 20 int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ 21 22 int root_mountflags = MS_RDONLY | MS_VERBOSE; 23 char * __initdata root_device_name; 24 static char __initdata saved_root_name[64]; 25 26 /* this is initialized in init/main.c */ 27 dev_t ROOT_DEV; 28 29 static int __init load_ramdisk(char *str) 30 { 31 rd_doload = simple_strtol(str,NULL,0) & 3; 32 return 1; 33 } 34 __setup("load_ramdisk=", load_ramdisk); 35 36 static int __init readonly(char *str) 37 { 38 if (*str) 39 return 0; 40 root_mountflags |= MS_RDONLY; 41 return 1; 42 } 43 44 static int __init readwrite(char *str) 45 { 46 if (*str) 47 return 0; 48 root_mountflags &= ~MS_RDONLY; 49 return 1; 50 } 51 52 __setup("ro", readonly); 53 __setup("rw", readwrite); 54 55 static dev_t try_name(char *name, int part) 56 { 57 char path[64]; 58 char buf[32]; 59 int range; 60 dev_t res; 61 char *s; 62 int len; 63 int fd; 64 unsigned int maj, min; 65 66 /* read device number from .../dev */ 67 68 sprintf(path, "/sys/block/%s/dev", name); 69 fd = sys_open(path, 0, 0); 70 if (fd < 0) 71 goto fail; 72 len = sys_read(fd, buf, 32); 73 sys_close(fd); 74 if (len <= 0 || len == 32 || buf[len - 1] != '\n') 75 goto fail; 76 buf[len - 1] = '\0'; 77 if (sscanf(buf, "%u:%u", &maj, &min) == 2) { 78 /* 79 * Try the %u:%u format -- see print_dev_t() 80 */ 81 res = MKDEV(maj, min); 82 if (maj != MAJOR(res) || min != MINOR(res)) 83 goto fail; 84 } else { 85 /* 86 * Nope. Try old-style "0321" 87 */ 88 res = new_decode_dev(simple_strtoul(buf, &s, 16)); 89 if (*s) 90 goto fail; 91 } 92 93 /* if it's there and we are not looking for a partition - that's it */ 94 if (!part) 95 return res; 96 97 /* otherwise read range from .../range */ 98 sprintf(path, "/sys/block/%s/range", name); 99 fd = sys_open(path, 0, 0); 100 if (fd < 0) 101 goto fail; 102 len = sys_read(fd, buf, 32); 103 sys_close(fd); 104 if (len <= 0 || len == 32 || buf[len - 1] != '\n') 105 goto fail; 106 buf[len - 1] = '\0'; 107 range = simple_strtoul(buf, &s, 10); 108 if (*s) 109 goto fail; 110 111 /* if partition is within range - we got it */ 112 if (part < range) 113 return res + part; 114 fail: 115 return 0; 116 } 117 118 /* 119 * Convert a name into device number. We accept the following variants: 120 * 121 * 1) device number in hexadecimal represents itself 122 * 2) /dev/nfs represents Root_NFS (0xff) 123 * 3) /dev/<disk_name> represents the device number of disk 124 * 4) /dev/<disk_name><decimal> represents the device number 125 * of partition - device number of disk plus the partition number 126 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is 127 * used when disk name of partitioned disk ends on a digit. 128 * 129 * If name doesn't have fall into the categories above, we return 0. 130 * Sysfs is used to check if something is a disk name - it has 131 * all known disks under bus/block/devices. If the disk name 132 * contains slashes, name of sysfs node has them replaced with 133 * bangs. try_name() does the actual checks, assuming that sysfs 134 * is mounted on rootfs /sys. 135 */ 136 137 dev_t name_to_dev_t(char *name) 138 { 139 char s[32]; 140 char *p; 141 dev_t res = 0; 142 int part; 143 144 #ifdef CONFIG_SYSFS 145 int mkdir_err = sys_mkdir("/sys", 0700); 146 if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) 147 goto out; 148 #endif 149 150 if (strncmp(name, "/dev/", 5) != 0) { 151 unsigned maj, min; 152 153 if (sscanf(name, "%u:%u", &maj, &min) == 2) { 154 res = MKDEV(maj, min); 155 if (maj != MAJOR(res) || min != MINOR(res)) 156 goto fail; 157 } else { 158 res = new_decode_dev(simple_strtoul(name, &p, 16)); 159 if (*p) 160 goto fail; 161 } 162 goto done; 163 } 164 name += 5; 165 res = Root_NFS; 166 if (strcmp(name, "nfs") == 0) 167 goto done; 168 res = Root_RAM0; 169 if (strcmp(name, "ram") == 0) 170 goto done; 171 172 if (strlen(name) > 31) 173 goto fail; 174 strcpy(s, name); 175 for (p = s; *p; p++) 176 if (*p == '/') 177 *p = '!'; 178 res = try_name(s, 0); 179 if (res) 180 goto done; 181 182 while (p > s && isdigit(p[-1])) 183 p--; 184 if (p == s || !*p || *p == '0') 185 goto fail; 186 part = simple_strtoul(p, NULL, 10); 187 *p = '\0'; 188 res = try_name(s, part); 189 if (res) 190 goto done; 191 192 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') 193 goto fail; 194 p[-1] = '\0'; 195 res = try_name(s, part); 196 done: 197 #ifdef CONFIG_SYSFS 198 sys_umount("/sys", 0); 199 out: 200 if (!mkdir_err) 201 sys_rmdir("/sys"); 202 #endif 203 return res; 204 fail: 205 res = 0; 206 goto done; 207 } 208 209 static int __init root_dev_setup(char *line) 210 { 211 strlcpy(saved_root_name, line, sizeof(saved_root_name)); 212 return 1; 213 } 214 215 __setup("root=", root_dev_setup); 216 217 static char * __initdata root_mount_data; 218 static int __init root_data_setup(char *str) 219 { 220 root_mount_data = str; 221 return 1; 222 } 223 224 static char * __initdata root_fs_names; 225 static int __init fs_names_setup(char *str) 226 { 227 root_fs_names = str; 228 return 1; 229 } 230 231 static unsigned int __initdata root_delay; 232 static int __init root_delay_setup(char *str) 233 { 234 root_delay = simple_strtoul(str, NULL, 0); 235 return 1; 236 } 237 238 __setup("rootflags=", root_data_setup); 239 __setup("rootfstype=", fs_names_setup); 240 __setup("rootdelay=", root_delay_setup); 241 242 static void __init get_fs_names(char *page) 243 { 244 char *s = page; 245 246 if (root_fs_names) { 247 strcpy(page, root_fs_names); 248 while (*s++) { 249 if (s[-1] == ',') 250 s[-1] = '\0'; 251 } 252 } else { 253 int len = get_filesystem_list(page); 254 char *p, *next; 255 256 page[len] = '\0'; 257 for (p = page-1; p; p = next) { 258 next = strchr(++p, '\n'); 259 if (*p++ != '\t') 260 continue; 261 while ((*s++ = *p++) != '\n') 262 ; 263 s[-1] = '\0'; 264 } 265 } 266 *s = '\0'; 267 } 268 269 static int __init do_mount_root(char *name, char *fs, int flags, void *data) 270 { 271 int err = sys_mount(name, "/root", fs, flags, data); 272 if (err) 273 return err; 274 275 sys_chdir("/root"); 276 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; 277 printk("VFS: Mounted root (%s filesystem)%s.\n", 278 current->fs->pwdmnt->mnt_sb->s_type->name, 279 current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 280 " readonly" : ""); 281 return 0; 282 } 283 284 void __init mount_block_root(char *name, int flags) 285 { 286 char *fs_names = __getname(); 287 char *p; 288 char b[BDEVNAME_SIZE]; 289 290 get_fs_names(fs_names); 291 retry: 292 for (p = fs_names; *p; p += strlen(p)+1) { 293 int err = do_mount_root(name, p, flags, root_mount_data); 294 switch (err) { 295 case 0: 296 goto out; 297 case -EACCES: 298 flags |= MS_RDONLY; 299 goto retry; 300 case -EINVAL: 301 continue; 302 } 303 /* 304 * Allow the user to distinguish between failed sys_open 305 * and bad superblock on root device. 306 */ 307 __bdevname(ROOT_DEV, b); 308 printk("VFS: Cannot open root device \"%s\" or %s\n", 309 root_device_name, b); 310 printk("Please append a correct \"root=\" boot option\n"); 311 312 panic("VFS: Unable to mount root fs on %s", b); 313 } 314 panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); 315 out: 316 putname(fs_names); 317 } 318 319 #ifdef CONFIG_ROOT_NFS 320 static int __init mount_nfs_root(void) 321 { 322 void *data = nfs_root_data(); 323 324 create_dev("/dev/root", ROOT_DEV, NULL); 325 if (data && 326 do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0) 327 return 1; 328 return 0; 329 } 330 #endif 331 332 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) 333 void __init change_floppy(char *fmt, ...) 334 { 335 struct termios termios; 336 char buf[80]; 337 char c; 338 int fd; 339 va_list args; 340 va_start(args, fmt); 341 vsprintf(buf, fmt, args); 342 va_end(args); 343 fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); 344 if (fd >= 0) { 345 sys_ioctl(fd, FDEJECT, 0); 346 sys_close(fd); 347 } 348 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); 349 fd = sys_open("/dev/console", O_RDWR, 0); 350 if (fd >= 0) { 351 sys_ioctl(fd, TCGETS, (long)&termios); 352 termios.c_lflag &= ~ICANON; 353 sys_ioctl(fd, TCSETSF, (long)&termios); 354 sys_read(fd, &c, 1); 355 termios.c_lflag |= ICANON; 356 sys_ioctl(fd, TCSETSF, (long)&termios); 357 sys_close(fd); 358 } 359 } 360 #endif 361 362 void __init mount_root(void) 363 { 364 #ifdef CONFIG_ROOT_NFS 365 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { 366 if (mount_nfs_root()) 367 return; 368 369 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); 370 ROOT_DEV = Root_FD0; 371 } 372 #endif 373 #ifdef CONFIG_BLK_DEV_FD 374 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { 375 /* rd_doload is 2 for a dual initrd/ramload setup */ 376 if (rd_doload==2) { 377 if (rd_load_disk(1)) { 378 ROOT_DEV = Root_RAM1; 379 root_device_name = NULL; 380 } 381 } else 382 change_floppy("root floppy"); 383 } 384 #endif 385 create_dev("/dev/root", ROOT_DEV, root_device_name); 386 mount_block_root("/dev/root", root_mountflags); 387 } 388 389 /* 390 * Prepare the namespace - decide what/where to mount, load ramdisks, etc. 391 */ 392 void __init prepare_namespace(void) 393 { 394 int is_floppy; 395 396 mount_devfs(); 397 398 if (root_delay) { 399 printk(KERN_INFO "Waiting %dsec before mounting root device...\n", 400 root_delay); 401 ssleep(root_delay); 402 } 403 404 md_run_setup(); 405 406 if (saved_root_name[0]) { 407 root_device_name = saved_root_name; 408 ROOT_DEV = name_to_dev_t(root_device_name); 409 if (strncmp(root_device_name, "/dev/", 5) == 0) 410 root_device_name += 5; 411 } 412 413 is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; 414 415 if (initrd_load()) 416 goto out; 417 418 if (is_floppy && rd_doload && rd_load_disk(0)) 419 ROOT_DEV = Root_RAM0; 420 421 mount_root(); 422 out: 423 umount_devfs("/dev"); 424 sys_mount(".", "/", NULL, MS_MOVE, NULL); 425 sys_chroot("."); 426 security_sb_post_mountroot(); 427 mount_devfs_fs (); 428 } 429 430