• 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 
 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