[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [PATCH 2/2] mount: use volume_id for fstype detection
From: "Alex Xu (Hello71)" <alex_y_xu () yahoo ! ca>
Date: 2021-11-25 23:22:50
Message-ID: 20211125232250.87522-2-alex_y_xu () yahoo ! ca
[Download RAW message or body]
This allows filesystems to be mounted even if the module is not
currently loaded and the type is not listed in /etc/filesystems. This
was semi-rejected back in 2005 on the basis that it would be impractical
to add a database of all filesystem types into busybox, but that has
since been added in the form of volume_id. The benefits of using
volume_id instead of adding all filesystems to /etc/filesystems or
listing modaliases are:
1. it is faster since it doesn't call mount (or worse, modprobe) N times
for each filesystem
2. it doesn't require loading all filesystems into kernel memory
3. it doesn't require the distributor/sysadmin to maintain
/etc/filesystems
function old new delta
resolve_mount_spec 107 266 +159
singlemount 1053 1150 +97
uuidcache_init 64 67 +3
swap_enable_disable 245 247 +2
findfs_main 82 84 +2
devices_scanned - 1 +1
mount_main 1275 1255 -20
get_devname_from_uuid 63 - -63
get_devname_from_label 68 - -68
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 5/1 up/down: 264/-151) Total: 113 bytes
---
include/volume_id.h | 4 +-
util-linux/findfs.c | 2 +-
util-linux/mount.c | 54 ++++++++++++-----------
util-linux/swaponoff.c | 4 +-
util-linux/volume_id/get_devname.c | 69 +++++++++++++-----------------
5 files changed, 64 insertions(+), 69 deletions(-)
diff --git a/include/volume_id.h b/include/volume_id.h
index a83da899e..6e6d7aef9 100644
--- a/include/volume_id.h
+++ b/include/volume_id.h
@@ -18,8 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-char *get_devname_from_label(const char *spec);
-char *get_devname_from_uuid(const char *spec);
void display_uuid_cache(int scan_devices);
/* Returns:
@@ -27,5 +25,5 @@ void display_uuid_cache(int scan_devices);
* 1: UUID= or LABEL= prefix found. In this case,
* *fsname is replaced if device with such UUID or LABEL is found
*/
-int resolve_mount_spec(char **fsname);
+int resolve_mount_spec(char **fsname, char **fstype);
int add_to_uuid_cache(const char *device);
diff --git a/util-linux/findfs.c b/util-linux/findfs.c
index f5621a1fa..3a5f442a9 100644
--- a/util-linux/findfs.c
+++ b/util-linux/findfs.c
@@ -46,7 +46,7 @@ int findfs_main(int argc UNUSED_PARAM, char **argv)
} else {
/* Otherwise, handle LABEL=xxx and UUID=xxx,
* fail on anything else */
- if (!resolve_mount_spec(argv))
+ if (!resolve_mount_spec(argv, NULL))
bb_show_usage();
}
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 4e65b6b46..2a94ca759 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -55,8 +55,8 @@
//config: "sometype [-o opts] fs /mnt" if simple mount syscall fails.
//config: The idea is to use such virtual filesystems in /etc/fstab.
//config:
-//config:config FEATURE_MOUNT_LABEL
-//config: bool "Support specifying devices by label or UUID"
+//config:config FEATURE_MOUNT_VOLUMEID
+//config: bool "Support auto-detecting type and searching by label or UUID"
//config: default y
//config: depends on MOUNT
//config: select VOLUMEID
@@ -234,10 +234,10 @@
#include "libbb.h"
#include "common_bufsiz.h"
-#if ENABLE_FEATURE_MOUNT_LABEL
+#if ENABLE_FEATURE_MOUNT_VOLUMEID
# include "volume_id.h"
#else
-# define resolve_mount_spec(fsname) ((void)0)
+# define resolve_mount_spec(fsname, fstype) ((void)0)
#endif
// Needed for nfs support only
@@ -1972,7 +1972,7 @@ static int singlemount(struct mntent *mp, int ignore_busy)
int loopfd = -1;
int rc = -1;
unsigned long vfsflags;
- char *loopFile = NULL, *filteropts = NULL;
+ char *loopFile = NULL, *filteropts = NULL, *guess_type = NULL;
llist_t *fl = NULL;
struct stat st;
@@ -2103,6 +2103,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
}
}
+ resolve_mount_spec(&mp->mnt_fsname, mp->mnt_type ? NULL : &guess_type);
+
// Look at the file. (Not found isn't a failure for remount, or for
// a synthetic filesystem like proc or sysfs.)
// (We use stat, not lstat, in order to allow
@@ -2162,23 +2164,31 @@ static int singlemount(struct mntent *mp, int ignore_busy)
mp->mnt_type = next + 1;
}
} else {
- // Loop through filesystem types until mount succeeds
- // or we run out
-
- // Initialize list of block backed filesystems.
- // This has to be done here so that during "mount -a",
- // mounts after /proc shows up can autodetect.
- if (!fslist) {
- fslist = get_block_backed_filesystems();
- if (ENABLE_FEATURE_CLEAN_UP && fslist)
- atexit(delete_block_backed_filesystems);
+ // Try the guessed type if one is available
+ if (guess_type) {
+ mp->mnt_type = guess_type;
+ rc = mount_it_now(mp, vfsflags, filteropts);
}
- for (fl = fslist; fl; fl = fl->link) {
- mp->mnt_type = fl->data;
- rc = mount_it_now(mp, vfsflags, filteropts);
- if (rc == 0)
- break;
+ if (rc != 0) {
+ // Loop through filesystem types until mount succeeds
+ // or we run out
+
+ // Initialize list of block backed filesystems.
+ // This has to be done here so that during "mount -a",
+ // mounts after /proc shows up can autodetect.
+ if (!fslist) {
+ fslist = get_block_backed_filesystems();
+ if (ENABLE_FEATURE_CLEAN_UP && fslist)
+ atexit(delete_block_backed_filesystems);
+ }
+
+ for (fl = fslist; fl; fl = fl->link) {
+ mp->mnt_type = fl->data;
+ rc = mount_it_now(mp, vfsflags, filteropts);
+ if (rc == 0)
+ break;
+ }
}
}
@@ -2350,7 +2360,6 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
mtpair->mnt_dir = argv[1];
mtpair->mnt_type = fstype;
mtpair->mnt_opts = cmdopts;
- resolve_mount_spec(&mtpair->mnt_fsname);
rc = singlemount(mtpair, /*ignore_busy:*/ 0);
return rc;
}
@@ -2446,8 +2455,6 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
if (!match_opt(mtcur->mnt_opts, O_optmatch))
continue;
- resolve_mount_spec(&mtcur->mnt_fsname);
-
// NFS mounts want this to be xrealloc-able
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
@@ -2523,7 +2530,6 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// ...mount the last thing we found
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
append_mount_options(&(mtcur->mnt_opts), cmdopts);
- resolve_mount_spec(&mtpair->mnt_fsname);
rc = singlemount(mtcur, /*ignore_busy:*/ 0);
if (ENABLE_FEATURE_CLEAN_UP)
free(mtcur->mnt_opts);
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index e2ff4b5cc..540faa042 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -82,7 +82,7 @@
#if ENABLE_FEATURE_SWAPONOFF_LABEL
# include "volume_id.h"
#else
-# define resolve_mount_spec(fsname) ((void)0)
+# define resolve_mount_spec(fsname, fstype) ((void)0)
#endif
#ifndef MNTTYPE_SWAP
@@ -151,7 +151,7 @@ static int swap_enable_disable(char *device)
int err = 0;
int quiet = 0;
- resolve_mount_spec(&device);
+ resolve_mount_spec(&device, NULL);
if (do_swapoff) {
err = swapoff(device);
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c
index 9a5f6abce..007d2b737 100644
--- a/util-linux/volume_id/get_devname.c
+++ b/util-linux/volume_id/get_devname.c
@@ -28,6 +28,8 @@ static struct uuidCache_s {
const char *type;
} *uuidCache;
+static unsigned char devices_scanned;
+
/* Returns !0 on error.
* Otherwise, returns malloc'ed strings for label and uuid
* (and they can't be NULL, although they can be "").
@@ -116,8 +118,6 @@ static struct uuidCache_s*
uuidcache_init(int scan_devices)
{
dbg("DBG: uuidCache=%x, uuidCache");
- if (uuidCache)
- return uuidCache;
/* We were scanning /proc/partitions
* and /proc/sys/dev/cdrom/info here.
@@ -129,21 +129,22 @@ uuidcache_init(int scan_devices)
* This is unacceptably complex. Let's just scan /dev.
* (Maybe add scanning of /sys/block/XXX/dev for devices
* somehow not having their /dev/XXX entries created?) */
- if (scan_devices) {
+ if (scan_devices && !devices_scanned) {
recursive_action("/dev", ACTION_RECURSE,
uuidcache_check_device, /* file_action */
NULL, /* dir_action */
NULL /* userData */
);
+ devices_scanned = 1;
}
return uuidCache;
}
+#ifdef UNUSED
#define UUID 1
#define VOL 2
-#ifdef UNUSED
static char *
get_spec_by_x(int n, const char *t, int *majorPtr, int *minorPtr)
{
@@ -254,49 +255,39 @@ int add_to_uuid_cache(const char *device)
/* Used by mount and findfs */
-
-char *get_devname_from_label(const char *spec)
+int resolve_mount_spec(char **fsname, char **fstype)
{
- struct uuidCache_s *uc;
+ struct uuidCache_s *uc = NULL;
+ enum { NONE = 0, UUID, LABEL } nametype =
+ is_prefixed_with(*fsname, "UUID=") ? UUID :
+ is_prefixed_with(*fsname, "LABEL=") ? LABEL :
+ NONE;
- uc = uuidcache_init(/*scan_devices:*/ 1);
- while (uc) {
- if (uc->label[0] && strcmp(spec, uc->label) == 0) {
- return xstrdup(uc->device);
- }
- uc = uc->next;
+ if (nametype) {
+ uc = uuidcache_init(/*scan_devices:*/ 1);
+ } else if (fstype) {
+ uc = uuidcache_init(/*scan_devices:*/ 0);
+ add_to_uuid_cache(*fsname);
}
- return NULL;
-}
-
-char *get_devname_from_uuid(const char *spec)
-{
- struct uuidCache_s *uc;
-
- uc = uuidcache_init(/*scan_devices:*/ 1);
- while (uc) {
- /* case of hex numbers doesn't matter */
- if (strcasecmp(spec, uc->uc_uuid) == 0) {
- return xstrdup(uc->device);
+ if (nametype || fstype) {
+ while (uc) {
+ if ((nametype == NONE && strcmp(*fsname, uc->device) == 0) ||
+ (nametype == UUID && strcasecmp(*fsname + 5, uc->uc_uuid) == 0) ||
+ (nametype == LABEL && uc->label[0] && strcmp(*fsname + 6, uc->label) == 0)) {
+ break;
+ }
+ uc = uc->next;
}
- uc = uc->next;
}
- return NULL;
-}
-int resolve_mount_spec(char **fsname)
-{
- char *tmp = *fsname;
+ if (!uc)
+ return 0;
- if (is_prefixed_with(*fsname, "UUID="))
- tmp = get_devname_from_uuid(*fsname + 5);
- else if (is_prefixed_with(*fsname, "LABEL="))
- tmp = get_devname_from_label(*fsname + 6);
+ if (nametype)
+ *fsname = xstrdup(uc->device);
- if (tmp == *fsname)
- return 0; /* no UUID= or LABEL= prefix found */
+ if (fstype)
+ *fstype = xstrdup(uc->type);
- if (tmp)
- *fsname = tmp;
return 1;
}
--
2.34.1
_______________________________________________
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