All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: bschubert@ddn.com
Cc: miklos@szeredi.hu, neal@gompa.dev, linux-fsdevel@vger.kernel.org,
	bernd@bsbernd.com, joannelkoong@gmail.com
Subject: Re: [PATCH 03/13] mount_service: create high level fuse helpers
Date: Tue, 14 Apr 2026 16:58:35 -0700	[thread overview]
Message-ID: <20260414235835.GG604658@frogsfrogsfrogs> (raw)
In-Reply-To: <177577270271.2064074.7122706765827201316.stgit@frogsfrogsfrogs>

On Thu, Apr 09, 2026 at 03:21:20PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Create a fuse_main wrapper for fuse services.
> 
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  include/fuse.h         |   34 +++++++++++++
>  lib/fuse_versionscript |    1 
>  lib/helper.c           |  125 ++++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 156 insertions(+), 4 deletions(-)
> 
> 
> diff --git a/include/fuse.h b/include/fuse.h
> index 2bc3a9650c7c8b..129c744e39c46a 100644
> --- a/include/fuse.h
> +++ b/include/fuse.h
> @@ -1008,6 +1008,40 @@ static inline int fuse_main_fn(int argc, char *argv[],
>  #define fuse_main(argc, argv, op, user_data) \
>  	fuse_main_fn(argc, argv, op, user_data)
>  
> +#if FUSE_MAKE_VERSION(3, 19) <= FUSE_USE_VERSION
> +struct fuse_service;
> +int fuse_service_main_real_versioned(struct fuse_service *service,
> +				     struct fuse_args *args,
> +				     const struct fuse_operations *op,
> +				     size_t op_size,
> +				     struct libfuse_version *version,
> +				     void *user_data);
> +
> +/**
> + * Same as fuse_service_main_fn, but takes its information from the mount
> + * service context and an fuse_args that has already had fuse_service_append_args
> + * applied to it.
> + */
> +static inline int fuse_service_main_fn(struct fuse_service *service,
> +				       struct fuse_args *args,
> +				       const struct fuse_operations *op,
> +				       void *user_data)
> +{
> +	struct libfuse_version version = {
> +		.major  = FUSE_MAJOR_VERSION,
> +		.minor  = FUSE_MINOR_VERSION,
> +		.hotfix = FUSE_HOTFIX_VERSION,
> +		.padding = FUSE_USE_VERSION,
> +	};
> +
> +	return fuse_service_main_real_versioned(service, args, op,
> +						sizeof(*(op)), &version,
> +						user_data);
> +}
> +#define fuse_service_main(s, args, op, user_data) \
> +	fuse_service_main_fn(s, args, op, user_data)
> +#endif /* FUSE_USE_VERSION >= FUSE_MAKE_VERSION(3, 19) */
> +
>  /* ----------------------------------------------------------- *
>   * More detailed API					       *
>   * ----------------------------------------------------------- */
> diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
> index aa1912c76fb715..fc37931b475bdf 100644
> --- a/lib/fuse_versionscript
> +++ b/lib/fuse_versionscript
> @@ -236,6 +236,7 @@ FUSE_3.19 {
>  		fuse_service_exit;
>  		fuse_service_expect_mount_mode;
>  		fuse_service_finish_file_requests;
> +		fuse_service_main_real_versioned;
>  		fuse_service_parse_cmdline_opts;
>  		fuse_service_receive_file;
>  		fuse_service_release;
> diff --git a/lib/helper.c b/lib/helper.c
> index 819b9a6e4d243c..a2b3cc617bca54 100644
> --- a/lib/helper.c
> +++ b/lib/helper.c
> @@ -15,6 +15,7 @@
>  #include "fuse_misc.h"
>  #include "fuse_opt.h"
>  #include "fuse_lowlevel.h"
> +#include "fuse_service.h"
>  #include "mount_util.h"
>  
>  #include <stdio.h>
> @@ -365,6 +366,126 @@ int fuse_daemonize(int foreground)
>  	return 0;
>  }
>  
> +struct fuse *_fuse_new_31(struct fuse_args *args,
> +		       const struct fuse_operations *op, size_t op_size,
> +		       struct libfuse_version *version,
> +		       void *user_data);
> +
> +int fuse_service_main_real_versioned(struct fuse_service *service,
> +				     struct fuse_args *args,
> +				     const struct fuse_operations *op,
> +				     size_t op_size,
> +				     struct libfuse_version *version,
> +				     void *user_data)
> +{
> +	struct fuse *fuse;
> +	struct fuse_cmdline_opts opts;
> +	int res;
> +	struct fuse_loop_config *loop_config = NULL;
> +
> +	if (fuse_service_parse_cmdline_opts(args, &opts) != 0) {
> +		res = 1;
> +		goto out0;
> +	}
> +
> +	if (opts.show_version) {
> +		printf("FUSE library version %s\n", PACKAGE_VERSION);
> +		fuse_lowlevel_version();
> +		res = 0;
> +		goto out1;
> +	}
> +
> +	if (opts.show_help) {
> +		if (args->argv[0][0] != '\0')
> +			printf("usage: %s [options] <mountpoint>\n\n",
> +			       args->argv[0]);
> +		printf("FUSE options:\n");
> +		fuse_cmdline_help();
> +		fuse_lib_help(args);
> +		res = 0;
> +		goto out1;
> +	}
> +
> +	if (!opts.show_help &&
> +	    !opts.mountpoint) {
> +		fuse_log(FUSE_LOG_ERR, "error: no mountpoint specified\n");
> +		res = 2;
> +		goto out1;
> +	}
> +
> +	fuse = _fuse_new_31(args, op, op_size, version, user_data);
> +	if (fuse == NULL) {
> +		res = 3;
> +		goto out1;
> +	}
> +
> +	if (fuse_service_session_mount(service, fuse_get_session(fuse),

Just use @se below.

> +				       0, &opts) != 0) {
> +		res = 4;
> +		goto out2;
> +	}
> +
> +	/* No need to fork when running as a systemd service */
> +	if (fuse_daemonize(1) != 0) {

I'll change fuse_service_session_mount to do the chdir("/") call and
then we can skip this call entirely.

> +		res = 5;
> +		goto out3;
> +	}
> +
> +	struct fuse_session *se = fuse_get_session(fuse);
> +
> +	if (fuse_set_signal_handlers(se) != 0) {
> +		res = 6;
> +		goto out3;
> +	}
> +
> +	if (opts.singlethread) {
> +		fuse_service_send_goodbye(service, 0);
> +		fuse_service_release(service);
> +
> +		res = fuse_loop(fuse);
> +	} else {
> +		loop_config = fuse_loop_cfg_create();
> +		if (loop_config == NULL) {

Put this fallible call before fuse_service_session_mount and then we
don't have to call fuse_service_session_unmount to back this out.

> +			res = 7;
> +			goto out4;
> +		}
> +
> +		fuse_loop_cfg_set_clone_fd(loop_config, opts.clone_fd);
> +
> +		fuse_loop_cfg_set_idle_threads(loop_config, opts.max_idle_threads);
> +		fuse_loop_cfg_set_max_threads(loop_config, opts.max_threads);
> +
> +		fuse_service_send_goodbye(service, 0);
> +		fuse_service_release(service);
> +
> +		res = fuse_loop_mt(fuse, loop_config);
> +	}
> +	if (res)
> +		res = 8;
> +
> +	/*
> +	 * We've released the mount service helper, so we can't ask it to
> +	 * unmount the filesystem.  In other words, once mount() succeeds,
> +	 * the user has to unmount the filesystem.
> +	 */
> +	fuse_remove_signal_handlers(se);
> +	goto out2;
> +
> +out4:
> +	fuse_remove_signal_handlers(se);

Not needing the fuse_service_session_unmount call makes this cleanup
code become much simpler.

--D

> +out3:
> +	fuse_service_session_unmount(service);
> +out2:
> +	fuse_destroy(fuse);
> +out1:
> +	fuse_loop_cfg_destroy(loop_config);
> +	free(opts.mountpoint);
> +out0:
> +	fuse_service_send_goodbye(service, res);
> +	fuse_service_release(service);
> +	return res;
> +}
> +
>  int fuse_main_real_versioned(int argc, char *argv[],
>  			     const struct fuse_operations *op, size_t op_size,
>  			     struct libfuse_version *version, void *user_data)
> @@ -403,10 +524,6 @@ int fuse_main_real_versioned(int argc, char *argv[],
>  		goto out1;
>  	}
>  
> -	struct fuse *_fuse_new_31(struct fuse_args *args,
> -			       const struct fuse_operations *op, size_t op_size,
> -			       struct libfuse_version *version,
> -			       void *user_data);
>  	fuse = _fuse_new_31(&args, op, op_size, version, user_data);
>  	if (fuse == NULL) {
>  		res = 3;
> 
> 

  reply	other threads:[~2026-04-14 23:58 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-09 22:20 [PATCHSET v4] libfuse: run fuse servers as a contained service Darrick J. Wong
2026-04-09 22:20 ` [PATCH 01/13] Refactor mount code / move common functions to mount_util.c Darrick J. Wong
2026-04-09 22:21 ` [PATCH 02/13] mount_service: add systemd/inetd socket service mounting helper Darrick J. Wong
2026-04-14  1:00   ` Darrick J. Wong
2026-04-14 23:48   ` Darrick J. Wong
2026-04-17 23:19   ` Darrick J. Wong
2026-04-09 22:21 ` [PATCH 03/13] mount_service: create high level fuse helpers Darrick J. Wong
2026-04-14 23:58   ` Darrick J. Wong [this message]
2026-04-09 22:21 ` [PATCH 04/13] mount_service: use the new mount api for the mount service Darrick J. Wong
2026-04-17 22:03   ` Darrick J. Wong
2026-04-09 22:21 ` [PATCH 05/13] mount_service: update mtab after a successful mount Darrick J. Wong
2026-04-09 22:22 ` [PATCH 06/13] util: hoist the fuse.conf parsing and setuid mode enforcement code Darrick J. Wong
2026-04-09 22:22 ` [PATCH 07/13] util: fix checkpatch complaints in fuser_conf.[ch] Darrick J. Wong
2026-04-09 22:22 ` [PATCH 08/13] mount_service: enable unprivileged users in the same manner as fusermount Darrick J. Wong
2026-04-14 23:53   ` Darrick J. Wong
2026-04-17 22:01     ` Darrick J. Wong
2026-04-09 22:22 ` [PATCH 09/13] mount.fuse3: integrate systemd service startup Darrick J. Wong
2026-04-17 22:41   ` Darrick J. Wong
2026-04-20 23:41   ` Darrick J. Wong
2026-04-09 22:23 ` [PATCH 10/13] mount_service: allow installation as a setuid program Darrick J. Wong
2026-04-09 22:23 ` [PATCH 11/13] example/service_ll: create a sample systemd service fuse server Darrick J. Wong
2026-04-14 23:56   ` Darrick J. Wong
2026-04-17 21:56   ` Darrick J. Wong
2026-04-09 22:23 ` [PATCH 12/13] example/service: create a sample systemd service for a high-level " Darrick J. Wong
2026-04-09 22:23 ` [PATCH 13/13] nullfs: support fuse systemd service mode Darrick J. Wong
  -- strict thread matches above, loose matches on Subject: below --
2026-04-22 23:18 [PATCHSET v5] libfuse: run fuse servers as a contained service Darrick J. Wong
2026-04-22 23:20 ` [PATCH 03/13] mount_service: create high level fuse helpers Darrick J. Wong
2026-04-30 21:15 [PATCHSET v5.1] libfuse: run fuse servers as a contained service Darrick J. Wong
2026-04-30 21:15 ` [PATCH 03/13] mount_service: create high level fuse helpers Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260414235835.GG604658@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=bernd@bsbernd.com \
    --cc=bschubert@ddn.com \
    --cc=joannelkoong@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=neal@gompa.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.