if (data) { /* init_mount() requires a full page as fifth argument */
p = alloc_page(GFP_KERNEL); if (!p) return -ENOMEM;
data_page = page_address(p);
strscpy_pad(data_page, data, PAGE_SIZE);
}
ret = init_mount(name, "/root", fs, flags, data_page); if (ret) goto out;
scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)",
MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); if (root_fs_names)
num_fs = split_fs_names(fs_names, PAGE_SIZE); else
num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE);
retry: for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) { int err;
if (!*p) continue;
err = do_mount_root(name, p, flags, root_mount_data); switch (err) { case 0: goto out; case -EACCES: case -EINVAL: #ifdef CONFIG_BLOCK
init_flush_fput(); #endif continue;
} /* * Allow the user to distinguish between failed sys_open * and bad superblock on root device. * and give them a list of the available devices
*/
printk("VFS: Cannot open root device \"%s\" or %s: error %d\n",
pretty_name, b, err);
printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
printk_all_partitions();
if (root_fs_names)
num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE); if (!num_fs)
pr_err("Can't find any bdev filesystem to be used for mount!\n"); else {
pr_err("List of all bdev filesystems:\n"); for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1)
pr_err(" %s", p);
pr_err("\n");
}
panic("VFS: Unable to mount root fs on %s", b);
} if (!(flags & SB_RDONLY)) {
flags |= SB_RDONLY; goto retry;
}
printk("List of all partitions:\n");
printk_all_partitions();
printk("No filesystem could mount root, tried: "); for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1)
printk(" %s", p);
printk("\n");
panic("VFS: Unable to mount root fs on \"%s\" or %s", pretty_name, b);
out:
put_page(page);
}
if (nfs_root_data(&root_dev, &root_data)) goto fail;
/* * The server or network may not be ready, so try several * times. Stop after a few tries in case the client wants * to fall back to other boot methods.
*/
timeout = NFSROOT_TIMEOUT_MIN; for (try = 1; ; try++) { if (!do_mount_root(root_dev, "nfs", root_mountflags, root_data)) return; if (try > NFSROOT_RETRY_MAX) break;
/* Wait, in case the server refused us immediately */
ssleep(timeout);
timeout <<= 1; if (timeout > NFSROOT_TIMEOUT_MAX)
timeout = NFSROOT_TIMEOUT_MAX;
}
fail:
pr_err("VFS: Unable to mount root fs via NFS.\n");
} #else staticinlinevoid mount_nfs_root(void)
{
} #endif/* CONFIG_ROOT_NFS */
void __init mount_root(char *root_device_name)
{ switch (ROOT_DEV) { case Root_NFS:
mount_nfs_root(); break; case Root_CIFS:
mount_cifs_root(); break; case Root_Generic:
mount_root_generic(root_device_name, root_device_name,
root_mountflags); break; case 0: if (root_device_name && root_fs_names &&
mount_nodev_root(root_device_name) == 0) break;
fallthrough; default:
mount_block_root(root_device_name); break;
}
}
/* wait for any asynchronous scanning to complete */ staticvoid __init wait_for_root(char *root_device_name)
{
ktime_t end;
if (ROOT_DEV != 0) return;
pr_info("Waiting for root device %s...\n", root_device_name);
end = ktime_add_ms(ktime_get_raw(), root_wait);
while (!driver_probe_done() ||
early_lookup_bdev(root_device_name, &ROOT_DEV) < 0) {
msleep(5); if (root_wait > 0 && ktime_after(ktime_get_raw(), end)) break;
}
async_synchronize_full();
}
static dev_t __init parse_root_device(char *root_device_name)
{ int error;
dev_t dev;
if (!strncmp(root_device_name, "mtd", 3) ||
!strncmp(root_device_name, "ubi", 3)) return Root_Generic; if (strcmp(root_device_name, "/dev/nfs") == 0) return Root_NFS; if (strcmp(root_device_name, "/dev/cifs") == 0) return Root_CIFS; if (strcmp(root_device_name, "/dev/ram") == 0) return Root_RAM0;
error = early_lookup_bdev(root_device_name, &dev); if (error) { if (error == -EINVAL && root_wait) {
pr_err("Disabling rootwait; root= is invalid.\n");
root_wait = 0;
} return 0;
} return dev;
}
/* * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
*/ void __init prepare_namespace(void)
{ if (root_delay) {
printk(KERN_INFO "Waiting %d sec before mounting root device...\n",
root_delay);
ssleep(root_delay);
}
/* * wait for the known devices to complete their probing * * Note: this is a potential source of long boot delays. * For example, it is not atypical to wait 5 seconds here * for the touchpad of a laptop to initialize.
*/
wait_for_device_probe();
md_run_setup();
if (saved_root_name[0])
ROOT_DEV = parse_root_device(saved_root_name);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.