Skip to content

Commit f9688b2

Browse files
sterlingjensenbehlendorf
authored andcommitted
Drop path prefix workaround
Canonicalization, the source of the trouble, was disabled in 9000a9f. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes #11295
1 parent fad85e5 commit f9688b2

File tree

2 files changed

+40
-61
lines changed

2 files changed

+40
-61
lines changed

cmd/mount_zfs/mount_zfs.c

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,53 +43,30 @@
4343
libzfs_handle_t *g_zfs;
4444

4545
/*
46-
* Return the pool/dataset to mount given the name passed to mount. This
47-
* is expected to be of the form pool/dataset, however may also refer to
48-
* a block device if that device contains a valid zfs label.
46+
* Opportunistically convert a target string into a pool name. If the
47+
* string does not represent a block device with a valid zfs label
48+
* then it is passed through without modification.
4949
*/
5050
static void
5151
parse_dataset(const char *target, char **dataset)
5252
{
53-
/*
54-
* We expect a pool/dataset to be provided, however if we're
55-
* given a device which is a member of a zpool we attempt to
56-
* extract the pool name stored in the label. Given the pool
57-
* name we can mount the root dataset.
58-
*/
59-
int fd = open(target, O_RDONLY);
60-
if (fd >= 0) {
61-
nvlist_t *config = NULL;
62-
if (zpool_read_label(fd, &config, NULL) != 0)
63-
config = NULL;
64-
if (close(fd))
65-
perror("close");
66-
67-
if (config) {
68-
char *name = NULL;
69-
if (!nvlist_lookup_string(config,
70-
ZPOOL_CONFIG_POOL_NAME, &name))
71-
(void) strlcpy(*dataset, name, PATH_MAX);
72-
nvlist_free(config);
73-
if (name)
74-
return;
75-
}
76-
}
53+
/* Assume pool/dataset is more likely */
54+
strlcpy(*dataset, target, PATH_MAX);
7755

78-
/*
79-
* If a file or directory in your current working directory is
80-
* named 'dataset' then mount(8) will prepend your current working
81-
* directory to the dataset. There is no way to prevent this
82-
* behavior so we simply check for it and strip the prepended
83-
* patch when it is added.
84-
*/
85-
char cwd[PATH_MAX];
86-
if (getcwd(cwd, PATH_MAX) != NULL) {
87-
int len = strlen(cwd);
88-
/* Do not add one when cwd already ends in a trailing '/' */
89-
if (strncmp(cwd, target, len) == 0)
90-
target += len + (cwd[len-1] != '/');
56+
int fd = open(target, O_RDONLY | O_CLOEXEC);
57+
if (fd < 0)
58+
return;
59+
60+
nvlist_t *cfg = NULL;
61+
if (zpool_read_label(fd, &cfg, NULL) == 0) {
62+
char *nm = NULL;
63+
if (!nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &nm))
64+
strlcpy(*dataset, nm, PATH_MAX);
65+
nvlist_free(cfg);
9166
}
92-
strlcpy(*dataset, target, PATH_MAX);
67+
68+
if (close(fd))
69+
perror("close");
9370
}
9471

9572
/*

tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_013_pos.ksh

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,37 @@
2525
verify_runnable "both"
2626

2727
set -A vdevs $(get_disklist_fullpath $TESTPOOL)
28-
vdev=${vdevs[0]}
29-
mntpoint=$TESTDIR/$TESTPOOL
30-
helper="mount.zfs -o zfsutil"
31-
fs=$TESTPOOL/$TESTFS
28+
typeset -r mntpoint=$(get_prop mountpoint $TESTPOOL)
29+
typeset -r helper="mount.zfs -o zfsutil"
30+
typeset -r fs=$TESTPOOL/$TESTFS
3231

3332
function cleanup
3433
{
35-
log_must force_unmount $vdev
36-
[[ -d $mntpoint ]] && log_must rm -rf $mntpoint
34+
cd $STF_SUITE
35+
[[ -d $TESTDIR/$$ ]] && (rm -rf $TESTDIR/$$ || log_fail)
36+
mounted && zfs $mountcmd $TESTPOOL
3737
return 0
3838
}
3939
log_onexit cleanup
4040

4141
log_note "Verify zfs mount helper functions for both devices and pools"
4242

4343
# Ensure that the ZFS filesystem is unmounted
44-
force_unmount $fs
45-
log_must mkdir -p $mntpoint
44+
force_unmount $TESTPOOL
4645

4746
log_note "Verify '<dataset> <path>'"
4847
log_must $helper $fs $mntpoint
4948
log_must ismounted $fs
5049
force_unmount $fs
5150

52-
log_note "Verify '\$PWD/<pool> <path>' prefix workaround"
53-
log_must $helper $PWD/$fs $mntpoint
54-
log_must ismounted $fs
55-
force_unmount $fs
51+
log_note "Verify mount(8) does not canonicalize before calling helper"
52+
# Canonicalization is confused by files in PWD matching [device|mountpoint]
53+
mkdir -p $TESTDIR/$$/$TESTPOOL && cd $TESTDIR/$$ || log_fail
54+
# The env flag directs zfs to exec /bin/mount, which then calls helper
55+
log_must eval ZFS_MOUNT_HELPER=1 zfs $mountcmd -v $TESTPOOL
56+
# mount (2.35.2) still suffers from a cosmetic PWD prefix bug
57+
log_must mounted $TESTPOOL
58+
force_unmount $TESTPOOL
5659

5760
log_note "Verify '-f <dataset> <path>' fakemount"
5861
log_must $helper -f $fs $mntpoint
@@ -63,14 +66,13 @@ log_must ${helper},ro -v $fs $mntpoint
6366
log_must ismounted $fs
6467
force_unmount $fs
6568

66-
log_note "Verify '<device> <path>'"
67-
log_must $helper $vdev $mntpoint
68-
log_must ismounted $mntpoint
69-
log_must umount $TESTPOOL
70-
7169
log_note "Verify '-o abc -s <device> <path>' sloppy option"
72-
log_must ${helper},abc -s $vdev $mntpoint
73-
log_must ismounted $mntpoint
74-
log_must umount $TESTPOOL
70+
log_must ${helper},abc -s ${vdevs[0]} $mntpoint
71+
log_must mounted $mntpoint
72+
force_unmount $TESTPOOL
73+
74+
log_note "Verify '<device> <path>'"
75+
log_must $helper ${vdevs[0]} $mntpoint
76+
log_must mounted $mntpoint
7577

7678
log_pass "zfs mount helper correctly handles both device and pool strings"

0 commit comments

Comments
 (0)