/* Enumerate all disks to name devices. */ static void enumerate_disks (void) { struct grub_efidisk_data *devices; devices = make_devices (); if (! devices) return; name_devices (devices); free_devices (devices); }
/* Some utility functions to map GRUB devices with EFI devices. */ grub_efi_handle_t grub_efidisk_get_current_bdev_handle (void) { struct grub_efidisk_data *d; d = get_device_from_drive (current_drive); if (d == NULL) return NULL; if (current_drive == GRUB_INVALID_DRIVE) return NULL; if (current_drive == cdrom_drive) return d->handle; if (! (current_drive & 0x80)) return d->handle; /* If this is the whole disk, just return its own data. */ else if (current_partition == 0xFFFFFF) return d->handle; /* Otherwise, we must query the corresponding device to the firmware. */ else { struct grub_efidisk_data *devices; grub_efi_handle_t handle = 0; auto int find_partition (struct grub_efidisk_data *c); int find_partition (struct grub_efidisk_data *c) { grub_efi_hard_drive_device_path_t hd; grub_memcpy (&hd, c->last_device_path, sizeof (hd)); if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) && (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE) && (part_start == hd.partition_start)) { handle = c->handle; return 1; } return 0; } devices = make_devices (); iterate_child_devices (devices, d, find_partition); free_devices (devices); if (handle != 0) return handle; }
/* command line interface for the 'makedev' command */ void vinum_makedev(int argc, char *argv[], char *arg0[]) { make_devices(); }
int main(int argc, char *argv[], char *envp[]) { struct stat histstat; if (modfind(VINUMMOD) < 0) { /* need to load the vinum module */ if (kldload(VINUMMOD) < 0 || modfind(VINUMMOD) < 0) { perror(VINUMMOD ": Kernel module not available"); return 1; } } dateformat = getenv("VINUM_DATEFORMAT"); if (dateformat == NULL) dateformat = "%e %b %Y %H:%M:%S"; historyfile = getenv("VINUM_HISTORY"); if (historyfile == NULL) historyfile = DEFAULT_HISTORYFILE; if (stat(historyfile, &histstat) == 0) { /* history file exists */ if ((histstat.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "Vinum history file %s must be a regular file\n", historyfile); exit(1); } } else if ((errno != ENOENT) /* not "not there", */ &&(errno != EROFS)) { /* and not read-only file system */ fprintf(stderr, "Can't open %s: %s (%d)\n", historyfile, strerror(errno), errno); exit(1); } hist = fopen(historyfile, "a+"); if (hist != NULL) { timestamp(); fprintf(hist, "*** " VINUMMOD " started ***\n"); fflush(hist); /* before we start the daemon */ } superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open vinum superdevice */ if (superdev < 0) { /* no go */ if (errno == ENODEV) { /* not configured, */ superdev = open(VINUM_WRONGSUPERDEV_NAME, O_RDWR); /* do we have a debug mismatch? */ if (superdev >= 0) { /* yup! */ #if VINUMDEBUG fprintf(stderr, "This program is compiled with debug support, but the kernel module does\n" "not have debug support. This program must be matched with the kernel\n" "module. Please alter /usr/src/sbin/" VINUMMOD "/Makefile and remove\n" "the option -DVINUMDEBUG from the CFLAGS definition, or alternatively\n" "edit /usr/src/sys/modules/" VINUMMOD "/Makefile and add the option\n" "-DVINUMDEBUG to the CFLAGS definition. Then rebuild the component\n" "of your choice with 'make clean all install'. If you rebuild the kernel\n" "module, you must stop " VINUMMOD " and restart it\n"); #else fprintf(stderr, "This program is compiled without debug support, but the kernel module\n" "includes debug support. This program must be matched with the kernel\n" "module. Please alter /usr/src/sbin/" VINUMMOD "/Makefile and add\n" "the option -DVINUMDEBUG to the CFLAGS definition, or alternatively\n" "edit /usr/src/sys/modules/" VINUMMOD "/Makefile and remove the option\n" "-DVINUMDEBUG from the CFLAGS definition. Then rebuild the component\n" "of your choice with 'make clean all install'. If you rebuild the kernel\n" "module, you must stop " VINUMMOD " and restart it\n"); #endif return 1; } } else if (errno == ENOENT) /* we don't have our node, */ make_devices(); /* create them first */ if (superdev < 0) { perror("Can't open " VINUM_SUPERDEV_NAME); return 1; } } /* Check if the dæmon is running. If not, start it in the * background */ start_daemon(); if (argc > 1) { /* we have a command on the line */ if (setjmp(command_fail) != 0) /* long jumped out */ return -1; parseline(argc - 1, &argv[1]); /* do it */ } else { /* * Catch a possible race condition which could cause us to * longjmp() into nowhere if we receive a SIGINT in the next few * lines. */ if (setjmp(command_fail)) /* come back here on catastrophic failure */ return 1; setsigs(); /* set signal handler */ for (;;) { /* ugh */ char *c; int childstatus; /* from wait4 */ if (setjmp(command_fail) == 2) /* come back here on catastrophic failure */ fprintf(stderr, "*** interrupted ***\n"); /* interrupted */ while (wait4(-1, &childstatus, WNOHANG, NULL) > 0); /* wait for all dead children */ c = readline(VINUMMOD " -> "); /* get an input */ if (c == NULL) { /* EOF or error */ if (ferror(stdin)) { fprintf(stderr, "Can't read input: %s (%d)\n", strerror(errno), errno); return 1; } else { /* EOF */ printf("\n"); return 0; } } else if (*c) { /* got something there */ add_history(c); /* save it in the history */ strcpy(buffer, c); /* put it where we can munge it */ free(c); line++; /* count the lines */ tokens = tokenize(buffer, token); /* got something potentially worth parsing */ if (tokens) parseline(tokens, token); /* and do what he says */ } if (hist) fflush(hist); } } return 0; /* normal completion */ }
int main(int argc, char *argv[]) { char **cmdv, **args; char *cmdlines[3]; int i; const char *errmsg; int ret = 0; int cmdc; int fd; struct timeval now; char *mount_argv[] = {"mount_part", "rootfs", "/root"}; pid_t pid; int nandboot = 0; gettimeofday(&now, NULL); srand48(now.tv_usec ^ (now.tv_sec << 24)); /* Default parameters for anything init-like we execute */ init_argc = argc; init_argv = alloca((argc+1)*sizeof(char *)); memcpy(init_argv, argv, (argc+1)*sizeof(char *)); /* * omit /dev/console when generating initramfs, * so we create it dynamically */ if (access("/dev/console", O_RDWR)) { mknod("/dev/console", S_IFCHR|0644, makedev(5, 1)); } if ((fd = open("/dev/console", O_RDWR)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) { close(fd); } } mnt_procfs = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0; if (!mnt_procfs) { ret = 1; goto bail; } mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0; if (!mnt_sysfs) { ret = 1; goto bail; } /* Construct the effective kernel command line. The effective kernel command line consists of /arch.cmd, if it exists, /proc/cmdline, plus any arguments after an -- argument on the proper command line, in that order. */ ret = readfile("/arch.cmd", &cmdlines[0]); if (ret < 0) cmdlines[0] = ""; ret = readfile("/proc/cmdline", &cmdlines[1]); if (ret < 0) { fprintf(stderr, "%s: cannot read /proc/cmdline\n", progname); ret = 1; goto bail; } cmdlines[2] = NULL; /* Find an -- argument, and if so append to the command line */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--")) { i++; break; } } args = &argv[i]; /* Points either to first argument past -- or to the final NULL */ /* Count the number of arguments */ cmdc = split_cmdline(INT_MAX, NULL, argv[0], cmdlines, args); /* Actually generate the cmdline array */ cmdv = (char **)alloca((cmdc+1)*sizeof(char *)); if (split_cmdline(cmdc, cmdv, argv[0], cmdlines, args) != cmdc) { ret = 1; goto bail; } /* Debugging... */ dump_args(cmdc, cmdv); { const char * root_device_name = get_arg(cmdc, cmdv, "root="); if (strncmp(root_device_name, "/dev/mtdblock", strlen("/dev/mtdblock")) == 0) { nandboot = 1; printf("kinit: NAND mode, check online upgrade flag\n"); do_rootfs_OU(); } else { nandboot = 0; printf("kinit: None-NAND mode, ignore online upgrade flag\n"); } } /* Resume from suspend-to-disk, if appropriate */ /* If successful, does not return */ do_resume(cmdc, cmdv); /* Initialize networking, if applicable */ do_ipconfig(cmdc, cmdv); check_path("/root"); if (nandboot) { int index = 0; while (1) { char name[128]; snprintf(name, sizeof(name), "/sys/block/mtdblock%d", index); if (access(name, F_OK) == 0) { snprintf(name, sizeof(name), "/dev/mtdblock%d", index); create_dev(name, name_to_dev_t(name)); index++; } else { break; } } if((pid=fork())<0) fprintf(stderr, "fork error.\n"); else if(pid == 0) { if((ret = execve("/bin/mount_part", mount_argv, NULL)) <0) perror("excute mount_part error\n"); } if(waitpid(pid, NULL, 0) < 0) fprintf(stderr, "wait mount_part error.\n"); } else { do_mounts(cmdc, cmdv); } if (mnt_procfs) { umount2("/proc", 0); mnt_procfs = 0; } if (mnt_sysfs) { umount2("/sys", 0); mnt_sysfs = 0; } make_devices(); init_path = find_init("/root", get_arg(cmdc, cmdv, "init=")); if (!init_path) { fprintf(stderr, "%s: init not found!\n", progname); ret = 2; goto bail; } DEBUG(("kinit: init_path = %s, init=%s\n", init_path, get_arg(cmdc, cmdv, "init="))); init_argv[0] = strrchr(init_path, '/') + 1; errmsg = run_init("/root", "/dev/console", init_path, init_argv); /* If run_init returned, something went bad */ fprintf(stderr, "%s: %s: %s\n", progname, errmsg, strerror(errno)); ret = 2; goto bail; bail: if (mnt_procfs) umount2("/proc", 0); if (mnt_sysfs) umount2("/sys", 0); /* * If we get here, something bad probably happened, and the kernel * will most likely panic. Drain console output so the user can * figure out what happened. */ tcdrain(2); tcdrain(1); return ret; }