// there should be some checks whether the action actually succeded int ensure_lagfix_mount_points(const RootInfo *info) { int bindopts; bindopts = get_bind_options(); if (strcmp(info->name,"DATA:")==0) { mount_block("DATA","/dev/block/mmcblk0p2","/dev/block/loop1","/data","/res/odata"); if (bindopts>0) { ensure_root_path_mounted("DATADATA:"); __system("mkdir -p /dbdata/.data/data"); __system("mkdir -p /data/data"); __system("mount -o bind /dbdata/.data/data /data/data"); } } else if (strcmp(info->name,"DATADATA:")==0) { mount_block("DBDATA","/dev/block/stl10","/dev/block/loop2","/dbdata","/res/odbdata"); } else if (strcmp(info->name,"CACHE:")==0) { mount_block("CACHE","/dev/block/stl11","/dev/block/loop3","/cache","/res/ocache"); } else { return 1; } return 0; }
/* * Run /linuxrc, for emulation of old-style initrd */ static int run_linuxrc(int argc, char *argv[], dev_t root_dev) { int root_fd, old_fd; pid_t pid; long realroot = Root_RAM0; const char *ramdisk_name = "/dev/ram0"; FILE *fp; dprintf("kinit: mounting initrd\n"); mkdir("/root", 0700); if (!mount_block(ramdisk_name, "/root", NULL, MS_VERBOSE, NULL)) return -errno; /* Write the current "real root device" out to procfs */ dprintf("kinit: real_root_dev = %#x\n", root_dev); fp = fopen("/proc/sys/kernel/real-root-dev", "w"); fprintf(fp, "%u", root_dev); fclose(fp); mkdir("/old", 0700); root_fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0); old_fd = open("/old", O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0); if (root_fd < 0 || old_fd < 0) return -errno; if (chdir("/root") || mount(".", "/", NULL, MS_MOVE, NULL) || chroot(".")) return -errno; pid = vfork(); if (pid == 0) { setsid(); /* Looks like linuxrc doesn't get the init environment or parameters. Weird, but so is the whole linuxrc bit. */ execl("/linuxrc", "linuxrc", NULL); _exit(255); } else if (pid > 0) { dprintf("kinit: Waiting for linuxrc to complete...\n"); while (waitpid(pid, NULL, 0) != pid) ; dprintf("kinit: linuxrc done\n"); } else { return -errno; } if (fchdir(old_fd) || mount("/", ".", NULL, MS_MOVE, NULL) || fchdir(root_fd) || chroot(".")) return -errno; close(root_fd); close(old_fd); getintfile("/proc/sys/kernel/real-root-dev", &realroot); /* If realroot is Root_RAM0, then the initrd did any necessary work */ if (realroot == Root_RAM0) { if (mount("/old", "/root", NULL, MS_MOVE, NULL)) return -errno; } else { mount_root(argc, argv, (dev_t) realroot, NULL); /* If /root/initrd exists, move the initrd there, otherwise discard */ if (!mount("/old", "/root/initrd", NULL, MS_MOVE, NULL)) { /* We're good */ } else { int olddev = open(ramdisk_name, O_RDWR); umount2("/old", MNT_DETACH); if (olddev < 0 || ioctl(olddev, BLKFLSBUF, (long)0) || close(olddev)) { fprintf(stderr, "%s: Cannot flush initrd contents\n", progname); } } } rmdir("/old"); return 0; }