Print this page
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 <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
*** 183,195 ****
{ "set", zpool_do_set, HELP_SET },
};
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
! zpool_command_t *current_command;
static char history_str[HIS_MAX_RECORD_LEN];
!
static uint_t timestamp_fmt = NODATE;
static const char *
get_usage(zpool_help_t idx) {
switch (idx) {
--- 183,195 ----
{ "set", zpool_do_set, HELP_SET },
};
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
! static zpool_command_t *current_command;
static char history_str[HIS_MAX_RECORD_LEN];
! static boolean_t log_history = B_TRUE;
static uint_t timestamp_fmt = NODATE;
static const char *
get_usage(zpool_help_t idx) {
switch (idx) {
*** 933,943 ****
(void) fprintf(stderr, gettext("could not destroy '%s': "
"could not unmount datasets\n"), zpool_get_name(zhp));
return (1);
}
! ret = (zpool_destroy(zhp) != 0);
zpool_close(zhp);
return (ret);
}
--- 933,946 ----
(void) fprintf(stderr, gettext("could not destroy '%s': "
"could not unmount datasets\n"), zpool_get_name(zhp));
return (1);
}
! /* The history must be logged as part of the export */
! log_history = B_FALSE;
!
! ret = (zpool_destroy(zhp, history_str) != 0);
zpool_close(zhp);
return (ret);
}
*** 997,1010 ****
ret = 1;
zpool_close(zhp);
continue;
}
if (hardforce) {
! if (zpool_export_force(zhp) != 0)
ret = 1;
! } else if (zpool_export(zhp, force) != 0) {
ret = 1;
}
zpool_close(zhp);
}
--- 1000,1016 ----
ret = 1;
zpool_close(zhp);
continue;
}
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
if (hardforce) {
! if (zpool_export_force(zhp, history_str) != 0)
ret = 1;
! } else if (zpool_export(zhp, force, history_str) != 0) {
ret = 1;
}
zpool_close(zhp);
}
*** 4267,4276 ****
--- 4273,4290 ----
ret = zpool_upgrade(zhp, cbp->cb_version);
if (!ret) {
(void) printf(gettext("Successfully upgraded "
"'%s'\n\n"), zpool_get_name(zhp));
}
+ /*
+ * If they did "zpool upgrade -a", then we could
+ * be doing ioctls to different pools. We need
+ * to log this history once to each pool, and bypass
+ * the normal history logging that happens in main().
+ */
+ (void) zpool_log_history(g_zfs, history_str);
+ log_history = B_FALSE;
}
} else if (cbp->cb_newer && !SPA_VERSION_IS_SUPPORTED(version)) {
assert(!cbp->cb_all);
if (cbp->cb_first) {
*** 4489,4500 ****
return (ret);
}
typedef struct hist_cbdata {
boolean_t first;
! int longfmt;
! int internal;
} hist_cbdata_t;
/*
* Print out the command history for a specific pool.
*/
--- 4503,4514 ----
return (ret);
}
typedef struct hist_cbdata {
boolean_t first;
! boolean_t longfmt;
! boolean_t internal;
} hist_cbdata_t;
/*
* Print out the command history for a specific pool.
*/
*** 4502,4526 ****
get_history_one(zpool_handle_t *zhp, void *data)
{
nvlist_t *nvhis;
nvlist_t **records;
uint_t numrecords;
- char *cmdstr;
- char *pathstr;
- uint64_t dst_time;
- time_t tsec;
- struct tm t;
- char tbuf[30];
int ret, i;
- uint64_t who;
- struct passwd *pwd;
- char *hostname;
- char *zonename;
- char internalstr[MAXPATHLEN];
hist_cbdata_t *cb = (hist_cbdata_t *)data;
- uint64_t txg;
- uint64_t ievent;
cb->first = B_FALSE;
(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
--- 4516,4527 ----
*** 4528,4595 ****
return (ret);
verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
&records, &numrecords) == 0);
for (i = 0; i < numrecords; i++) {
! if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
! &dst_time) != 0)
! continue;
! /* is it an internal event or a standard event? */
! if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
! &cmdstr) != 0) {
! if (cb->internal == 0)
! continue;
! if (nvlist_lookup_uint64(records[i],
! ZPOOL_HIST_INT_EVENT, &ievent) != 0)
continue;
! verify(nvlist_lookup_uint64(records[i],
! ZPOOL_HIST_TXG, &txg) == 0);
! verify(nvlist_lookup_string(records[i],
! ZPOOL_HIST_INT_STR, &pathstr) == 0);
! if (ievent >= LOG_END)
continue;
- (void) snprintf(internalstr,
- sizeof (internalstr),
- "[internal %s txg:%lld] %s",
- zfs_history_event_names[ievent], txg,
- pathstr);
- cmdstr = internalstr;
}
! tsec = dst_time;
! (void) localtime_r(&tsec, &t);
! (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
! (void) printf("%s %s", tbuf, cmdstr);
if (!cb->longfmt) {
(void) printf("\n");
continue;
}
(void) printf(" [");
! if (nvlist_lookup_uint64(records[i],
! ZPOOL_HIST_WHO, &who) == 0) {
! pwd = getpwuid((uid_t)who);
! if (pwd)
! (void) printf("user %s on",
! pwd->pw_name);
! else
! (void) printf("user %d on",
! (int)who);
! } else {
! (void) printf(gettext("no info]\n"));
! continue;
! }
! if (nvlist_lookup_string(records[i],
! ZPOOL_HIST_HOST, &hostname) == 0) {
! (void) printf(" %s", hostname);
! }
! if (nvlist_lookup_string(records[i],
! ZPOOL_HIST_ZONE, &zonename) == 0) {
! (void) printf(":%s", zonename);
}
-
(void) printf("]");
(void) printf("\n");
}
(void) printf("\n");
nvlist_free(nvhis);
--- 4529,4626 ----
return (ret);
verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
&records, &numrecords) == 0);
for (i = 0; i < numrecords; i++) {
! nvlist_t *rec = records[i];
! char tbuf[30] = "";
! if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
! time_t tsec;
! struct tm t;
!
! tsec = fnvlist_lookup_uint64(records[i],
! ZPOOL_HIST_TIME);
! (void) localtime_r(&tsec, &t);
! (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
! }
! if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
! (void) printf("%s %s", tbuf,
! fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
! } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
! int ievent =
! fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
! if (!cb->internal)
continue;
! if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
! (void) printf("%s unrecognized record:\n",
! tbuf);
! dump_nvlist(rec, 4);
continue;
}
! (void) printf("%s [internal %s txg:%lld] %s", tbuf,
! zfs_history_event_names[ievent],
! fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
! fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
! } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
! if (!cb->internal)
! continue;
! (void) printf("%s [txg:%lld] %s", tbuf,
! fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
! fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
! if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
! (void) printf(" %s (%llu)",
! fnvlist_lookup_string(rec,
! ZPOOL_HIST_DSNAME),
! fnvlist_lookup_uint64(rec,
! ZPOOL_HIST_DSID));
! }
! (void) printf(" %s", fnvlist_lookup_string(rec,
! ZPOOL_HIST_INT_STR));
! } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
! if (!cb->internal)
! continue;
! (void) printf("%s ioctl %s\n", tbuf,
! fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
! if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
! (void) printf(" input:\n");
! dump_nvlist(fnvlist_lookup_nvlist(rec,
! ZPOOL_HIST_INPUT_NVL), 8);
! }
! if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
! (void) printf(" output:\n");
! dump_nvlist(fnvlist_lookup_nvlist(rec,
! ZPOOL_HIST_OUTPUT_NVL), 8);
! }
! } else {
! if (!cb->internal)
! continue;
! (void) printf("%s unrecognized record:\n", tbuf);
! dump_nvlist(rec, 4);
! }
if (!cb->longfmt) {
(void) printf("\n");
continue;
}
(void) printf(" [");
! if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
! uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
! struct passwd *pwd = getpwuid(who);
! (void) printf("user %d ", (int)who);
! if (pwd != NULL)
! (void) printf("(%s) ", pwd->pw_name);
! }
! if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
! (void) printf("on %s",
! fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
! }
! if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
! (void) printf(":%s",
! fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
}
(void) printf("]");
(void) printf("\n");
}
(void) printf("\n");
nvlist_free(nvhis);
*** 4600,4611 ****
/*
* zpool history <pool>
*
* Displays the history of commands that modified pools.
*/
-
-
int
zpool_do_history(int argc, char **argv)
{
hist_cbdata_t cbdata = { 0 };
int ret;
--- 4631,4640 ----
*** 4614,4627 ****
cbdata.first = B_TRUE;
/* check options */
while ((c = getopt(argc, argv, "li")) != -1) {
switch (c) {
case 'l':
! cbdata.longfmt = 1;
break;
case 'i':
! cbdata.internal = 1;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
--- 4643,4656 ----
cbdata.first = B_TRUE;
/* check options */
while ((c = getopt(argc, argv, "li")) != -1) {
switch (c) {
case 'l':
! cbdata.longfmt = B_TRUE;
break;
case 'i':
! cbdata.internal = B_TRUE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
*** 4842,4853 ****
* Special case '-?'
*/
if (strcmp(cmdname, "-?") == 0)
usage(B_TRUE);
! zpool_set_history_str("zpool", argc, argv, history_str);
! verify(zpool_stage_history(g_zfs, history_str) == 0);
/*
* Run the appropriate command.
*/
if (find_command_idx(cmdname, &i) == 0) {
--- 4871,4881 ----
* Special case '-?'
*/
if (strcmp(cmdname, "-?") == 0)
usage(B_TRUE);
! zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
/*
* Run the appropriate command.
*/
if (find_command_idx(cmdname, &i) == 0) {
*** 4870,4879 ****
--- 4898,4910 ----
(void) fprintf(stderr, gettext("unrecognized "
"command '%s'\n"), cmdname);
usage(B_FALSE);
}
+ 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.