[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH] umount: Implement -O option to unmount by mount options
From:       Sören Tempel <soeren () soeren-tempel ! net>
Date:       2023-01-12 18:05:49
Message-ID: 2UUGHLYZS9L38.3I46X0XCDIJKQ () 8pit ! net
[Download RAW message or body]

PING.

This would be very helpful for us at Alpine since OpenRC uses this
option to unmount all network file systems and there isn't any other
clean way of achieving this.

soeren@soeren-tempel.net wrote:
> From: Sören Tempel <soeren+git@soeren-tempel.net>
> 
> This commit adds a primitive implementation of the umount -O option, as
> provided by util-linux's mount(8) implementation, to BusyBox. Similar to
> -t, the option is intended to be used in conjunction with -a thereby
> allowing users to filter which file systems are unmounted by mount
> options. Multiple options can be specified with -O, all of which need to
> match. Each option can be prefixed with `no` to indicate that no action
> should be taken for a mount point with this mount option.
> 
> At Alpine, this feature is often requested by users as the OpenRC
> netmount service uses `umount -a -O _netdev` to amount all network
> file systems [1] [2].
> 
> Discussion:
> 
> * There is some minor code duplication between fsopt_matches and
> fstype_matches. Adding some sort of utility function to resolve
> this may allow for a further decrease in text segment size.
> * The semantics of -O are not well described in the util-linux
> mount(8) man page. Please review this carefully to ensure that the
> implementation proposed here is semantically equivalent to the one
> provided by util-linux.
> 
> [1]: https://gitlab.alpinelinux.org/alpine/aports/-/issues/9923
> [2]: https://gitlab.alpinelinux.org/alpine/aports/-/issues/13789
> 
> Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
> ---
> I haven't tested this extensively yet. Feedback is most welcome.
> 
> include/libbb.h      |  1 +
> libbb/Kbuild.src     |  1 +
> libbb/match_fsopts.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
> util-linux/umount.c  | 10 +++++---
> 4 files changed, 68 insertions(+), 3 deletions(-)
> create mode 100644 libbb/match_fsopts.c
> 
> diff --git a/include/libbb.h b/include/libbb.h
> index 6aeec249d..1a203861e 100644
> --- a/include/libbb.h
> +++ b/include/libbb.h
> @@ -1585,6 +1585,7 @@ const struct hwtype *get_hwntype(int type) FAST_FUNC;
> 
> 
> extern int fstype_matches(const char *fstype, const char *comma_list) FAST_FUNC;
> +extern int fsopts_matches(const char *opts_list, const char *reqopts_list) \
> FAST_FUNC; #ifdef HAVE_MNTENT_H
> extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC;
> #endif
> diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
> index 653025e56..4bb8260b9 100644
> --- a/libbb/Kbuild.src
> +++ b/libbb/Kbuild.src
> @@ -120,6 +120,7 @@ lib-y += xrealloc_vector.o
> 
> lib-$(CONFIG_MOUNT) += match_fstype.o
> lib-$(CONFIG_UMOUNT) += match_fstype.o
> +lib-$(CONFIG_UMOUNT) += match_fsopts.o
> 
> lib-$(CONFIG_FEATURE_UTMP) += utmp.o
> 
> diff --git a/libbb/match_fsopts.c b/libbb/match_fsopts.c
> new file mode 100644
> index 000000000..fff236c7a
> --- /dev/null
> +++ b/libbb/match_fsopts.c
> @@ -0,0 +1,59 @@
> +/* vi: set sw=4 ts=4: */
> +/*
> + * Match fsopts for use in mount unmount -O.
> + *
> + * Returns 1 for a match, otherwise 0.
> + *
> + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
> + */
> +
> +#include "libbb.h"
> +
> +static int FAST_FUNC fsopt_matches(const char *opts_list, const char *opt, size_t \
> optlen) +{
> +	int match = 1;
> +
> +	if (optlen > 2 && opt[0] == 'n' && opt[1] == '0') {
> +		match--;
> +		opt += 2; optlen -= 2;
> +	}
> +
> +	while (1) {
> +		if (strncmp(opts_list, opt, optlen) == 0) {
> +			const char *after_opt = opts_list + optlen;
> +			if (*after_opt == '\0' || *after_opt == ',')
> +				return match;
> +		}
> +
> +		opts_list = strchr(opts_list, ',');
> +		if (!opts_list)
> +			break;
> +		opts_list++;
> +	}
> +
> +	return !match;
> +}
> +
> +int FAST_FUNC fsopts_matches(const char *opts_list, const char *reqopts_list)
> +{
> +	if (!reqopts_list)
> +		return 1; /* no options requested, match anything */
> +
> +	while (1) {
> +		size_t len;
> +		const char *comma = strchr(reqopts_list, ',');
> +		if (!comma)
> +			len = strlen(reqopts_list);
> +		else
> +			len = comma - reqopts_list;
> +
> +		if (len && !fsopt_matches(opts_list, reqopts_list, len))
> +			return 0;
> +
> +		if (!comma)
> +			break;
> +		reqopts_list = ++comma;
> +	}
> +
> +	return 1;
> +}
> diff --git a/util-linux/umount.c b/util-linux/umount.c
> index 23da32868..7a54cafb0 100644
> --- a/util-linux/umount.c
> +++ b/util-linux/umount.c
> @@ -41,7 +41,7 @@
> //kbuild:lib-$(CONFIG_UMOUNT) += umount.o
> 
> //usage:#define umount_trivial_usage
> -//usage:       "[-rlf"IF_FEATURE_MTAB_SUPPORT("m")IF_FEATURE_MOUNT_LOOP("d")IF_FEATURE_UMOUNT_ALL("a")"] \
> [-t FSTYPE] FILESYSTEM|DIRECTORY" +//usage:       \
> "[-rlf"IF_FEATURE_MTAB_SUPPORT("m")IF_FEATURE_MOUNT_LOOP("d")IF_FEATURE_UMOUNT_ALL("a")"] \
> [-t FSTYPE] [-O FSOPT] FILESYSTEM|DIRECTORY" //usage:#define umount_full_usage \
>                 "\n\n"
> //usage:       "Unmount filesystems\n"
> //usage:	IF_FEATURE_UMOUNT_ALL(
> @@ -57,6 +57,7 @@
> //usage:     "\n	-d	Free loop device if it has been used"
> //usage:	)
> //usage:     "\n	-t FSTYPE[,...]	Unmount only these filesystem type(s)"
> +//usage:     "\n	-O FSOPT[,...]	Unmount only filesystem mounted with the given \
> options" //usage:
> //usage:#define umount_example_usage
> //usage:       "$ umount /dev/hdc1\n"
> @@ -82,7 +83,7 @@ static struct mntent *getmntent_r(FILE* stream, struct mntent* \
> result, #endif
> 
> /* ignored: -c -v -i */
> -#define OPTION_STRING           "fldnrat:" "cvi"
> +#define OPTION_STRING           "fldnrat:O:" "cvi"
> #define OPT_FORCE               (1 << 0) // Same as MNT_FORCE
> #define OPT_LAZY                (1 << 1) // Same as MNT_DETACH
> #define OPT_FREELOOP            (1 << 2)
> @@ -96,6 +97,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv)
> 	int doForce;
> 	struct mntent me;
> 	FILE *fp;
> +	char *opts = NULL;
> 	char *fstype = NULL;
> 	int status = EXIT_SUCCESS;
> 	unsigned opt;
> @@ -105,7 +107,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv)
> 		struct mtab_list *next;
> 	} *mtl, *m;
> 
> -	opt = getopt32(argv, OPTION_STRING, &fstype);
> +	opt = getopt32(argv, OPTION_STRING, &fstype, &opts);
> 	//argc -= optind;
> 	argv += optind;
> 
> @@ -133,6 +135,8 @@ int umount_main(int argc UNUSED_PARAM, char **argv)
> 			/* Match fstype (fstype==NULL matches always) */
> 			if (!fstype_matches(me.mnt_type, fstype))
> 				continue;
> +			if (!fsopts_matches(me.mnt_opts, opts))
> +				continue;
> 			m = xzalloc(sizeof(*m));
> 			m->next = mtl;
> 			m->device = xstrdup(me.mnt_fsname);
> _______________________________________________
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic