From: Dominique Martinet <dominique.marti...@atmark-techno.com> Checking st_dev fails to identify bind mounts as mount points if the bind mount target is in the same filesystem as its parent directory, for example (simple 'mountpoint' command is util-linux's): ``` cd $(mktemp -d) mkdir src target mount --bind src target busybox mountpoint target; echo $? # target is not a mountpoint # 1 mountpoint target; echo $? # target is a mountpoint # 0 umount target rm -rf $PWD ```
Parsing /proc/mounts with getmntent (like util-linux implementation does) fixes the issue. function old new delta .rodata 79535 79529 -6 mountpoint_main 469 424 -45 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-51) Total: -51 bytes --- FWIW I've been working around this problem with a awk one-liner instead: ``` is_mountpoint() { ! awk -v dir="$1" '$5 == dir { exit 1 }' < /proc/self/mountinfo } ``` But this bit us somewhere else that wasn't using my wrapper, so figured I'd try to fix this here... and it turns out to be a size saving as well because we have a helper for mntent (find_mount_point). I'll submit it to alpine in a few weeks depending on initial feedback. util-linux/mountpoint.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/util-linux/mountpoint.c b/util-linux/mountpoint.c index 87f4cc60d8c5..0a6df5160399 100644 --- a/util-linux/mountpoint.c +++ b/util-linux/mountpoint.c @@ -69,33 +69,23 @@ int mountpoint_main(int argc UNUSED_PARAM, char **argv) errno = ENOTDIR; if (S_ISDIR(st.st_mode)) { - dev_t st_dev = st.st_dev; - ino_t st_ino = st.st_ino; - char *p = xasprintf("%s/..", arg); - - if (stat(p, &st) == 0) { - //int is_mnt = (st_dev != st.st_dev) || (st_dev == st.st_dev && st_ino == st.st_ino); - int is_not_mnt = (st_dev == st.st_dev) && (st_ino != st.st_ino); - - if (opt & OPT_d) - printf("%u:%u\n", major(st_dev), minor(st_dev)); - if (opt & OPT_n) { - const char *d = find_block_device(arg); - /* name is undefined, but device is mounted -> anonymous superblock! */ - /* happens with btrfs */ - if (!d) { - d = "UNKNOWN"; - /* TODO: iterate /proc/mounts, or /proc/self/mountinfo - * to find out the device name */ - } - printf("%s %s\n", d, arg); + bool is_not_mnt = find_mount_point(arg, 0) == NULL; + if (opt & OPT_d) + printf("%u:%u\n", major(st.st_dev), minor(st.st_dev)); + if (opt & OPT_n) { + const char *d = find_block_device(arg); + /* name is undefined, but device is mounted -> anonymous superblock! */ + /* happens with btrfs */ + if (!d) { + d = "UNKNOWN"; + /* TODO: iterate /proc/mounts, or /proc/self/mountinfo + * to find out the device name */ } - if (!(opt & (OPT_q | OPT_d | OPT_n))) - printf("%s is %sa mountpoint\n", arg, is_not_mnt ? "not " : ""); - return is_not_mnt; + printf("%s %s\n", d, arg); } - arg = p; - /* else: stat had set errno, just fall through */ + if (!(opt & (OPT_q | OPT_d | OPT_n))) + printf("%s is %sa mountpoint\n", arg, is_not_mnt ? "not " : ""); + return is_not_mnt; } err: -- 2.39.2 _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox