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.

[email protected] wrote:
> From: Sören Tempel <[email protected]>
> 
> 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 <[email protected]>
> ---
> 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
> [email protected]
> http://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to