summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c111
1 files changed, 79 insertions, 32 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 247a77ea9..46cfb05ed 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -2692,56 +2692,80 @@ notify (xlator_t *this, int32_t event,
return 0;
}
+static struct fuse_opt subtype_workaround[] = {
+ FUSE_OPT_KEY("subtype=", 0),
+ FUSE_OPT_KEY("fssubtype=", 0),
+ FUSE_OPT_END
+};
+
+static int
+subtype_workaround_optproc(void *data, const char *arg, int key,
+ struct fuse_args *outargs)
+{
+ return key ? 1 : 0;
+}
+
int
init (xlator_t *this_xl)
{
int ret = 0;
dict_t *options = NULL;
char *value_string = NULL;
+ char *fsname = NULL, *fsname_opt = NULL;
fuse_private_t *priv = NULL;
struct stat stbuf = {0,};
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ char **p = NULL;
#ifdef GF_DARWIN_HOST_OS
- int fuse_argc = 9;
char *fuse_argv[] = {"glusterfs",
+ "-o", "XXX",
+ "-o", "fssubtype=glusterfs",
"-o", "allow_other",
"-o", "default_permissions",
- "-o", "fsname=glusterfs",
- "-o", "local",
+ NULL, NULL,
NULL};
+ for (p = fuse_argv; *p; p++);
+ if (!dict_get (options, "macfuse-local")) {
+ /* This way, GlusterFS will be detected as 'servers' instead
+ * of 'devices'. This method is useful if you want to do
+ * 'umount <mount_point>' over network, instead of 'eject'ing
+ * it from desktop. Works better for servers
+ */
+ *(p++) = "-o";
+ *(p++) = "local";
+ }
+
#elif GF_LINUX_HOST_OS /* ! DARWIN_OS */
- int fuse_argc = 19;
-
char *fuse_argv[] = {"glusterfs",
+ "-o", "XXX",
+ "-o", "subtype=glusterfs",
"-o", "nonempty",
"-o", "max_readahead=1048576",
"-o", "max_read=1048576",
"-o", "max_write=1048576",
"-o", "allow_other",
"-o", "default_permissions",
- "-o", "fsname=glusterfs",
"-o", "dev",
"-o", "suid",
NULL};
#else /* BSD || SOLARIS */
/* BSD fuse doesn't support '-o dev', '-o nonempty' option */
- int fuse_argc = 15;
-
char *fuse_argv[] = {"glusterfs",
+ "-o", "XXX",
+ "-o", "subtype=glusterfs",
"-o", "max_readahead=1048576",
"-o", "max_read=1048576",
"-o", "max_write=1048576",
"-o", "allow_other",
"-o", "default_permissions",
- "-o", "fsname=glusterfs",
"-o", "suid",
NULL};
#endif /* ! DARWIN_OS || ! LINUX */
- struct fuse_args args = FUSE_ARGS_INIT (fuse_argc, fuse_argv);
-
+
if (this_xl == NULL)
return -1;
@@ -2750,34 +2774,33 @@ init (xlator_t *this_xl)
options = this_xl->options;
- if (this_xl->name == NULL)
+ if (this_xl->name == NULL) {
this_xl->name = strdup ("fuse");
+ ERR_ABORT(this_xl->name);
+ }
+
+ fsname = this_xl->ctx->cmd_args.volume_file;
+ fsname = (fsname ? fsname : this_xl->ctx->cmd_args.volfile_server);
+ fsname = (fsname ? fsname : "glusterfs");
+ ret = asprintf(&fsname_opt, "fsname=%s", fsname);
+ if (ret == -1)
+ ERR_ABORT(NULL);
+ fuse_argv[2] = fsname_opt;
+
+ for (p = fuse_argv; *p; p++);
+ args.argc = p - fuse_argv;
+ args.argv = fuse_argv;
priv = CALLOC (1, sizeof (*priv));
ERR_ABORT (priv);
this_xl->private = (void *) priv;
-
-#ifdef GF_DARWIN_HOST_OS
- if (dict_get (options, "macfuse-local")) {
- /* This way, GlusterFS will be detected as 'servers' instead
- * of 'devices'. This method is useful if you want to do
- * 'umount <mount_point>' over network, instead of 'eject'ing
- * it from desktop. Works better for servers
- */
- /* Make the '-o local' in argv as NULL, so that its not
- in effect */
- fuse_argv[--args.argc] = NULL;
- fuse_argv[--args.argc] = NULL;
- }
-#endif /* ! DARWIN */
-
/* get options from option dictionary */
ret = dict_get_str (options, ZR_MOUNTPOINT_OPT, &value_string);
if (value_string == NULL) {
gf_log ("fuse", GF_LOG_ERROR,
"mandatory option mountpoint is not specified");
- return -1;
+ goto cleanup_exit;
}
if (stat (value_string, &stbuf) != 0) {
@@ -2796,17 +2819,17 @@ init (xlator_t *this_xl)
ZR_MOUNTPOINT_OPT,
value_string, strerror (errno));
}
- return -1;
+ goto cleanup_exit;
}
if (S_ISDIR (stbuf.st_mode) == 0) {
gf_log (this_xl->name, GF_LOG_ERROR ,
"%s %s is not a directory",
ZR_MOUNTPOINT_OPT, value_string);
- return -1;
+ goto cleanup_exit;
}
priv->mount_point = strdup (value_string);
-
+ ERR_ABORT(priv->mount_point);
ret = dict_get_double (options, "attribute-timeout",
&priv->attribute_timeout);
@@ -2860,6 +2883,27 @@ init (xlator_t *this_xl)
priv->se = fuse_lowlevel_new (&args, &fuse_ops,
sizeof (fuse_ops), this_xl);
+ if (priv->se == NULL && !errno) {
+ /*
+ * Option parsing misery. Can happen if libfuse is of
+ * FUSE < 2.7.0, as then the "-o subtype" option is not
+ * handled.
+ *
+ * Best we can do to is to handle it at runtime -- this is not
+ * a binary incompatibility issue (which should dealt with at
+ * compile time), but a behavioural incompatibility issue. Ie.
+ * we can't tell in advance whether the lib we use supports
+ * "-o subtype". So try to be clever now.
+ *
+ * Delete the subtype option, and try again.
+ */
+ if (fuse_opt_parse(&args, NULL, subtype_workaround,
+ subtype_workaround_optproc) == 0)
+ priv->se = fuse_lowlevel_new (&args, &fuse_ops,
+ sizeof (fuse_ops),
+ this_xl);
+ }
+
if (priv->se == NULL) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"fuse_lowlevel_new() failed with error %s on "
@@ -2877,6 +2921,7 @@ init (xlator_t *this_xl)
}
fuse_opt_free_args (&args);
+ FREE (fsname_opt);
fuse_session_add_chan (priv->se, priv->ch);
@@ -2893,7 +2938,9 @@ umount_exit:
fuse_unmount (priv->mount_point, priv->ch);
cleanup_exit:
fuse_opt_free_args (&args);
- FREE (priv->mount_point);
+ FREE (fsname_opt);
+ if (priv)
+ FREE (priv->mount_point);
FREE (priv);
return -1;
}