Skip to content
Snippets Groups Projects
Commit 8e801726 authored by Sören Tempel's avatar Sören Tempel Committed by Sören Tempel
Browse files

main/busybox: add support for umount -O

See: http://lists.busybox.net/pipermail/busybox/2022-June/089769.html

Fixes !35149
Fixes #13789
Fixes #9923
parent 5b8fd746
No related branches found
No related tags found
No related merge requests found
From 7ea459b570760f8e836d05e58422dbd3a7d1b016 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Tempel?= <soeren+git@soeren-tempel.net>
Date: Sun, 19 Jun 2022 17:49:41 +0200
Subject: [PATCH] umount: Implement -O option to unmount by mount options
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds an 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. The "no" prefix
interpretation can be disabled using the "+" prefix.
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].
This implementation is functionally equivalent to the util-linux
implementation with the exception that it implements no special handling
for `key="value"` mount options to keep the implementation simple.
Therefore, filesystems mounted with options like `foo="bar"` won't
be matched by `umount -a -O foo`.
[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@soeren-tempel.net>
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
---
include/libbb.h | 1 +
libbb/Kbuild.src | 1 +
libbb/match_fsopts.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
util-linux/umount.c | 10 +++++--
4 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 libbb/match_fsopts.c
diff --git a/include/libbb.h b/include/libbb.h
index cca33a177..ad41adec8 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1586,6 +1586,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..b1cc85c3c
--- /dev/null
+++ b/libbb/match_fsopts.c
@@ -0,0 +1,69 @@
+/* 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 fsopt_matches(const char *opts_list, const char *opt, size_t optlen)
+{
+ int match = 1;
+
+ if (optlen >= 2 && opt[0] == 'n' && opt[1] == 'o') {
+ match--;
+ opt += 2; optlen -= 2;
+ }
+
+ /* The alone "no" is an error, all matching ends with False. */
+ if (optlen == 0)
+ return 0;
+
+ /* The "no" prefix interpretation can be disabled by the "+" prefix. */
+ if (match && optlen > 1 && *opt == '+') {
+ opt++; optlen--;
+ }
+
+ 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;
+}
+
+/* This function implements the mnt_match_options function from libmount. */
+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);
......@@ -5,7 +5,7 @@
# Maintainer: Sören Tempel <soeren+alpine@soeren-tempel.net>
pkgname=busybox
pkgver=1.36.0
pkgrel=4
pkgrel=5
pkgdesc="Size optimized toolbox of many common UNIX utilities"
url="https://busybox.net/"
arch="all"
......@@ -73,6 +73,7 @@ source="https://busybox.net/downloads/busybox-$pkgver.tar.bz2
0024-tests-musl-doesn-t-seem-to-recognize-UTC0-as-a-timez.patch
0025-Hackfix-to-disable-HW-acceleration-for-MD5-SHA1-on-x.patch
0026-lineedit-Handle-SIGWINCH-gracefully.patch
0027-umount-Implement-O-option-to-unmount-by-mount-option.patch
acpid.logrotate
busyboxconfig
......@@ -383,6 +384,7 @@ ce4316e44148562addc1f5839166ca9314ee6f26dae218617c287791a8d9239e374f993688a9299e
192fe9b535b3ae4cfbd8455d642e9c73b134ddbdf9265b3ebd1a185122bbb1064cf2c1f01840a8cf35d0665969846ff7168c215fdce96b46b031d73c16f7622f 0024-tests-musl-doesn-t-seem-to-recognize-UTC0-as-a-timez.patch
0a0e4c425879d8250b4dee925dc9feb2595ed68b1fdb5c22e78f3452e46dc17c882ea47f119c2308915f4105b69e5c6f38156131bee1fe9ba0ff684bfd10a049 0025-Hackfix-to-disable-HW-acceleration-for-MD5-SHA1-on-x.patch
09358ed36d6c13a50119a9d96898fdc2d3e6ca089659780604425ae3d32960a17c3083de81a131b1cf9a9a2b449e40a8ed6af3a8b916247571ebc41765ab365b 0026-lineedit-Handle-SIGWINCH-gracefully.patch
e3670ab567818a42593698546dcdabaa447c10682261c128901b4390eb2bf2dbea9e84f8f2dcdd6d67c82bf93bb1eed14406e5a8dd723b4670d1995b6100651f 0027-umount-Implement-O-option-to-unmount-by-mount-option.patch
aa93095e20de88730f526c6f463cef711b290b9582cdbd8c1ba2bd290019150cbeaa7007c2e15f0362d5b9315dd63f60511878f0ea05e893f4fdfb4a54af3fb1 acpid.logrotate
94148428f096a97572beb3ddf4af46bc2ae24f127658c2794cffcb5946fd7565eca6d10d56a9a3728cf756d1e647c279dc5b64537704587c520220c7f0eeccec busyboxconfig
976c77e0b85cef1b9893536c7824898ad43e6dd651735620e3b90703068cfe4052b4ccbda8ac4533590dfb676b9ed80499ea3e785aa0c5ad99fe46079fa31e3d busyboxconfig-extras
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment