Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once

Reviewed by: George Wilson <[email protected]>
Reviewed by: Chris Siden <[email protected]>
Reviewed by: Garrett D'Amore <[email protected]>
Reviewed by: Bill Pijewski <[email protected]>
Reviewed by: Dan Kruchinin <[email protected]>
Approved by: Eric Schrock <[email protected]>

References:
  illumos/illumos-gate@4445fff

Ported-by: Tim Chase <[email protected]>
Closes openzfs#1293

Porting notes:

Add "nosleep" versions of the fnvlist_dup, fnvlist_merge, fnvlist_alloc
and fnvlist_pack functions with a suffix of "_nosleep".  They simply
perform their allocations with the KM_NOSLEEP flag.

Add zvol minor device creation to the new zfs_snapshot_nvl function.

Remove the logging of the "release" operation in
dsl_dataset_user_release_sync().  The logging caused a null dereference
because ds->ds_dir is zeroed in dsl_dataset_destroy_sync() and the
logging functions try to get the ds name via the dsl_dataset_name()
function. I've got no idea why this particular code would have worked
in Illumos.  This code has subsequently been completely reworked in
Illumos commit 3b2aab1 (3464 zfs synctask code needs restructuring).

Squash some "may be used uninitialized" warning/erorrs.

Fix some printf format warnings for %lld and %llu.

Apply a few spa_writeable() changes that were made to Illumos in
illumos/illumos-gate.git@cd1c8b8 as part of the 3112, 3113, 3114 and
3115 fixes.

Add a missing call to fnvlist_free(nvl) in log_internal() that was added
in Illumos to fix issue 3085 but couldn't be ported to ZoL at the time
(openzfs/zfs@9e11c73) because it depended on future work.
  • Loading branch information
ahrens authored and dweeezil committed Aug 12, 2013
1 parent 570d6ed commit 1726a6b
Show file tree
Hide file tree
Showing 57 changed files with 2,926 additions and 1,518 deletions.
41 changes: 36 additions & 5 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <sys/arc.h>
#include <sys/ddt.h>
#include <sys/zfeature.h>
#include <zfs_comutil.h>
#undef ZFS_MAXNAMELEN
#include <libzfs.h>

Expand Down Expand Up @@ -209,6 +210,27 @@ dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
nvlist_free(nv);
}

/* ARGSUSED */
static void
dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
{
spa_history_phys_t *shp = data;

if (shp == NULL)
return;

(void) printf("\t\tpool_create_len = %llu\n",
(u_longlong_t)shp->sh_pool_create_len);
(void) printf("\t\tphys_max_off = %llu\n",
(u_longlong_t)shp->sh_phys_max_off);
(void) printf("\t\tbof = %llu\n",
(u_longlong_t)shp->sh_bof);
(void) printf("\t\teof = %llu\n",
(u_longlong_t)shp->sh_eof);
(void) printf("\t\trecords_lost = %llu\n",
(u_longlong_t)shp->sh_records_lost);
}

static void
zdb_nicenum(uint64_t num, char *buf)
{
Expand Down Expand Up @@ -869,21 +891,22 @@ dump_history(spa_t *spa)
for (i = 0; i < num; i++) {
uint64_t time, txg, ievent;
char *cmd, *intstr;
boolean_t printed = B_FALSE;

if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
&time) != 0)
continue;
goto next;
if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
&cmd) != 0) {
if (nvlist_lookup_uint64(events[i],
ZPOOL_HIST_INT_EVENT, &ievent) != 0)
continue;
goto next;
verify(nvlist_lookup_uint64(events[i],
ZPOOL_HIST_TXG, &txg) == 0);
verify(nvlist_lookup_string(events[i],
ZPOOL_HIST_INT_STR, &intstr) == 0);
if (ievent >= LOG_END)
continue;
if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS)
goto next;

(void) snprintf(internalstr,
sizeof (internalstr),
Expand All @@ -896,6 +919,14 @@ dump_history(spa_t *spa)
(void) localtime_r(&tsec, &t);
(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
(void) printf("%s %s\n", tbuf, cmd);
printed = B_TRUE;

next:
if (dump_opt['h'] > 1) {
if (!printed)
(void) printf("unrecognized record:\n");
dump_nvlist(events[i], 2);
}
}
}

Expand Down Expand Up @@ -1529,7 +1560,7 @@ static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
dump_zap, /* other ZAP */
dump_zap, /* persistent error log */
dump_uint8, /* SPA history */
dump_uint64, /* SPA history offsets */
dump_history_offsets, /* SPA history offsets */
dump_zap, /* Pool properties */
dump_zap, /* DSL permissions */
dump_acl, /* ZFS ACL */
Expand Down
3 changes: 2 additions & 1 deletion cmd/zfs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ zfs_LDADD = \
$(top_builddir)/lib/libnvpair/libnvpair.la \
$(top_builddir)/lib/libuutil/libuutil.la \
$(top_builddir)/lib/libzpool/libzpool.la \
$(top_builddir)/lib/libzfs/libzfs.la
$(top_builddir)/lib/libzfs/libzfs.la \
$(top_builddir)/lib/libzfs_core/libzfs_core.la

zfs_LDFLAGS = -pthread -lm $(ZLIB) -lrt -ldl $(LIBUUID) $(LIBBLKID)
105 changes: 80 additions & 25 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <time.h>

#include <libzfs.h>
#include <libzfs_core.h>
#include <zfs_prop.h>
#include <zfs_deleg.h>
#include <libuutil.h>
Expand All @@ -71,6 +72,7 @@ libzfs_handle_t *g_zfs;

static FILE *mnttab_file;
static char history_str[HIS_MAX_RECORD_LEN];
static boolean_t log_history = B_TRUE;

static int zfs_do_clone(int argc, char **argv);
static int zfs_do_create(int argc, char **argv);
Expand Down Expand Up @@ -260,7 +262,7 @@ get_usage(zfs_help_t idx)
return (gettext("\tshare <-a | filesystem>\n"));
case HELP_SNAPSHOT:
return (gettext("\tsnapshot|snap [-r] [-o property=value] ... "
"<filesystem@snapname|volume@snapname>\n"));
"<filesystem@snapname|volume@snapname> ...\n"));
case HELP_UNMOUNT:
return (gettext("\tunmount [-f] "
"<-a | filesystem|mountpoint>\n"));
Expand Down Expand Up @@ -891,9 +893,9 @@ typedef struct destroy_cbdata {
nvlist_t *cb_nvl;

/* first snap in contiguous run */
zfs_handle_t *cb_firstsnap;
char *cb_firstsnap;
/* previous snap in contiguous run */
zfs_handle_t *cb_prevsnap;
char *cb_prevsnap;
int64_t cb_snapused;
char *cb_snapspec;
} destroy_cbdata_t;
Expand Down Expand Up @@ -1007,11 +1009,13 @@ destroy_print_cb(zfs_handle_t *zhp, void *arg)

if (nvlist_exists(cb->cb_nvl, name)) {
if (cb->cb_firstsnap == NULL)
cb->cb_firstsnap = zfs_handle_dup(zhp);
cb->cb_firstsnap = strdup(name);
if (cb->cb_prevsnap != NULL)
zfs_close(cb->cb_prevsnap);
free(cb->cb_prevsnap);
/* this snap continues the current range */
cb->cb_prevsnap = zfs_handle_dup(zhp);
cb->cb_prevsnap = strdup(name);
if (cb->cb_firstsnap == NULL || cb->cb_prevsnap == NULL)
nomem();
if (cb->cb_verbose) {
if (cb->cb_parsable) {
(void) printf("destroy\t%s\n", name);
Expand All @@ -1026,12 +1030,12 @@ destroy_print_cb(zfs_handle_t *zhp, void *arg)
} else if (cb->cb_firstsnap != NULL) {
/* end of this range */
uint64_t used = 0;
err = zfs_get_snapused_int(cb->cb_firstsnap,
err = lzc_snaprange_space(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
cb->cb_snapused += used;
zfs_close(cb->cb_firstsnap);
free(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
zfs_close(cb->cb_prevsnap);
free(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
zfs_close(zhp);
Expand All @@ -1048,13 +1052,13 @@ destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_cbdata_t *cb)
if (cb->cb_firstsnap != NULL) {
uint64_t used = 0;
if (err == 0) {
err = zfs_get_snapused_int(cb->cb_firstsnap,
err = lzc_snaprange_space(cb->cb_firstsnap,
cb->cb_prevsnap, &used);
}
cb->cb_snapused += used;
zfs_close(cb->cb_firstsnap);
free(cb->cb_firstsnap);
cb->cb_firstsnap = NULL;
zfs_close(cb->cb_prevsnap);
free(cb->cb_prevsnap);
cb->cb_prevsnap = NULL;
}
return (err);
Expand Down Expand Up @@ -1142,7 +1146,7 @@ zfs_do_destroy(int argc, char **argv)
{
destroy_cbdata_t cb = { 0 };
int c;
zfs_handle_t *zhp;
zfs_handle_t *zhp = NULL;
char *at;
zfs_type_t type = ZFS_TYPE_DATASET;

Expand Down Expand Up @@ -1243,7 +1247,7 @@ zfs_do_destroy(int argc, char **argv)
if (cb.cb_doclones)
err = destroy_clones(&cb);
if (err == 0) {
err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl,
err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl,
cb.cb_defer_destroy);
}
}
Expand Down Expand Up @@ -1907,9 +1911,11 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
/*
* If they did "zfs upgrade -a", then we could
* be doing ioctls to different pools. We need
* to log this history once to each pool.
* to log this history once to each pool, and bypass
* the normal history logging that happens in main().
*/
verify(zpool_stage_history(g_zfs, history_str) == 0);
(void) zpool_log_history(g_zfs, history_str);
log_history = B_FALSE;
}
if (zfs_prop_set(zhp, "version", verstr) == 0)
cb->cb_numupgraded++;
Expand Down Expand Up @@ -3422,6 +3428,32 @@ zfs_do_set(int argc, char **argv)
return (ret);
}

typedef struct snap_cbdata {
nvlist_t *sd_nvl;
boolean_t sd_recursive;
const char *sd_snapname;
} snap_cbdata_t;

static int
zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
{
snap_cbdata_t *sd = arg;
char *name;
int rv = 0;
int error;

error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
if (error == -1)
nomem();
fnvlist_add_boolean(sd->sd_nvl, name);
free(name);

if (sd->sd_recursive)
rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
zfs_close(zhp);
return (rv);
}

/*
* zfs snapshot [-r] [-o prop=value] ... <fs@snap>
*
Expand All @@ -3431,13 +3463,16 @@ zfs_do_set(int argc, char **argv)
static int
zfs_do_snapshot(int argc, char **argv)
{
boolean_t recursive = B_FALSE;
int ret = 0;
signed char c;
nvlist_t *props;
snap_cbdata_t sd = { 0 };
boolean_t multiple_snaps = B_FALSE;

if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
nomem();
if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
nomem();

/* check options */
while ((c = getopt(argc, argv, "ro:")) != -1) {
Expand All @@ -3447,7 +3482,8 @@ zfs_do_snapshot(int argc, char **argv)
return (1);
break;
case 'r':
recursive = B_TRUE;
sd.sd_recursive = B_TRUE;
multiple_snaps = B_TRUE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
Expand All @@ -3464,18 +3500,35 @@ zfs_do_snapshot(int argc, char **argv)
(void) fprintf(stderr, gettext("missing snapshot argument\n"));
goto usage;
}
if (argc > 1) {
(void) fprintf(stderr, gettext("too many arguments\n"));
goto usage;

if (argc > 1)
multiple_snaps = B_TRUE;
for (; argc > 0; argc--, argv++) {
char *atp;
zfs_handle_t *zhp;

atp = strchr(argv[0], '@');
if (atp == NULL)
goto usage;
*atp = '\0';
sd.sd_snapname = atp + 1;
zhp = zfs_open(g_zfs, argv[0],
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
if (zhp == NULL)
goto usage;
if (zfs_snapshot_cb(zhp, &sd) != 0)
goto usage;
}

ret = zfs_snapshot(g_zfs, argv[0], recursive, props);
ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
nvlist_free(sd.sd_nvl);
nvlist_free(props);
if (ret && recursive)
if (ret != 0 && multiple_snaps)
(void) fprintf(stderr, gettext("no snapshots were created\n"));
return (ret != 0);

usage:
nvlist_free(sd.sd_nvl);
nvlist_free(props);
usage(B_FALSE);
return (-1);
Expand Down Expand Up @@ -6388,8 +6441,7 @@ main(int argc, char **argv)
if ((g_zfs = libzfs_init()) == NULL)
return (1);

zpool_set_history_str("zfs", argc, argv, history_str);
verify(zpool_stage_history(g_zfs, history_str) == 0);
zfs_save_arguments(argc, argv, history_str, sizeof (history_str));

libzfs_print_on_error(g_zfs, B_TRUE);

Expand All @@ -6414,6 +6466,9 @@ main(int argc, char **argv)

(void) fclose(mnttab_file);

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

/*
* The 'ZFS_ABORT' environment variable causes us to dump core on exit
* for the purposes of running ::findleaks.
Expand Down
7 changes: 7 additions & 0 deletions cmd/zhack/zhack.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx)
zfeature_info_t *feature = arg2;

spa_feature_enable(spa, feature, tx);
spa_history_log_internal(spa, "zhack enable feature", tx,
"name=%s can_readonly=%u",
feature->fi_guid, feature->fi_can_readonly);
}

static void
Expand Down Expand Up @@ -356,6 +359,8 @@ feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
zfeature_info_t *feature = arg2;

spa_feature_incr(spa, feature, tx);
spa_history_log_internal(spa, "zhack feature incr", tx,
"name=%s", feature->fi_guid);
}

static void
Expand All @@ -365,6 +370,8 @@ feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
zfeature_info_t *feature = arg2;

spa_feature_decr(spa, feature, tx);
spa_history_log_internal(spa, "zhack feature decr", tx,
"name=%s", feature->fi_guid);
}

static void
Expand Down
Loading

0 comments on commit 1726a6b

Please sign in to comment.