1 /* 2 * Copyright (C) 2014 John Crispin <blogic@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2.1 6 * as published by the Free Software Foundation 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #include <sys/mount.h> 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <unistd.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 21 #include <libubox/ulog.h> 22 23 #include "libfstools/libfstools.h" 24 #include "libfstools/volume.h" 25 #include "libfstools/common.h" 26 27 #define BUFLEN 64 28 29 /* 30 * Called in the early (PREINIT) stage, when we immediately need some writable 31 * filesystem. 32 */ 33 static int 34 start(int argc, char *argv[3]) 35 { 36 char dataparam[BUFLEN]; 37 char *dataname = "rootfs_data"; 38 struct volume *root; 39 struct volume *data; 40 struct stat s; 41 42 if (get_var_from_file("/proc/cmdline", "fstools_overlay_name", dataparam, sizeof(dataparam))) 43 dataname = dataparam; 44 45 data = volume_find(dataname); 46 47 if (!getenv("PREINIT") && stat("/tmp/.preinit", &s)) 48 return -1; 49 50 if (!data) { 51 root = volume_find("rootfs"); 52 volume_init(root); 53 if (argc < 3) 54 ULOG_NOTE("mounting /dev/root\n"); 55 else 56 ULOG_NOTE("mounting /dev/root with options %s\n", argv[2]); 57 58 /* 59 * If present, mount rootfs with passed options. 60 * Example F2FS filesystem with compress_algorithm option. 61 */ 62 mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 63 argc < 3 ? 0 : argv[2]); 64 } 65 66 /* Check for extroot config in rootfs before even trying rootfs_data */ 67 if (!mount_extroot("")) { 68 ULOG_NOTE("switched to extroot\n"); 69 return 0; 70 } 71 72 /* There isn't extroot, so just try to mount "rootfs_data" */ 73 volume_init(data); 74 switch (volume_identify(data)) { 75 case FS_NONE: 76 ULOG_WARN("no usable overlay filesystem found, using tmpfs overlay\n"); 77 return ramoverlay(); 78 79 case FS_DEADCODE: 80 /* 81 * Filesystem isn't ready yet and we are in the preinit, so we 82 * can't afford waiting for it. Use tmpfs for now and handle it 83 * properly in the "done" call. 84 */ 85 ULOG_NOTE("jffs2 not ready yet, using temporary tmpfs overlay\n"); 86 return ramoverlay(); 87 88 case FS_EXT4: 89 case FS_F2FS: 90 case FS_JFFS2: 91 case FS_UBIFS: 92 mount_overlay(data); 93 break; 94 95 case FS_SNAPSHOT: 96 mount_snapshot(data); 97 break; 98 } 99 100 return 0; 101 } 102 103 static int 104 stop(int argc, char *argv[1]) 105 { 106 if (!getenv("SHUTDOWN")) 107 return -1; 108 109 return 0; 110 } 111 112 /* 113 * Called at the end of init, it can wait for filesystem if needed. 114 */ 115 static int 116 done(int argc, char *argv[1]) 117 { 118 struct volume *v = volume_find("rootfs_data"); 119 120 if (!v) 121 return -1; 122 123 switch (volume_identify(v)) { 124 case FS_NONE: 125 case FS_DEADCODE: 126 return jffs2_switch(v); 127 128 case FS_EXT4: 129 case FS_F2FS: 130 case FS_JFFS2: 131 case FS_UBIFS: 132 fs_state_set("/overlay", FS_STATE_READY); 133 break; 134 } 135 136 return 0; 137 } 138 139 int main(int argc, char **argv) 140 { 141 if (argc < 2 || !strcmp(argv[1], "start")) 142 return start(argc, argv); 143 if (!strcmp(argv[1], "ram")) 144 return ramoverlay(); 145 if (!strcmp(argv[1], "stop")) 146 return stop(argc, argv); 147 if (!strcmp(argv[1], "done")) 148 return done(argc, argv); 149 return -1; 150 } 151
This page was automatically generated by LXR 0.3.1. • OpenWrt