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