Merged revisions 10129-10142 via svnmerge from
[wvapps.git] / funfs / funfsmain.cc
blob7e680f4b03773e582a0fad09117ef397ddc7ca53
1 #include "wvfuse.h"
2 #include "funfs.h"
3 #include "cachefs.h"
5 #include <wvlogrcv.h>
6 #include <uniconfroot.h>
7 #include <wvistreamlist.h>
8 #include <wvstringlist.h>
9 #include <fileutils.h>
11 #include <signal.h>
12 #include <getopt.h>
14 static bool want_to_die = false;
15 static WvFuse* fuse;
16 #define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
18 static void fuse_unmount()
20 if (!fuse || !fuse->fs_unmounted)
21 system(getenv(FUSE_UMOUNT_CMD_ENV));
22 close(0);
23 delete fuse;
26 void sighandler_die(int signum)
28 want_to_die = true;
31 void sighandler_ignore(int signum)
35 void usage()
37 wvcon->print("\n");
38 wvcon->print("Usage: funfs <remote mount point> <local mount point> [options]\n"
39 "Supported options:\n"
40 "\t-d/--debug <1-9>\n"
41 "\t-h/--help\n"
42 "\t-k/--kernel-cache[=no] \tdefault: no\n"
43 "\t-m/--unmount[=no] \tdefault: yes\n"
44 "\t-p/--port <int>\n"
46 exit(99);
49 int main(int argc, char *argv[])
51 WvLog::LogLevel lvl = WvLog::Error;
52 signal(SIGTERM, sighandler_die);
53 signal(SIGHUP, sighandler_die);
54 signal(SIGINT, sighandler_die);
55 signal(SIGUSR1, sighandler_ignore);
56 signal(SIGPIPE, SIG_IGN);
58 fuse = NULL;
59 bool slave = false;
60 bool cache = false;
61 bool umount = true;
62 int port = 1337;
63 atexit(fuse_unmount);
65 char *remotempoint = NULL;
66 char *localmpoint = NULL;
68 while (1)
70 int option_index = 0;
71 static struct option long_options[] = {
72 {"help", 0, 0, 'h'},
73 {"debug", 1, 0, 'd'},
74 {"slave", 0, 0, 's'},
75 {"kernel-cache", 2, 0, 'k'},
76 {"port", 1, 0, 'p'},
77 {"unmount", 2, 0, 'm'},
78 {0, 0, 0, 0}
81 int opt = getopt_long(argc, argv, "d:hk::m::p:s", long_options, &option_index);
83 if (opt == -1)
84 break;
86 if (opt == '?' || opt == ':')
87 usage();
89 switch (opt)
91 case 'd':
93 int loglevel = atoi(optarg);
94 if (loglevel < 1 || loglevel > 9)
96 wvcon->print("%s: Invalid debug level.\n", argv[0]);
97 usage();
99 lvl = (WvLog::LogLevel)(loglevel - 1);
101 break;
103 case 'h':
104 usage();
105 break;
107 case 'k':
108 if (optarg)
110 cache = !strstr(optarg, "no");
112 else
113 cache = true;
114 break;
117 case 'p':
118 port = atoi(optarg);
119 if (!port || port < 1 || port > 65536)
121 wvcon->print("%s: Invalid port %s\n", argv[0], optarg);
122 usage();
125 case 's':
126 slave = true;
127 break;
129 case 'u':
130 if (optarg)
131 umount = !strstr(optarg, "no");
132 else
133 umount = true;
134 break;
136 default:
137 break;
141 if (argc - optind < 2 - !!slave)
143 usage();
145 else if (argc - optind > 2)
147 optind += 2;
148 wvcon->print("%s: Unrecognized paramater(s): ", argv[0]);
149 while (optind < argc)
150 wvcon->print("%s ", argv[optind++]);
151 wvcon->print("\n");
153 usage();
156 remotempoint = argv[optind++];
158 if (!slave)
160 localmpoint = argv[optind++];
162 if (umount)
163 system(WvString("fusermount -u %s 2>/dev/null", localmpoint));
165 const char *params[11];
166 int next = 0;
168 WvString strlvl(lvl);
169 WvString strport(port);
171 params[next++] = "fusermount";
172 if (cache)
173 params[next++] = "-c";
174 params[next++] = localmpoint;
175 params[next++] = argv[0];
176 params[next++] = remotempoint;
177 params[next++] = "--slave";
178 params[next++] = "--debug";
179 params[next++] = strlvl;
180 params[next++] = "--port";
181 params[next++] = strport;
182 params[next++] = NULL;
184 execvp("fusermount", (char* const*)params);
186 fprintf(stderr, "%s: fusermount: %s\n", argv[0], strerror(errno));
187 return errno;
190 wvcon->print("\n");
192 WvLogConsole logdisp(2, lvl);
194 WvStringList lst;
195 lst.split(remotempoint, ":", 2);
197 if (lst.count() != 2)
199 wvcon->print("funfs: Bad mount point %s: expected format 'host:/path'\n",
200 remotempoint);
201 return 10;
204 UniConfRoot cfg("temp");
206 UniConf funfscfg = cfg["FunFS"];
207 funfscfg["Hostname"].set(lst.popstr());
208 funfscfg["Remote Mount Point"].set(lst.popstr());
209 funfscfg["Port"].setint(port);
210 funfscfg["Local Mount Point"].set(localmpoint);
212 UniConf cachefscfg = cfg["CacheFS"];
213 cachefscfg["Cache Root"].set("cache");
214 cachefscfg["Cache Size"].setint(5 * 1024); // Megabytes
216 cachefscfg["DB Location"].set("%s/%s", cachefscfg["Cache Root"].get(),
217 getpid());
219 mkdirp(cachefscfg["DB Location"].get());
220 system(WvString("rm -f %s/*", cachefscfg["DB Location"].get()));
222 cachefscfg["Meta Root"].set("%s/meta/%s/%s", cachefscfg["Cache Root"].get(),
223 funfscfg["Hostname"].get(), funfscfg["Remote Mount Point"].get());
224 cachefscfg["Data Root"].set("%s/data/%s/%s", cachefscfg["Cache Root"].get(),
225 funfscfg["Hostname"].get(), funfscfg["Remote Mount Point"].get());
227 UniConf fusecfg = cfg["WvFuse"];
228 fusecfg["DB Location"].set(cachefscfg["DB Location"].get());
230 FunFS *funfs = new FunFS(funfscfg);
232 fuse = new WvFuse(new CacheFS(funfs, cachefscfg), fusecfg);
233 WvIStreamList::globallist.append(fuse, false);
235 while (fuse->isok() && funfs->isok() && !want_to_die)
237 WvIStreamList::globallist.select(-1);
240 WvIStreamList::globallist.zap();
241 system(WvString("rm -f %s/*", cachefscfg["DB Location"].get()));
242 rmdir(cachefscfg["DB Location"].get());
244 return 0;