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
