summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/beadm/beadm.c62
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm_loader.c26
-rw-r--r--usr/src/cmd/ctfconvert/ctfconvert.c54
-rw-r--r--usr/src/cmd/eeprom/i386/Makefile1
-rw-r--r--usr/src/cmd/eeprom/i386/benv.c278
-rw-r--r--usr/src/cmd/truss/codes.c4
-rw-r--r--usr/src/cmd/zinject/translate.c4
7 files changed, 394 insertions, 35 deletions
diff --git a/usr/src/cmd/beadm/beadm.c b/usr/src/cmd/beadm/beadm.c
index 1dfc8afcd1..8a89c380b4 100644
--- a/usr/src/cmd/beadm/beadm.c
+++ b/usr/src/cmd/beadm/beadm.c
@@ -129,7 +129,7 @@ usage(void)
"\n"
"\tsubcommands:\n"
"\n"
- "\tbeadm activate [-v] beName\n"
+ "\tbeadm activate [-v] [-t | -T] beName\n"
"\tbeadm create [-a] [-d BE_desc]\n"
"\t\t[-o property=value] ... [-p zpool] \n"
"\t\t[-e nonActiveBe | beName@snapshot] [-v] beName\n"
@@ -343,7 +343,7 @@ print_be_nodes(const char *be_name, boolean_t parsable, struct hdr_info *hdr,
be_node_list_t *cur_be;
for (cur_be = nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
- char active[3] = "-\0";
+ char active[4] = "-\0\0";
int ai = 0;
const char *datetime_fmt = "%F %R";
const char *name = cur_be->be_node_name;
@@ -374,9 +374,12 @@ print_be_nodes(const char *be_name, boolean_t parsable, struct hdr_info *hdr,
active[ai++] = 'N';
if (cur_be->be_active_on_boot) {
if (!cur_be->be_global_active)
- active[ai] = 'b';
+ active[ai++] = 'b';
else
- active[ai] = 'R';
+ active[ai++] = 'R';
+ }
+ if (cur_be->be_active_next) {
+ active[ai] = 'T';
}
nicenum(used, buf, sizeof (buf));
@@ -472,7 +475,7 @@ print_fmt_nodes(const char *be_name, enum be_fmt be_fmt, boolean_t parsable,
be_node_list_t *cur_be;
for (cur_be = nodes; cur_be != NULL; cur_be = cur_be->be_next_node) {
- char active[3] = "-\0";
+ char active[4] = "-\0\0";
int ai = 0;
const char *datetime_fmt = "%F %R";
const char *name = cur_be->be_node_name;
@@ -495,7 +498,9 @@ print_fmt_nodes(const char *be_name, enum be_fmt be_fmt, boolean_t parsable,
if (cur_be->be_active)
active[ai++] = 'N';
if (cur_be->be_active_on_boot)
- active[ai] = 'R';
+ active[ai++] = 'R';
+ if (cur_be->be_active_next)
+ active[ai++] = 'T';
nicenum(used, buf, sizeof (buf));
if (be_fmt & BE_FMT_DATASET)
@@ -606,6 +611,20 @@ be_nvl_alloc(nvlist_t **nvlp)
}
static int
+be_nvl_add_boolean(nvlist_t *nvl, const char *name, boolean_t val)
+{
+ assert(nvl != NULL);
+
+ if (nvlist_add_boolean_value(nvl, name, val) != 0) {
+ (void) fprintf(stderr, _("nvlist_add_boolean_value failed for "
+ "%s (%s).\n"), name, val ? "true" : "false");
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
be_nvl_add_string(nvlist_t *nvl, const char *name, const char *val)
{
assert(nvl != NULL);
@@ -654,12 +673,30 @@ be_do_activate(int argc, char **argv)
int err = 1;
int c;
char *obe_name;
+ boolean_t nextboot = B_FALSE;
+ boolean_t do_nextboot = B_FALSE;
- while ((c = getopt(argc, argv, "v")) != -1) {
+ while ((c = getopt(argc, argv, "vtT")) != -1) {
switch (c) {
case 'v':
libbe_print_errors(B_TRUE);
break;
+ case 't':
+ if (do_nextboot == B_TRUE) {
+ usage();
+ return (1);
+ }
+ nextboot = B_TRUE;
+ do_nextboot = B_TRUE;
+ break;
+ case 'T':
+ if (do_nextboot == B_TRUE) {
+ usage();
+ return (1);
+ }
+ nextboot = B_FALSE;
+ do_nextboot = B_TRUE;
+ break;
default:
usage();
return (1);
@@ -682,11 +719,20 @@ be_do_activate(int argc, char **argv)
if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
goto out;
+ if (do_nextboot == B_TRUE) {
+ if (be_nvl_add_boolean(be_attrs, BE_ATTR_ACTIVE_NEXTBOOT,
+ nextboot) != 0)
+ goto out;
+ }
+
err = be_activate(be_attrs);
switch (err) {
case BE_SUCCESS:
- (void) printf(_("Activated successfully\n"));
+ if (do_nextboot && nextboot == B_FALSE)
+ (void) printf(_("Temporary activation removed\n"));
+ else
+ (void) printf(_("Activated successfully\n"));
break;
case BE_ERR_BE_NOENT:
(void) fprintf(stderr, _("%s does not exist or appear "
diff --git a/usr/src/cmd/boot/bootadm/bootadm_loader.c b/usr/src/cmd/boot/bootadm/bootadm_loader.c
index 15bf160745..e2d99b24b0 100644
--- a/usr/src/cmd/boot/bootadm/bootadm_loader.c
+++ b/usr/src/cmd/boot/bootadm/bootadm_loader.c
@@ -66,6 +66,7 @@ extern char *bam_root;
typedef struct menu_entry {
int me_idx;
boolean_t me_active;
+ boolean_t me_active_next;
char *me_title;
char *me_type;
char *me_bootfs;
@@ -114,6 +115,10 @@ print_menu_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
(void) snprintf(buf, bufsize, "%s", entry->me_type);
break;
case 4:
+ if (entry->me_active_next == B_TRUE) {
+ (void) snprintf(buf, bufsize, " T");
+ break;
+ }
if (entry->me_active == B_TRUE)
(void) snprintf(buf, bufsize, " *");
else
@@ -266,6 +271,26 @@ menu_active_on_boot(be_node_list_t *be_nodes, const char *bootfs)
return (rv);
}
+/*
+ * Get the be_active_next for bootfs.
+ */
+static boolean_t
+menu_active_next(be_node_list_t *be_nodes, const char *bootfs)
+{
+ be_node_list_t *be_node;
+ boolean_t rv = B_FALSE;
+
+ for (be_node = be_nodes; be_node != NULL;
+ be_node = be_node->be_next_node) {
+ if (strcmp(be_node->be_root_ds, bootfs) == 0) {
+ rv = be_node->be_active_next;
+ break;
+ }
+ }
+
+ return (rv);
+}
+
error_t
menu_read(struct menu_lst *menu, char *menu_path)
{
@@ -335,6 +360,7 @@ menu_read(struct menu_lst *menu, char *menu_path)
mp->me_type = type;
mp->me_bootfs = bootfs;
mp->me_active = menu_active_on_boot(be_nodes, bootfs);
+ mp->me_active_next = menu_active_next(be_nodes, bootfs);
STAILQ_INSERT_TAIL(menu, mp, me_next);
title = NULL;
diff --git a/usr/src/cmd/ctfconvert/ctfconvert.c b/usr/src/cmd/ctfconvert/ctfconvert.c
index 0e37d070f1..bae355be22 100644
--- a/usr/src/cmd/ctfconvert/ctfconvert.c
+++ b/usr/src/cmd/ctfconvert/ctfconvert.c
@@ -37,6 +37,7 @@
#define CTFCONVERT_FATAL 1
#define CTFCONVERT_USAGE 2
+#define CTFCONVERT_DEFAULT_BATCHSIZE 256
#define CTFCONVERT_DEFAULT_NTHREADS 4
static char *ctfconvert_progname;
@@ -67,17 +68,21 @@ ctfconvert_usage(const char *fmt, ...)
va_end(ap);
}
- (void) fprintf(stderr, "Usage: %s [-ims] [-j nthrs] [-l label | "
- "-L labelenv] [-o outfile] input\n"
+ (void) fprintf(stderr, "Usage: %s [-ikm] [-j nthrs] [-l label | "
+ "-L labelenv] [-b batchsize]\n"
+ " [-o outfile] input\n"
"\n"
+ "\t-b batch process this many dies at a time (default %d)\n"
"\t-i ignore files not built partially from C sources\n"
- "\t-j use nthrs threads to perform the merge\n"
+ "\t-j use nthrs threads to perform the merge (default %d)\n"
"\t-k keep around original input file on failure\n"
- "\t-m allow input to have missing debug info\n"
- "\t-o copy input to outfile and add CTF\n"
"\t-l set output container's label to specified value\n"
- "\t-L set output container's label to value from environment\n",
- ctfconvert_progname);
+ "\t-L set output container's label to value from environment\n"
+ "\t-m allow input to have missing debug info\n"
+ "\t-o copy input to outfile and add CTF\n",
+ ctfconvert_progname,
+ CTFCONVERT_DEFAULT_BATCHSIZE,
+ CTFCONVERT_DEFAULT_NTHREADS);
}
/*
@@ -226,35 +231,48 @@ main(int argc, char *argv[])
int c, ifd, err;
boolean_t keep = B_FALSE;
uint_t flags = 0;
+ uint_t bsize = CTFCONVERT_DEFAULT_BATCHSIZE;
uint_t nthreads = CTFCONVERT_DEFAULT_NTHREADS;
const char *outfile = NULL;
const char *label = NULL;
const char *infile = NULL;
char *tmpfile;
ctf_file_t *ofp;
- long argj;
- char *eptr;
char buf[4096];
boolean_t optx = B_FALSE;
boolean_t ignore_non_c = B_FALSE;
ctfconvert_progname = basename(argv[0]);
- while ((c = getopt(argc, argv, ":ij:kl:L:mo:X")) != -1) {
+ while ((c = getopt(argc, argv, ":b:ij:kl:L:mo:X")) != -1) {
switch (c) {
+ case 'b': {
+ long argno;
+ const char *errstr;
+
+ argno = strtonum(optarg, 1, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ ctfconvert_fatal("invalid argument for -b: "
+ "%s - %s\n", optarg, errstr);
+ }
+ bsize = (uint_t)argno;
+ break;
+ }
case 'i':
ignore_non_c = B_TRUE;
break;
- case 'j':
- errno = 0;
- argj = strtol(optarg, &eptr, 10);
- if (errno != 0 || argj == LONG_MAX ||
- argj > 1024 || *eptr != '\0') {
+ case 'j': {
+ long argno;
+ const char *errstr;
+
+ argno = strtonum(optarg, 1, 1024, &errstr);
+ if (errstr != NULL) {
ctfconvert_fatal("invalid argument for -j: "
- "%s\n", optarg);
+ "%s - %s\n", optarg, errstr);
}
- nthreads = (uint_t)argj;
+ nthreads = (uint_t)argno;
break;
+ }
case 'k':
keep = B_TRUE;
break;
@@ -309,7 +327,7 @@ main(int argc, char *argv[])
if (outfile != NULL && strcmp(infile, outfile) != 0)
keep = B_TRUE;
- ofp = ctf_fdconvert(ifd, label, nthreads, flags, &err, buf,
+ ofp = ctf_fdconvert(ifd, label, bsize, nthreads, flags, &err, buf,
sizeof (buf));
if (ofp == NULL) {
/*
diff --git a/usr/src/cmd/eeprom/i386/Makefile b/usr/src/cmd/eeprom/i386/Makefile
index d47fd832d1..baf63db774 100644
--- a/usr/src/cmd/eeprom/i386/Makefile
+++ b/usr/src/cmd/eeprom/i386/Makefile
@@ -28,6 +28,7 @@ SRCDIR = ..
include $(SRCDIR)/Makefile.com
OBJS += benv.o benv_kvm.o
+LDLIBS += -lzfsbootenv
.KEEP_STATE:
diff --git a/usr/src/cmd/eeprom/i386/benv.c b/usr/src/cmd/eeprom/i386/benv.c
index 0e3a89f0b7..697bcd9a19 100644
--- a/usr/src/cmd/eeprom/i386/benv.c
+++ b/usr/src/cmd/eeprom/i386/benv.c
@@ -27,10 +27,12 @@
#include "benv.h"
#include <ctype.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <sys/mman.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
+#include <libzfsbootenv.h>
/*
* Usage: % eeprom [-v] [-f prom_dev] [-]
@@ -671,33 +673,295 @@ get_line(void)
return (NULL);
}
+static int
+add_pair(const char *name, const char *nvlist, const char *key,
+ const char *type, const char *value)
+{
+ void *data, *nv;
+ size_t size;
+ int rv;
+ char *end;
+
+ rv = lzbe_nvlist_get(name, nvlist, &nv);
+ if (rv != 0)
+ return (rv);
+
+ data = NULL;
+ rv = EINVAL;
+ if (strcmp(type, "DATA_TYPE_STRING") == 0) {
+ data = (void *)(uintptr_t)value;
+ size = strlen(data) + 1;
+ rv = lzbe_add_pair(nv, key, type, data, size);
+ } else if (strcmp(type, "DATA_TYPE_UINT64") == 0) {
+ uint64_t v;
+
+ v = strtoull(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_INT64") == 0) {
+ int64_t v;
+
+ v = strtoll(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_UINT32") == 0) {
+ u_longlong_t lv;
+ uint32_t v;
+
+ lv = strtoull(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv > UINT32_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_INT32") == 0) {
+ longlong_t lv;
+ int32_t v;
+
+ lv = strtoll(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv < INT32_MIN || lv > INT32_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_UINT16") == 0) {
+ uint32_t lv;
+ uint16_t v;
+
+ lv = strtoul(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv > UINT16_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_INT16") == 0) {
+ int32_t lv;
+ int16_t v;
+
+ v = strtol(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv < INT16_MIN || lv > INT16_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_UINT8") == 0) {
+ uint32_t lv;
+ uint8_t v;
+
+ lv = strtoul(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv > UINT8_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_INT8") == 0) {
+ int32_t lv;
+ int8_t v;
+
+ lv = strtol(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv < INT8_MIN || lv > INT8_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_BYTE") == 0) {
+ uint32_t lv;
+ uint8_t v;
+
+ lv = strtoul(value, &end, 0);
+ if (errno != 0 || *end != '\0')
+ goto done;
+ if (lv > UINT8_MAX)
+ goto done;
+ v = lv;
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ } else if (strcmp(type, "DATA_TYPE_BOOLEAN_VALUE") == 0) {
+ int32_t v;
+
+ v = strtol(value, &end, 0);
+ if (errno != 0 || *end != '\0') {
+ if (strcasecmp(value, "YES") == 0)
+ v = 1;
+ else if (strcasecmp(value, "NO") == 0)
+ v = 0;
+ else if (strcasecmp(value, "true") == 0)
+ v = 1;
+ else if (strcasecmp(value, "false") == 0)
+ v = 0;
+ else goto done;
+ }
+ size = sizeof (v);
+ rv = lzbe_add_pair(nv, key, type, &v, size);
+ }
+
+ if (rv == 0)
+ rv = lzbe_nvlist_set(name, nvlist, nv);
+
+done:
+ lzbe_nvlist_free(nv);
+ return (rv);
+}
+
+static int
+delete_pair(const char *name, const char *nvlist, const char *key)
+{
+ void *nv;
+ int rv;
+
+ rv = lzbe_nvlist_get(name, nvlist, &nv);
+ if (rv == 0)
+ rv = lzbe_remove_pair(nv, key);
+
+ if (rv == 0)
+ rv = lzbe_nvlist_set(name, nvlist, nv);
+
+ lzbe_nvlist_free(nv);
+ return (rv);
+}
+
+static int
+usage(char *name)
+{
+ char *usage = "Usage: %s [-v] [-f prom-device]"
+ " [variable[=value] ...]\n"
+ "%s [-z pool] [-d key] [-k key -t type -v value] [-p]\n"
+ "%s [-z pool] -n nvlist [-d key] [-k key -t type -v value] [-p]\n";
+
+ return (_error(NO_PERROR, usage, name, name, name));
+}
+
int
main(int argc, char **argv)
{
int c;
int updates = 0;
- char *usage = "Usage: %s [-v] [-f prom-device]"
- " [variable[=value] ...]";
eplist_t *elist;
benv_des_t *bd;
char *file = NULL;
+ bool bootenv, bootenv_print, bootenv_delete;
+ char *name, *key, *type, *nvlist, *value;
+ lzbe_flags_t flag = lzbe_add;
+
+ nvlist = NULL;
+ name = "rpool";
+ key = NULL;
+ type = NULL;
+ value = NULL;
+ bootenv = false;
+ bootenv_print = false;
+ bootenv_delete = false;
setpname(argv[0]);
- while ((c = getopt(argc, argv, "f:Itv")) != -1)
+ while ((c = getopt(argc, argv, "bd:f:k:n:prt:v:z:")) != -1)
switch (c) {
- case 'v':
- verbose++;
+ case 'b':
+ bootenv = true;
+ break;
+ case 'd':
+ if (bootenv) {
+ bootenv_delete = true;
+ key = optarg;
+ } else {
+ exit(usage(argv[0]));
+ }
break;
case 'f':
file = optarg;
break;
+ case 'k':
+ if (bootenv)
+ key = optarg;
+ else
+ exit(usage(argv[0]));
+ break;
+ case 'n':
+ if (bootenv)
+ nvlist = optarg;
+ else
+ exit(usage(argv[0]));
+ break;
+ case 'p':
+ if (bootenv)
+ bootenv_print = true;
+ else
+ exit(usage(argv[0]));
+ break;
+ case 'r':
+ if (bootenv)
+ flag = lzbe_replace;
+ else
+ exit(usage(argv[0]));
+ break;
case 't':
- test++;
+ if (bootenv)
+ type = optarg;
+ else
+ test++;
+ break;
+ case 'v':
+ if (bootenv)
+ value = optarg;
+ else
+ verbose++;
+ break;
+ case 'z':
+ if (bootenv)
+ name = optarg;
+ else
+ exit(usage(argv[0]));
break;
default:
- exit(_error(NO_PERROR, usage, argv[0]));
+ exit(usage(argv[0]));
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (bootenv) {
+ int rv = 0;
+
+ if (argc == 1)
+ value = argv[0];
+
+ if (bootenv_print)
+ return (lzbe_bootenv_print(name, nvlist, stdout));
+
+ if (key != NULL || value != NULL) {
+ if (type == NULL)
+ type = "DATA_TYPE_STRING";
+
+ if (bootenv_delete)
+ rv = delete_pair(name, nvlist, key);
+ else if (key == NULL)
+ rv = lzbe_set_boot_device(name, flag, value);
+ else
+ rv = add_pair(name, nvlist, key, type, value);
+
+ if (rv == 0)
+ printf("zfs bootenv is successfully written\n");
+ else
+ printf("error: %s\n", strerror(rv));
}
+ return (rv);
+ }
(void) uname(&uts_buf);
bd = new_bd();
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index 107b36ee87..fd6e02bad6 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -1301,6 +1301,10 @@ const struct ioc {
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_CHANGE_KEY, "ZFS_IOC_CHANGE_KEY",
"zfs_cmd_t" },
+ { (uint_t)ZFS_IOC_SET_BOOTENV, "ZFS_IOC_SET_BOOTENV",
+ "zfs_cmd_t" },
+ { (uint_t)ZFS_IOC_GET_BOOTENV, "ZFS_IOC_GET_BOOTENV",
+ "zfs_cmd_t" },
/* kssl ioctls */
{ (uint_t)KSSL_ADD_ENTRY, "KSSL_ADD_ENTRY",
diff --git a/usr/src/cmd/zinject/translate.c b/usr/src/cmd/zinject/translate.c
index 546009ab88..32cff30e16 100644
--- a/usr/src/cmd/zinject/translate.c
+++ b/usr/src/cmd/zinject/translate.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2020 by Delphix. All rights reserved.
*/
#include <libzfs.h>
@@ -407,7 +407,7 @@ translate_device(const char *pool, const char *device, err_type_t label_type,
record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1;
break;
case TYPE_LABEL_PAD2:
- record->zi_start = offsetof(vdev_label_t, vl_pad2);
+ record->zi_start = offsetof(vdev_label_t, vl_be);
record->zi_end = record->zi_start + VDEV_PAD_SIZE - 1;
break;
}