[haiku-commits] r41258 - haiku/trunk/src/tools/fs_shell

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 15 Apr 2011 23:10:41 +0200 (CEST)

Author: axeld
Date: 2011-04-15 23:10:40 +0200 (Fri, 15 Apr 2011)
New Revision: 41258
Changeset: https://dev.haiku-os.org/changeset/41258
Ticket: https://dev.haiku-os.org/ticket/7433

Modified:
   haiku/trunk/src/tools/fs_shell/fuse.cpp
Log:
* Applied patch by idefix that improves the integration with Linux, and let
  bfs_fuse act as a mount helper. This closes ticket #7433. Thanks a lot!


Modified: haiku/trunk/src/tools/fs_shell/fuse.cpp
===================================================================
--- haiku/trunk/src/tools/fs_shell/fuse.cpp     2011-04-15 18:44:34 UTC (rev 
41257)
+++ haiku/trunk/src/tools/fs_shell/fuse.cpp     2011-04-15 21:10:40 UTC (rev 
41258)
@@ -414,7 +414,7 @@
 
 
 static int
-fssh_fuse_session(const char* device, const char* mntPoint, const char* fsName)
+mount_volume(const char* device, const char* mntPoint, const char* fsName)
 {
        // Mount the volume in the root FS.
        fssh_dev_t fsDev = _kern_mount(kMountPoint, device, fsName, 0, NULL, 0);
@@ -440,37 +440,92 @@
                        isErr ? "unknown" : info.volume_name,
                        mntPoint);
        }
+       
+       return 0;
+}
 
-       // Run the fuse_main() loop.
-       const char* argv[13];
-       int fuseArgCount = 0;
 
-       argv[fuseArgCount++] = (const char*)"bfs_fuse";
-       argv[fuseArgCount++] = mntPoint;
-       argv[fuseArgCount++] = (const char*)"-s";
-       if (gIsDebug)
-               argv[fuseArgCount++] = (const char*)"-d";
-
-       initialiseFuseOps(&gFUSEOperations);
-
-       int ret = fuse_main(fuseArgCount, (char**)argv, &gFUSEOperations, NULL);
-
+static int
+unmount_volume(const char* device, const char* mntPoint)
+{
        // Unmount the volume again.
        // Avoid a "busy" vnode.
        _kern_setcwd(-1, "/");
        fssh_status_t error = _kern_unmount(kMountPoint, 0);
        if (error != FSSH_B_OK) {
                if (gIsDebug)
-                       fprintf(stderr, "Error: Unmounting FS failed: %s\n", 
fssh_strerror(error));
+                       fprintf(stderr, "Error: Unmounting FS failed: %s\n",
+                               fssh_strerror(error));
                else
-                       syslog(LOG_INFO, "Error: Unmounting FS failed: %s", 
fssh_strerror(error));
+                       syslog(LOG_INFO, "Error: Unmounting FS failed: %s",
+                               fssh_strerror(error));
                return 1;
        }
 
        if (!gIsDebug)
                syslog(LOG_INFO, "UnMounted %s from %s", device, mntPoint);
+       
+       return 0;
+}
 
-       return ret;
+
+static int
+fssh_fuse_session(const char* device, const char* mntPoint, const char* fsName,
+       struct fuse_args& fuseArgs)
+{
+       int ret;
+       
+       ret = mount_volume(device, mntPoint, fsName);
+       if (ret != 0)
+               return ret;
+       
+       char* fuseOptions = NULL;
+
+       // default FUSE options
+       char* fsNameOption = NULL;
+       if (fuse_opt_add_opt(&fuseOptions, "allow_other") < 0
+               || asprintf(&fsNameOption, "fsname=%s", device) < 0
+               || fuse_opt_add_opt(&fuseOptions, fsNameOption) < 0) {
+               unmount_volume(device, mntPoint);
+               return 1;
+       }
+
+       struct stat sbuf;
+       if ((stat(device, &sbuf) == 0) && S_ISBLK(sbuf.st_mode)) {
+               int blkSize = 512;
+               fssh_dev_t volumeID = get_volume_id();
+               if (volumeID >= 0) {
+                       fssh_fs_info info;
+                       if (_kern_read_fs_info(volumeID, &info) == FSSH_B_OK)
+                               blkSize = info.block_size;
+               }
+
+               char* blkSizeOption = NULL;
+               if (fuse_opt_add_opt(&fuseOptions, "blkdev") < 0
+                       || asprintf(&blkSizeOption, "blksize=%i", blkSize) < 0
+                       || fuse_opt_add_opt(&fuseOptions, blkSizeOption) < 0) {
+                       unmount_volume(device, mntPoint);
+                       return 1;
+               }
+       }
+
+       // Run the fuse_main() loop.
+       if (fuse_opt_add_arg(&fuseArgs, "-s") < 0
+               || fuse_opt_add_arg(&fuseArgs, "-o") < 0
+               || fuse_opt_add_arg(&fuseArgs, fuseOptions) < 0) {
+               unmount_volume(device, mntPoint);
+               return 1;
+       }
+
+       initialiseFuseOps(&gFUSEOperations);
+
+       int res = fuse_main(fuseArgs.argc, fuseArgs.argv, &gFUSEOperations, 
NULL);
+
+       ret = unmount_volume(device, mntPoint);
+       if (ret != 0)
+               return ret;
+
+       return res;
 }
 
 
@@ -488,34 +543,65 @@
 }
 
 
-int
-main(int argc, const char* const* argv)
+struct FsConfig {
+       const char* device;
+       const char* mntPoint;
+};
+
+
+enum {
+       KEY_DEBUG,
+       KEY_HELP
+};
+
+
+static int
+process_options(void* data, const char* arg, int key, struct fuse_args* 
outArgs)
 {
-       // eat options
-       int argi = 1;
-       while (argi < argc && argv[argi][0] == '-') {
-               const char* arg = argv[argi++];
-               if (strcmp(arg, "--help") == 0) {
-                       print_usage_and_exit(argv[0]);
-               } else if (strcmp(arg, "-d") == 0) {
+       struct FsConfig* config = (FsConfig*) data;
+
+       switch (key) {
+               case FUSE_OPT_KEY_NONOPT:
+                       if (!config->device) {
+                               config->device = arg;
+                               return 0;
+                                       // don't pass the device path to 
fuse_main()
+                       } else if (!config->mntPoint)
+                               config->mntPoint = arg;
+                       else
+                               print_usage_and_exit(outArgs->argv[0]);
+                       break;
+               case KEY_DEBUG:
                        gIsDebug = true;
-               } else {
-                       print_usage_and_exit(argv[0]);
-               }
+                       break;
+               case KEY_HELP:
+                       print_usage_and_exit(outArgs->argv[0]);
        }
 
-       // get device
-       if (argi >= argc)
-               print_usage_and_exit(argv[0]);
-       const char* device = argv[argi++];
-       // get mountpoint
-       if (argi >= argc)
-               print_usage_and_exit(argv[0]);
-       const char* mntPoint = argv[argi++];
-       // more parameters are excess
-       if (argi < argc)
-               print_usage_and_exit(argv[0]);
+       return 1;
+}
 
+
+int
+main(int argc, char* argv[])
+{
+       struct fuse_args fuseArgs = FUSE_ARGS_INIT(argc, argv);
+       struct FsConfig config;
+       memset(&config, 0, sizeof(config));
+       const struct fuse_opt fsOptions[] = {
+               FUSE_OPT_KEY("uhelper=",        FUSE_OPT_KEY_DISCARD),
+                       // fuse_main() throws an error about this unknown option
+                       // TODO: do not use fuse_main to mount filesystem, 
instead use
+                       // fuse_mount, fuse_new, fuse_set_signal_handlers and 
fuse_loop
+               FUSE_OPT_KEY("-d",                      KEY_DEBUG),
+               FUSE_OPT_KEY("-h",                      KEY_HELP),
+               FUSE_OPT_KEY("--help",          KEY_HELP),
+               FUSE_OPT_END
+       };
+
+       if (fuse_opt_parse(&fuseArgs, &config, fsOptions, process_options) < 0)
+               return 1;
+
        if (!modules[0]) {
                fprintf(stderr, "Error: Couldn't find FS module!\n");
                return 1;
@@ -527,7 +613,8 @@
                        fssh_strerror(error));
                return error;
        }
+
        const char* fsName = modules[0]->name;
-       return fssh_fuse_session(device, mntPoint, fsName);
+       return fssh_fuse_session(config.device, config.mntPoint, fsName, 
fuseArgs);
 }
 


Other related posts:

  • » [haiku-commits] r41258 - haiku/trunk/src/tools/fs_shell - axeld