summaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorDon Brady <[email protected]>2018-09-02 15:14:01 -0400
committerBrian Behlendorf <[email protected]>2018-09-02 12:14:01 -0700
commitb83a0e2dc1b972e3ae5c0c17b714941b4604dfd6 (patch)
tree1165e7298a9ca33290ec1988da3acb4cd5065541 /cmd
parente8bcb693d6a19962291e4429f2dc4ce60693bef7 (diff)
Add basic zfs ioc input nvpair validation
We want newer versions of libzfs_core to run against an existing zfs kernel module (i.e. a deferred reboot or module reload after an update). Programmatically document, via a zfs_ioc_key_t, the valid arguments for the ioc commands that rely on nvpair input arguments (i.e. non legacy commands from libzfs_core). Automatically verify the expected pairs before dispatching a command. This initial phase focuses on the non-legacy ioctls. A follow-on change can address the legacy ioctl input from the zfs_cmd_t. The zfs_ioc_key_t for zfs_keys_channel_program looks like: static const zfs_ioc_key_t zfs_keys_channel_program[] = { {"program", DATA_TYPE_STRING, 0}, {"arg", DATA_TYPE_UNKNOWN, 0}, {"sync", DATA_TYPE_BOOLEAN_VALUE, ZK_OPTIONAL}, {"instrlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, {"memlimit", DATA_TYPE_UINT64, ZK_OPTIONAL}, }; Introduce four input errors to identify specific input failures (in addition to generic argument value errors like EINVAL, ERANGE, EBADF, and E2BIG). ZFS_ERR_IOC_CMD_UNAVAIL the ioctl number is not supported by kernel ZFS_ERR_IOC_ARG_UNAVAIL an input argument is not supported by kernel ZFS_ERR_IOC_ARG_REQUIRED a required input argument is missing ZFS_ERR_IOC_ARG_BADTYPE an input argument has an invalid type Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Don Brady <[email protected]> Closes #7780
Diffstat (limited to 'cmd')
-rw-r--r--cmd/zfs/zfs_main.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index cf2d8f2d5..1a91b031a 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -7238,7 +7238,7 @@ zfs_do_bookmark(int argc, char **argv)
fnvlist_free(nvl);
if (ret != 0) {
- const char *err_msg;
+ const char *err_msg = NULL;
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf),
@@ -7265,11 +7265,13 @@ zfs_do_bookmark(int argc, char **argv)
err_msg = "dataset does not exist";
break;
default:
- err_msg = "unknown error";
+ (void) zfs_standard_error(g_zfs, ret, errbuf);
break;
}
- (void) fprintf(stderr, "%s: %s\n", errbuf,
- dgettext(TEXT_DOMAIN, err_msg));
+ if (err_msg != NULL) {
+ (void) fprintf(stderr, "%s: %s\n", errbuf,
+ dgettext(TEXT_DOMAIN, err_msg));
+ }
}
return (ret != 0);
@@ -7285,7 +7287,7 @@ zfs_do_channel_program(int argc, char **argv)
int ret, fd, c;
char *progbuf, *filename, *poolname;
size_t progsize, progread;
- nvlist_t *outnvl;
+ nvlist_t *outnvl = NULL;
uint64_t instrlimit = ZCP_DEFAULT_INSTRLIMIT;
uint64_t memlimit = ZCP_DEFAULT_MEMLIMIT;
boolean_t sync_flag = B_TRUE, json_output = B_FALSE;
@@ -7412,8 +7414,9 @@ zfs_do_channel_program(int argc, char **argv)
* falling back on strerror() for an unexpected return code.
*/
char *errstring = NULL;
+ const char *msg = gettext("Channel program execution failed");
uint64_t instructions = 0;
- if (nvlist_exists(outnvl, ZCP_RET_ERROR)) {
+ if (outnvl != NULL && nvlist_exists(outnvl, ZCP_RET_ERROR)) {
(void) nvlist_lookup_string(outnvl,
ZCP_RET_ERROR, &errstring);
if (errstring == NULL)
@@ -7442,12 +7445,12 @@ zfs_do_channel_program(int argc, char **argv)
"programs must be run as root.";
break;
default:
- errstring = strerror(ret);
+ (void) zfs_standard_error(g_zfs, ret, msg);
}
}
- (void) fprintf(stderr,
- gettext("Channel program execution failed:\n%s\n"),
- errstring);
+ if (errstring != NULL)
+ (void) fprintf(stderr, "%s:\n%s\n", msg, errstring);
+
if (ret == ETIME && instructions != 0)
(void) fprintf(stderr,
gettext("%llu Lua instructions\n"),