add ubi flashing tool
[project/fstools.git] / libfstools / 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 <stdio.h>
16 #include <stdlib.h>
17
18 #include "../fs-state.h"
19
20 #include "volume.h"
21
22 int
23 backend_mount(char *name)
24 {
25 struct backend *b = find_backend(name);
26
27 if (!b || !b->mount)
28 return -1;
29
30 return b->mount();
31 }
32
33 static int
34 backend_info(char *name)
35 {
36 struct backend *b = find_backend(name);
37
38 if (!b || !b->info)
39 return -1;
40
41 return b->info();
42 }
43
44 static int
45 start(int argc, char **argv)
46 {
47 struct volume *v = volume_find("rootfs_data");
48
49 if (!getenv("PREINIT"))
50 return -1;
51
52 if (!v) {
53 v = volume_find("rootfs");
54 volume_init(v);
55 fprintf(stderr, "mounting /dev/root\n");
56 mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 0);
57 return 0;
58 }
59
60 extroot_prefix = "";
61 if (!backend_mount("extroot")) {
62 fprintf(stderr, "fs-state: switched to extroot\n");
63 return 0;
64 }
65
66 switch (volume_identify(v)) {
67 case FS_NONE:
68 case FS_DEADCODE:
69 return ramoverlay();
70
71 case FS_JFFS2:
72 backend_mount("overlay");
73 break;
74
75 case FS_SNAPSHOT:
76 backend_mount("snapshot");
77 break;
78 }
79
80 return 0;
81 }
82
83 static int
84 stop(int argc, char **argv)
85 {
86 if (!getenv("SHUTDOWN"))
87 return -1;
88
89 return 0;
90 }
91
92 static int
93 done(int argc, char **argv)
94 {
95 struct volume *v = volume_find("rootfs_data");
96
97 if (!v)
98 return -1;
99
100 switch (volume_identify(v)) {
101 case FS_NONE:
102 case FS_DEADCODE:
103 return jffs2_switch(argc, argv);
104 }
105
106 return 0;
107 }
108
109 static int
110 info(int argc, char **argv)
111 {
112 struct volume *v = volume_find("rootfs_data");
113
114 if (!v)
115 return -1;
116
117 switch (volume_identify(v)) {
118 case FS_SNAPSHOT:
119 backend_info("snapshot");
120 return 0;
121 }
122
123 return 0;
124 }
125
126 static struct backend start_backend = {
127 .name = "start",
128 .cli = start,
129 };
130 BACKEND(start_backend);
131
132 static struct backend stop_backend = {
133 .name = "stop",
134 .cli = stop,
135 };
136 BACKEND(stop_backend);
137
138 static struct backend done_backend = {
139 .name = "done",
140 .cli = done,
141 };
142 BACKEND(done_backend);
143
144 static struct backend info_backend = {
145 .name = "info",
146 .cli = info,
147 };
148 BACKEND(info_backend);