Skip to content

Commit

Permalink
Fix the creation of ZPOOL_HIST_CMD pool history entries.
Browse files Browse the repository at this point in the history
Move the libzfs_fini() after the zpool_log_history() call so the
ZPOOL_HIST_CMD entry can get written.

Fix the handling of saved_poolname in zfsdev_ioctl()
which was broken as part of the stack-reduction work in
a168788.

Since ZoL destroys the TSD data in which the previously successful
ioctl()'s pool name is stored following every vop, the ZFS_IOC_LOG_HISTORY
ioctl has a very important restriction: it can only successfully write
a long entry following a successful ioctl() if no intervening vops have
been performed.  Some of zfs subcommands do perform intervening vops and
to do the logging themselves. At the moment, the "create" and "clone"
subcommands have been modified appropriately.

Signed-off-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #1998
  • Loading branch information
dweeezil authored and behlendorf committed Jan 7, 2014
1 parent 5d862cb commit fb8e608
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
13 changes: 12 additions & 1 deletion cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,11 @@ zfs_do_clone(int argc, char **argv)
if (ret == 0) {
zfs_handle_t *clone;

if (log_history) {
(void) zpool_log_history(g_zfs, history_str);
log_history = B_FALSE;
}

clone = zfs_open(g_zfs, argv[1], ZFS_TYPE_DATASET);
if (clone != NULL) {
if (zfs_get_type(clone) != ZFS_TYPE_VOLUME)
Expand Down Expand Up @@ -828,6 +833,11 @@ zfs_do_create(int argc, char **argv)
if (zfs_create(g_zfs, argv[0], type, props) != 0)
goto error;

if (log_history) {
(void) zpool_log_history(g_zfs, history_str);
log_history = B_FALSE;
}

if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
goto error;

Expand Down Expand Up @@ -6481,11 +6491,12 @@ main(int argc, char **argv)
usage(B_FALSE);
ret = 1;
}
libzfs_fini(g_zfs);

if (ret == 0 && log_history)
(void) zpool_log_history(g_zfs, history_str);

libzfs_fini(g_zfs);

/*
* The 'ZFS_ABORT' environment variable causes us to dump core on exit
* for the purposes of running ::findleaks.
Expand Down
17 changes: 9 additions & 8 deletions module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -5558,9 +5558,9 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
zfs_cmd_t *zc;
uint_t vecnum;
int error, rc, len, flag = 0;
int error, rc, len = 0, flag = 0;
const zfs_ioc_vec_t *vec;
char *saved_poolname;
char *saved_poolname = NULL;
nvlist_t *innvl = NULL;

vecnum = cmd - ZFS_IOC_FIRST;
Expand All @@ -5576,7 +5576,6 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
return (-SET_ERROR(EINVAL));

zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG);
saved_poolname = kmem_alloc(MAXNAMELEN, KM_SLEEP);

error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
if (error != 0) {
Expand Down Expand Up @@ -5626,9 +5625,9 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
goto out;

/* legacy ioctls can modify zc_name */
(void) strlcpy(saved_poolname, zc->zc_name, sizeof (saved_poolname));
len = strcspn(saved_poolname, "/@") + 1;
saved_poolname[len] = '\0';
len = strcspn(zc->zc_name, "/@#") + 1;
saved_poolname = kmem_alloc(len, KM_SLEEP);
(void) strlcpy(saved_poolname, zc->zc_name, len);

if (vec->zvec_func != NULL) {
nvlist_t *outnvl;
Expand Down Expand Up @@ -5693,10 +5692,12 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
char *s = tsd_get(zfs_allow_log_key);
if (s != NULL)
strfree(s);
(void) tsd_set(zfs_allow_log_key, strdup(saved_poolname));
(void) tsd_set(zfs_allow_log_key, saved_poolname);
} else {
if (saved_poolname != NULL)
kmem_free(saved_poolname, len);
}

kmem_free(saved_poolname, MAXNAMELEN);
kmem_free(zc, sizeof (zfs_cmd_t));
return (-error);
}
Expand Down

0 comments on commit fb8e608

Please sign in to comment.