various updates
[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 "../fs-state.h"
19
20 #include "../driver/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);