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 26 /* 27 * Called in the early (PREINIT) stage, when we immediately need some writable 28 * filesystem. 29 */ 30 static int 31 start(int argc, char *argv[3]) 32 { 33 struct volume *root; 34 struct volume *data = volume_find("rootfs_data"); 35 struct stat s; 36 37 if (!getenv("PREINIT") && stat("/tmp/.preinit", &s)) 38 return -1; 39 40 if (!data) { 41 root = volume_find("rootfs"); 42 volume_init(root); 43 if (argc < 3) 44 ULOG_NOTE("mounting /dev/root\n"); 45 else 46 ULOG_NOTE("mounting /dev/root with options %s\n", argv[2]); 47 48 /* 49 * If present, mount rootfs with passed options. 50 * Example F2FS filesystem with compress_algorithm option. 51 */ 52 mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 53 argc < 3 ? 0 : argv[2]); 54 } 55 56 /* Check for extroot config in rootfs before even trying rootfs_data */ 57 if (!mount_extroot("")) { 58 ULOG_NOTE("switched to extroot\n"); 59 return 0; 60 } 61 62 /* There isn't extroot, so just try to mount "rootfs_data" */ 63 volume_init(data); 64 switch (volume_identify(data)) { 65 case FS_NONE: 66 ULOG_WARN("no usable overlay filesystem found, using tmpfs overlay\n"); 67 return ramoverlay(); 68 69 case FS_DEADCODE: 70 /* 71 * Filesystem isn't ready yet and we are in the preinit, so we 72 * can't afford waiting for it. Use tmpfs for now and handle it 73 * properly in the "done" call. 74 */ 75 ULOG_NOTE("jffs2 not ready yet, using temporary tmpfs overlay\n"); 76 return ramoverlay(); 77 78 case FS_EXT4: 79 case FS_F2FS: 80 case FS_JFFS2: 81 case FS_UBIFS: 82 mount_overlay(data); 83 break; 84 85 case FS_SNAPSHOT: 86 mount_snapshot(data); 87 break; 88 } 89 90 return 0; 91 } 92 93 static int 94 stop(int argc, char *argv[1]) 95 { 96 if (!getenv("SHUTDOWN")) 97 return -1; 98 99 return 0; 100 } 101 102 /* 103 * Called at the end of init, it can wait for filesystem if needed. 104 */ 105 static int 106 done(int argc, char *argv[1]) 107 { 108 struct volume *v = volume_find("rootfs_data"); 109 110 if (!v) 111 return -1; 112 113 switch (volume_identify(v)) { 114 case FS_NONE: 115 case FS_DEADCODE: 116 return jffs2_switch(v); 117 118 case FS_EXT4: 119 case FS_F2FS: 120 case FS_JFFS2: 121 case FS_UBIFS: 122 fs_state_set("/overlay", FS_STATE_READY); 123 break; 124 } 125 126 return 0; 127 } 128 129 int main(int argc, char **argv) 130 { 131 if (argc < 2 || !strcmp(argv[1], "start")) 132 return start(argc, argv); 133 if (!strcmp(argv[1], "ram")) 134 return ramoverlay(); 135 if (!strcmp(argv[1], "stop")) 136 return stop(argc, argv); 137 if (!strcmp(argv[1], "done")) 138 return done(argc, argv); 139 return -1; 140 } 141
This page was automatically generated by LXR 0.3.1. • OpenWrt