• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/fstools/mount_root.c

  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