00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifdef HAVE_CONFIG_H
00011 #include "config.h"
00012 #endif
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <fcntl.h>
00020 #include <libgen.h>
00021 #include <fuse/fuse.h>
00022 #ifdef HAVE_MYSQL_MYSQL_H
00023 #include <mysql/mysql.h>
00024 #endif
00025 #ifdef HAVE_MYSQL_H
00026 #include <mysql.h>
00027 #endif
00028 #include <pthread.h>
00029 #include <sys/stat.h>
00030
00031 #ifdef DEBUG
00032 #include <mcheck.h>
00033 #endif
00034 #include <stddef.h>
00035
00036 #include "mysqlfs.h"
00037 #include "query.h"
00038 #include "pool.h"
00039 #include "log.h"
00040
00042 static char *status_filename = ".status";
00043 static char *status_pathname = "/.status";
00044
00045 static int mysqlfs_getattr(const char *path, struct stat *stbuf)
00046 {
00047 int ret;
00048 MYSQL *dbconn;
00049
00050
00051 log_printf(LOG_D_CALL, "mysqlfs_getattr(\"%s\")\n", path);
00052
00053 memset(stbuf, 0, sizeof(struct stat));
00054
00055 if ((dbconn = pool_get()) == NULL)
00056 return -EMFILE;
00057
00058 ret = query_getattr(dbconn, path, stbuf);
00059
00060 if(ret){
00061 if (ret != -ENOENT)
00062 log_printf(LOG_ERROR, "Error: query_getattr()\n");
00063 pool_put(dbconn);
00064 return ret;
00065 }else{
00066 long inode = query_inode(dbconn, path);
00067 if(inode < 0){
00068 log_printf(LOG_ERROR, "Error: query_inode()\n");
00069 pool_put(dbconn);
00070 return inode;
00071 }
00072
00073 stbuf->st_size = query_size(dbconn, inode);
00074 }
00075
00076 pool_put(dbconn);
00077
00078 return ret;
00079 }
00080
00081 static int mysqlfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
00082 off_t offset, struct fuse_file_info *fi)
00083 {
00084 (void) offset;
00085 (void) fi;
00086 int ret;
00087 MYSQL *dbconn;
00088 long inode;
00089
00090 log_printf(LOG_D_CALL, "mysqlfs_readdir(\"%s\")\n", path);
00091
00092 if ((dbconn = pool_get()) == NULL)
00093 return -EMFILE;
00094
00095 inode = query_inode(dbconn, path);
00096 if(inode < 0){
00097 log_printf(LOG_ERROR, "Error: query_inode()\n");
00098 pool_put(dbconn);
00099 return inode;
00100 }
00101
00102
00103 filler(buf, ".", NULL, 0);
00104 filler(buf, "..", NULL, 0);
00105 if (0 == strcmp (path, "/"))
00106 filler(buf, status_filename, NULL, 0);
00107 else if (0 == strcmp (path, status_pathname))
00108 {
00109 char *stubs[] = {"txt","xml"};
00110 int i;
00111
00112 for (i = 0; i < (sizeof(stubs)/sizeof(stubs[0])); i++)
00113 filler(buf, stubs[i], NULL, 0);
00114 }
00115
00116 ret = query_readdir(dbconn, inode, buf, filler);
00117 pool_put(dbconn);
00118
00119 return 0;
00120 }
00121
00123 static int mysqlfs_mknod(const char *path, mode_t mode, dev_t rdev)
00124 {
00125 int ret;
00126 MYSQL *dbconn;
00127 long parent_inode;
00128 char dir_path[PATH_MAX];
00129
00130 log_printf(LOG_D_CALL, "mysqlfs_mknod(\"%s\", %o): %s\n", path, mode,
00131 S_ISREG(mode) ? "file" :
00132 S_ISDIR(mode) ? "directory" :
00133 S_ISLNK(mode) ? "symlink" :
00134 "other");
00135
00136 if(!(strlen(path) < PATH_MAX)){
00137 log_printf(LOG_ERROR, "Error: Filename too long\n");
00138 return -ENAMETOOLONG;
00139 }
00140 strncpy(dir_path, path, PATH_MAX);
00141 dirname(dir_path);
00142
00143 if ((dbconn = pool_get()) == NULL)
00144 return -EMFILE;
00145
00146 parent_inode = query_inode(dbconn, dir_path);
00147 if(parent_inode < 0){
00148 pool_put(dbconn);
00149 return -ENOENT;
00150 }
00151
00152 ret = query_mknod(dbconn, path, mode, rdev, parent_inode, S_ISREG(mode) || S_ISLNK(mode));
00153 if(ret < 0){
00154 pool_put(dbconn);
00155 return ret;
00156 }
00157
00158 pool_put(dbconn);
00159 return 0;
00160 }
00161
00162 static int mysqlfs_mkdir(const char *path, mode_t mode){
00163 int ret;
00164 MYSQL *dbconn;
00165 long inode;
00166 char dir_path[PATH_MAX];
00167
00168 log_printf(LOG_D_CALL, "mysqlfs_mkdir(\"%s\", 0%o)\n", path, mode);
00169
00170 if(!(strlen(path) < PATH_MAX)){
00171 log_printf(LOG_ERROR, "Error: Filename too long\n");
00172 return -ENAMETOOLONG;
00173 }
00174 strncpy(dir_path, path, PATH_MAX);
00175 dirname(dir_path);
00176
00177 if ((dbconn = pool_get()) == NULL)
00178 return -EMFILE;
00179
00180 inode = query_inode(dbconn, dir_path);
00181 if(inode < 0){
00182 pool_put(dbconn);
00183 return -ENOENT;
00184 }
00185
00186 ret = query_mkdir(dbconn, path, mode, inode);
00187 if(ret < 0){
00188 log_printf(LOG_ERROR, "Error: query_mkdir()\n");
00189 pool_put(dbconn);
00190 return ret;
00191 }
00192
00193 pool_put(dbconn);
00194 return 0;
00195 }
00196
00197 static int mysqlfs_unlink(const char *path)
00198 {
00199 int ret;
00200 long inode, parent, nlinks;
00201 char name[PATH_MAX];
00202 MYSQL *dbconn;
00203
00204 log_printf(LOG_D_CALL, "mysqlfs_unlink(\"%s\")\n", path);
00205
00206 if ((dbconn = pool_get()) == NULL)
00207 return -EMFILE;
00208
00209 ret = query_inode_full(dbconn, path, name, sizeof(name),
00210 &inode, &parent, &nlinks);
00211 if (ret < 0) {
00212 if (ret != -ENOENT)
00213 log_printf(LOG_ERROR, "Error: query_inode_full(%s): %s\n",
00214 path, strerror(ret));
00215 goto err_out;
00216 }
00217
00218 ret = query_rmdirentry(dbconn, name, parent);
00219 if (ret < 0) {
00220 log_printf(LOG_ERROR, "Error: query_rmdirentry()\n");
00221 goto err_out;
00222 }
00223
00224
00225
00226
00227
00228 if (nlinks > 1)
00229 return 0;
00230
00231 ret = query_set_deleted(dbconn, inode);
00232 if (ret < 0) {
00233 log_printf(LOG_ERROR, "Error: query_set_deleted()\n");
00234 goto err_out;
00235 }
00236
00237 ret = query_purge_deleted(dbconn, inode);
00238 if (ret < 0) {
00239 log_printf(LOG_ERROR, "Error: query_purge_deleted()\n");
00240 goto err_out;
00241 }
00242
00243 pool_put(dbconn);
00244
00245 return 0;
00246
00247 err_out:
00248 pool_put(dbconn);
00249 return ret;
00250 }
00251
00252 static int mysqlfs_chmod(const char* path, mode_t mode)
00253 {
00254 int ret;
00255 long inode;
00256 MYSQL *dbconn;
00257
00258 log_printf(LOG_D_CALL, "mysql_chmod(\"%s\", 0%3o)\n", path, mode);
00259
00260 if ((dbconn = pool_get()) == NULL)
00261 return -EMFILE;
00262
00263 inode = query_inode(dbconn, path);
00264 if (inode < 0) {
00265 pool_put(dbconn);
00266 return inode;
00267 }
00268
00269 ret = query_chmod(dbconn, inode, mode);
00270 if(ret){
00271 log_printf(LOG_ERROR, "Error: query_chmod()\n");
00272 pool_put(dbconn);
00273 return -EIO;
00274 }
00275
00276 pool_put(dbconn);
00277
00278 return ret;
00279 }
00280
00281 static int mysqlfs_chown(const char *path, uid_t uid, gid_t gid)
00282 {
00283 int ret;
00284 long inode;
00285 MYSQL *dbconn;
00286
00287 log_printf(LOG_D_CALL, "mysql_chown(\"%s\", %ld, %ld)\n", path, uid, gid);
00288
00289 if ((dbconn = pool_get()) == NULL)
00290 return -EMFILE;
00291
00292 inode = query_inode(dbconn, path);
00293 if (inode < 0) {
00294 pool_put(dbconn);
00295 return inode;
00296 }
00297
00298 ret = query_chown(dbconn, inode, uid, gid);
00299 if(ret){
00300 log_printf(LOG_ERROR, "Error: query_chown()\n");
00301 pool_put(dbconn);
00302 return -EIO;
00303 }
00304
00305 pool_put(dbconn);
00306
00307 return ret;
00308 }
00309
00310 static int mysqlfs_truncate(const char* path, off_t length)
00311 {
00312 int ret;
00313 MYSQL *dbconn;
00314
00315 log_printf(LOG_D_CALL, "mysql_truncate(\"%s\"): len=%lld\n", path, length);
00316
00317 if ((dbconn = pool_get()) == NULL)
00318 return -EMFILE;
00319
00320 ret = query_truncate(dbconn, path, length);
00321 if (ret < 0) {
00322 log_printf(LOG_ERROR, "Error: query_length()\n");
00323 pool_put(dbconn);
00324 return -EIO;
00325 }
00326
00327 pool_put(dbconn);
00328
00329 return 0;
00330 }
00331
00332 static int mysqlfs_utime(const char *path, struct utimbuf *time)
00333 {
00334 int ret;
00335 long inode;
00336 MYSQL *dbconn;
00337
00338 log_printf(LOG_D_CALL, "mysql_utime(\"%s\")\n", path);
00339
00340 if ((dbconn = pool_get()) == NULL)
00341 return -EMFILE;
00342
00343 inode = query_inode(dbconn, path);
00344 if (inode < 0) {
00345 pool_put(dbconn);
00346 return inode;
00347 }
00348
00349 ret = query_utime(dbconn, inode, time);
00350 if (ret < 0) {
00351 log_printf(LOG_ERROR, "Error: query_utime()\n");
00352 pool_put(dbconn);
00353 return -EIO;
00354 }
00355
00356 pool_put(dbconn);
00357
00358 return 0;
00359 }
00360
00361 static int mysqlfs_open(const char *path, struct fuse_file_info *fi)
00362 {
00363 MYSQL *dbconn;
00364 long inode;
00365 int ret;
00366
00367 log_printf(LOG_D_CALL, "mysqlfs_open(\"%s\")\n", path);
00368
00369 if ((dbconn = pool_get()) == NULL)
00370 return -EMFILE;
00371
00372 inode = query_inode(dbconn, path);
00373 if(inode < 0){
00374 pool_put(dbconn);
00375 return -ENOENT;
00376 }
00377
00378
00379 fi->fh = inode;
00380
00381 log_printf(LOG_D_OTHER, "inode(\"%s\") = %d\n", path, fi->fh);
00382
00383 ret = query_inuse_inc(dbconn, inode, 1);
00384 if (ret < 0) {
00385 pool_put(dbconn);
00386 return ret;
00387 }
00388
00389 pool_put(dbconn);
00390
00391 return 0;
00392 }
00393
00394 static int mysqlfs_read(const char *path, char *buf, size_t size, off_t offset,
00395 struct fuse_file_info *fi)
00396 {
00397 int ret;
00398 MYSQL *dbconn;
00399
00400 log_printf(LOG_D_CALL, "mysqlfs_read(\"%s\" %zu@%llu)\n", path, size, offset);
00401
00402 if ((dbconn = pool_get()) == NULL)
00403 return -EMFILE;
00404
00405 ret = query_read(dbconn, fi->fh, buf, size, offset);
00406 pool_put(dbconn);
00407
00408 return ret;
00409 }
00410
00411 static int mysqlfs_write(const char *path, const char *buf, size_t size,
00412 off_t offset, struct fuse_file_info *fi)
00413 {
00414 int ret;
00415 MYSQL *dbconn;
00416
00417 log_printf(LOG_D_CALL, "mysqlfs_write(\"%s\" %zu@%lld)\n", path, size, offset);
00418
00419 if ((dbconn = pool_get()) == NULL)
00420 return -EMFILE;
00421
00422 ret = query_write(dbconn, fi->fh, buf, size, offset);
00423 pool_put(dbconn);
00424
00425 return ret;
00426 }
00427
00428 static int mysqlfs_release(const char *path, struct fuse_file_info *fi)
00429 {
00430 int ret;
00431 MYSQL *dbconn;
00432
00433 log_printf(LOG_D_CALL, "mysqlfs_release(\"%s\")\n", path);
00434
00435 if ((dbconn = pool_get()) == NULL)
00436 return -EMFILE;
00437
00438 ret = query_inuse_inc(dbconn, fi->fh, -1);
00439 if (ret < 0) {
00440 pool_put(dbconn);
00441 return ret;
00442 }
00443
00444 ret = query_purge_deleted(dbconn, fi->fh);
00445 if (ret < 0) {
00446 pool_put(dbconn);
00447 return ret;
00448 }
00449
00450 pool_put(dbconn);
00451
00452 return 0;
00453 }
00454
00455 static int mysqlfs_link(const char *from, const char *to)
00456 {
00457 int ret;
00458 long inode, new_parent;
00459 MYSQL *dbconn;
00460 char *tmp, *name, esc_name[PATH_MAX * 2];
00461
00462 log_printf(LOG_D_CALL, "link(%s, %s)\n", from, to);
00463
00464 if ((dbconn = pool_get()) == NULL)
00465 return -EMFILE;
00466
00467 inode = query_inode(dbconn, from);
00468 if(inode < 0){
00469 pool_put(dbconn);
00470 return inode;
00471 }
00472
00473 tmp = strdup(to);
00474 name = dirname(tmp);
00475 new_parent = query_inode(dbconn, name);
00476 free(tmp);
00477 if (new_parent < 0) {
00478 pool_put(dbconn);
00479 return new_parent;
00480 }
00481
00482 tmp = strdup(to);
00483 name = basename(tmp);
00484 mysql_real_escape_string(dbconn, esc_name, name, strlen(name));
00485 free(tmp);
00486
00487 ret = query_mkdirentry(dbconn, inode, esc_name, new_parent);
00488 if(ret < 0){
00489 pool_put(dbconn);
00490 return ret;
00491 }
00492
00493 pool_put(dbconn);
00494
00495 return 0;
00496 }
00497
00498 static int mysqlfs_symlink(const char *from, const char *to)
00499 {
00500 int ret;
00501 int inode;
00502 MYSQL *dbconn;
00503
00504 log_printf(LOG_D_CALL, "%s(\"%s\" -> \"%s\")\n", __func__, from, to);
00505
00506 ret = mysqlfs_mknod(to, S_IFLNK | 0755, 0);
00507 if (ret < 0)
00508 return ret;
00509
00510 if ((dbconn = pool_get()) == NULL)
00511 return -EMFILE;
00512
00513 inode = query_inode(dbconn, to);
00514 if(inode < 0){
00515 pool_put(dbconn);
00516 return -ENOENT;
00517 }
00518
00519 ret = query_write(dbconn, inode, from, strlen(from), 0);
00520 if (ret > 0) ret = 0;
00521
00522 pool_put(dbconn);
00523
00524 return ret;
00525 }
00526
00527 static int mysqlfs_readlink(const char *path, char *buf, size_t size)
00528 {
00529 int ret;
00530 long inode;
00531 MYSQL *dbconn;
00532
00533 log_printf(LOG_D_CALL, "%s(\"%s\")\n", __func__, path);
00534
00535 if ((dbconn = pool_get()) == NULL)
00536 return -EMFILE;
00537
00538 inode = query_inode(dbconn, path);
00539 if(inode < 0){
00540 pool_put(dbconn);
00541 return -ENOENT;
00542 }
00543
00544 memset (buf, 0, size);
00545 ret = query_read(dbconn, inode, buf, size, 0);
00546 log_printf(LOG_DEBUG, "readlink(%s): %s [%zd -> %d]\n", path, buf, size, ret);
00547 pool_put(dbconn);
00548
00549 if (ret > 0) ret = 0;
00550 return ret;
00551 }
00552
00553 static int mysqlfs_rename(const char *from, const char *to)
00554 {
00555 int ret;
00556 MYSQL *dbconn;
00557
00558 log_printf(LOG_D_CALL, "%s(%s -> %s)\n", __func__, from, to);
00559
00560
00561 mysqlfs_unlink(to);
00562
00563 if ((dbconn = pool_get()) == NULL)
00564 return -EMFILE;
00565
00566 ret = query_rename(dbconn, from, to);
00567
00568 pool_put(dbconn);
00569
00570 return ret;
00571 }
00572
00574 static struct fuse_operations mysqlfs_oper = {
00575 .getattr = mysqlfs_getattr,
00576 .readdir = mysqlfs_readdir,
00577 .mknod = mysqlfs_mknod,
00578 .mkdir = mysqlfs_mkdir,
00579 .unlink = mysqlfs_unlink,
00580 .rmdir = mysqlfs_unlink,
00581 .chmod = mysqlfs_chmod,
00582 .chown = mysqlfs_chown,
00583 .truncate = mysqlfs_truncate,
00584 .utime = mysqlfs_utime,
00585 .open = mysqlfs_open,
00586 .read = mysqlfs_read,
00587 .write = mysqlfs_write,
00588 .release = mysqlfs_release,
00589 .link = mysqlfs_link,
00590 .symlink = mysqlfs_symlink,
00591 .readlink = mysqlfs_readlink,
00592 .rename = mysqlfs_rename,
00593 };
00594
00596 void usage(){
00597 fprintf(stderr,
00598 "usage: mysqlfs [opts] <mountpoint>\n\n");
00599 fprintf(stderr,
00600 " mysqlfs [-osocket=/tmp/mysql.sock] [-oport=####] -ohost=host -ouser=user -opassword=password "
00601 "-odatabase=database ./mountpoint\n");
00602 fprintf(stderr,
00603 " mysqlfs [-d] [-ologfile=filename] -ohost=host -ouser=user -opassword=password "
00604 "-odatabase=database ./mountpoint\n");
00605 fprintf(stderr,
00606 " mysqlfs [-mycnf_group=group_name] -ohost=host -ouser=user -opassword=password "
00607 "-odatabase=database ./mountpoint\n");
00608 fprintf(stderr, "\n(mimick mysql options)\n");
00609 fprintf(stderr,
00610 " mysqlfs --host=host --user=user --password=password --database=database ./mountpoint\n");
00611 fprintf(stderr,
00612 " mysqlfs -h host -u user --password=password -D database ./mountpoint\n");
00613 }
00614
00616 #define MYSQLFS_OPT_KEY(t, p, v) { t, offsetof(struct mysqlfs_opt, p), v }
00617
00619 enum
00620 {
00621 KEY_BACKGROUND,
00622 KEY_DEBUG_DNQ,
00623 KEY_HELP,
00624 KEY_VERSION,
00625 };
00626
00628 static struct fuse_opt mysqlfs_opts[] =
00629 {
00630 MYSQLFS_OPT_KEY( "background", bg, 1),
00631 MYSQLFS_OPT_KEY( "database=%s", db, 1),
00632 MYSQLFS_OPT_KEY("--database=%s", db, 1),
00633 MYSQLFS_OPT_KEY( "-D %s", db, 1),
00634 MYSQLFS_OPT_KEY( "fsck", fsck, 1),
00635 MYSQLFS_OPT_KEY( "fsck=%d", fsck, 1),
00636 MYSQLFS_OPT_KEY("--fsck=%d", fsck, 1),
00637 MYSQLFS_OPT_KEY("nofsck", fsck, 0),
00638 MYSQLFS_OPT_KEY( "host=%s", host, 0),
00639 MYSQLFS_OPT_KEY("--host=%s", host, 0),
00640 MYSQLFS_OPT_KEY( "-h %s", host, 0),
00641 MYSQLFS_OPT_KEY( "logfile=%s", logfile, 0),
00642 MYSQLFS_OPT_KEY("--logfile=%s", logfile, 0),
00643 MYSQLFS_OPT_KEY( "mycnf_group=%s", mycnf_group, 0),
00644 MYSQLFS_OPT_KEY("--mycnf_group=%s", mycnf_group, 0),
00645 MYSQLFS_OPT_KEY( "password=%s", passwd, 0),
00646 MYSQLFS_OPT_KEY("--password=%s", passwd, 0),
00647 MYSQLFS_OPT_KEY( "port=%d", port, 0),
00648 MYSQLFS_OPT_KEY("--port=%d", port, 0),
00649 MYSQLFS_OPT_KEY( "-P %d", port, 0),
00650 MYSQLFS_OPT_KEY( "socket=%s", socket, 0),
00651 MYSQLFS_OPT_KEY("--socket=%s", socket, 0),
00652 MYSQLFS_OPT_KEY( "-S %s", socket, 0),
00653 MYSQLFS_OPT_KEY( "user=%s", user, 0),
00654 MYSQLFS_OPT_KEY("--user=%s", user, 0),
00655 MYSQLFS_OPT_KEY( "-u %s", user, 0),
00656
00657 FUSE_OPT_KEY("debug-dnq", KEY_DEBUG_DNQ),
00658 FUSE_OPT_KEY("-v", KEY_VERSION),
00659 FUSE_OPT_KEY("--version", KEY_VERSION),
00660 FUSE_OPT_KEY("--help", KEY_HELP),
00661 FUSE_OPT_END
00662 };
00663
00664
00665
00666 static int mysqlfs_opt_proc(void *data, const char *arg, int key,
00667 struct fuse_args *outargs){
00668 struct mysqlfs_opt *opt = (struct mysqlfs_opt *) data;
00669
00670 switch (key)
00671 {
00672 case FUSE_OPT_KEY_OPT:
00673
00674
00675
00676 break;
00677
00678 case KEY_DEBUG_DNQ:
00679
00680
00681
00682
00683 fprintf (stderr, "DEBUG: Dump and Quit\n\n");
00684 fprintf (stderr, "connect: mysql://%s:%s@%s:%d/%s\n", opt->user, opt->passwd, opt->host, opt->port, opt->db);
00685 fprintf (stderr, "connect: sock://%s\n", opt->socket);
00686 fprintf (stderr, "fsck? %s\n", (opt->fsck ? "yes" : "no"));
00687 fprintf (stderr, "group: %s\n", opt->mycnf_group);
00688 fprintf (stderr, "pool: %d initial connections\n", opt->init_conns);
00689 fprintf (stderr, "pool: %d idling connections\n", opt->max_idling_conns);
00690 fprintf (stderr, "logfile: file://%s\n", opt->logfile);
00691 fprintf (stderr, "bg? %s (debug)\n\n", (opt->bg ? "yes" : "no"));
00692
00693 exit (2);
00694
00695 case KEY_HELP:
00696 usage ();
00697 exit (0);
00698
00699 case KEY_VERSION:
00700 fprintf (stderr, "%s-%s fuse-%2.1f\n\n", PACKAGE_TARNAME, PACKAGE_VERSION, ((double) FUSE_USE_VERSION)/10.0);
00701 exit (0);
00702
00703 default:
00704 fuse_opt_add_arg(outargs, arg);
00705 return 0;
00706 }
00707
00708 fuse_opt_add_arg(outargs, arg);
00709 return 0;
00710 }
00711
00715 int main(int argc, char *argv[])
00716 {
00717 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
00718 struct mysqlfs_opt opt = {
00719 .init_conns = 1,
00720 .max_idling_conns = 5,
00721 .mycnf_group = "mysqlfs",
00722 .logfile = "mysqlfs.log",
00723 };
00724
00725 log_file = stderr;
00726
00727 fuse_opt_parse(&args, &opt, mysqlfs_opts, mysqlfs_opt_proc);
00728
00729 if (pool_init(&opt) < 0) {
00730 log_printf(LOG_ERROR, "Error: pool_init() failed\n");
00731 fuse_opt_free_args(&args);
00732 return EXIT_FAILURE;
00733 }
00734
00735
00736
00737
00738
00739
00740 if (0 < opt.bg)
00741 {
00742 if (0 < fork())
00743 return EXIT_SUCCESS;
00744
00745
00746 }
00747
00748 log_file = log_init(opt.logfile, 1);
00749
00750 fuse_main(args.argc, args.argv, &mysqlfs_oper);
00751 fuse_opt_free_args(&args);
00752
00753 pool_cleanup();
00754
00755 return EXIT_SUCCESS;
00756 }