Deleted Added
full compact
iovctl.c (282346) iovctl.c (285063)
1/*-
2 * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/usr.sbin/iovctl/iovctl.c 282346 2015-05-02 17:45:52Z oshogbo $");
28__FBSDID("$FreeBSD: head/usr.sbin/iovctl/iovctl.c 285063 2015-07-02 21:58:10Z oshogbo $");
29
30#include <sys/param.h>
31#include <sys/iov.h>
29
30#include <sys/param.h>
31#include <sys/iov.h>
32#include <sys/dnv.h>
33#include <sys/nv.h>
32
34
33#include <dnv.h>
34#include <err.h>
35#include <errno.h>
36#include <fcntl.h>
35#include <err.h>
36#include <errno.h>
37#include <fcntl.h>
37#include <nv.h>
38#include <regex.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43
44#include "iovctl.h"
45
46static void config_action(const char *filename, int dryrun);
47static void delete_action(const char *device, int dryrun);
48static void print_schema(const char *device);
49
50/*
51 * Fetch the config schema from the kernel via ioctl. This function has to
52 * call the ioctl twice: the first returns the amount of memory that we need
53 * to allocate for the schema, and the second actually fetches the schema.
54 */
55static nvlist_t *
56get_schema(int fd)
57{
58 struct pci_iov_schema arg;
59 nvlist_t *schema;
60 int error;
61
62 /* Do the ioctl() once to fetch the size of the schema. */
63 arg.schema = NULL;
64 arg.len = 0;
65 arg.error = 0;
66 error = ioctl(fd, IOV_GET_SCHEMA, &arg);
67 if (error != 0)
68 err(1, "Could not fetch size of config schema");
69
70 arg.schema = malloc(arg.len);
71 if (arg.schema == NULL)
72 err(1, "Could not allocate %zu bytes for schema",
73 arg.len);
74
75 /* Now do the ioctl() for real to get the schema. */
76 error = ioctl(fd, IOV_GET_SCHEMA, &arg);
77 if (error != 0 || arg.error != 0) {
78 if (arg.error != 0)
79 errno = arg.error;
80 err(1, "Could not fetch config schema");
81 }
82
83 schema = nvlist_unpack(arg.schema, arg.len, NV_FLAG_IGNORE_CASE);
84 if (schema == NULL)
85 err(1, "Could not unpack schema");
86
87 free(arg.schema);
88 return (schema);
89}
90
91/*
92 * Call the ioctl that activates SR-IOV and creates the VFs.
93 */
94static void
95config_iov(int fd, const char *dev_name, const nvlist_t *config, int dryrun)
96{
97 struct pci_iov_arg arg;
98 int error;
99
100 arg.config = nvlist_pack(config, &arg.len);
101 if (arg.config == NULL)
102 err(1, "Could not pack configuration");
103
104 if (dryrun) {
105 printf("Would enable SR-IOV on device '%s'.\n", dev_name);
106 printf(
107 "The following configuration parameters would be used:\n");
108 nvlist_fdump(config, stdout);
109 printf(
110 "The configuration parameters consume %zu bytes when packed.\n",
111 arg.len);
112 } else {
113 error = ioctl(fd, IOV_CONFIG, &arg);
114 if (error != 0)
115 err(1, "Failed to configure SR-IOV");
116 }
117
118 free(arg.config);
119}
120
121static int
122open_device(const char *dev_name)
123{
124 char *dev;
125 int fd;
126 size_t copied, size;
127 long path_max;
128
129 path_max = pathconf("/dev", _PC_PATH_MAX);
130 if (path_max < 0)
131 err(1, "Could not get maximum path length");
132
133 size = path_max;
134 dev = malloc(size);
135 if (dev == NULL)
136 err(1, "Could not allocate memory for device path");
137
138 if (dev_name[0] == '/')
139 copied = strlcpy(dev, dev_name, size);
140 else
141 copied = snprintf(dev, size, "/dev/iov/%s", dev_name);
142
143 /* >= to account for null terminator. */
144 if (copied >= size)
145 errx(1, "Provided file name too long");
146
147 fd = open(dev, O_RDWR);
148 if (fd < 0)
149 err(1, "Could not open device '%s'", dev);
150
151 free(dev);
152 return (fd);
153}
154
155static void
156usage(void)
157{
158
159 warnx("Usage: iovctl -C -f <config file> [-n]");
160 warnx(" iovctl -D [-d <PF device> | -f <config file>] [-n]");
161 warnx(" iovctl -S [-d <PF device> | -f <config file>]");
162 exit(1);
163
164}
165
166enum main_action {
167 NONE,
168 CONFIG,
169 DELETE,
170 PRINT_SCHEMA,
171};
172
173int
174main(int argc, char **argv)
175{
176 char *device;
177 const char *filename;
178 int ch, dryrun;
179 enum main_action action;
180
181 device = NULL;
182 filename = NULL;
183 dryrun = 0;
184 action = NONE;
185
186 while ((ch = getopt(argc, argv, "Cd:Df:nS")) != -1) {
187 switch (ch) {
188 case 'C':
189 if (action != NONE) {
190 warnx(
191 "Only one of -C, -D or -S may be specified");
192 usage();
193 }
194 action = CONFIG;
195 break;
196 case 'd':
197 device = strdup(optarg);
198 break;
199 case 'D':
200 if (action != NONE) {
201 warnx(
202 "Only one of -C, -D or -S may be specified");
203 usage();
204 }
205 action = DELETE;
206 break;
207 case 'f':
208 filename = optarg;
209 break;
210 case 'n':
211 dryrun = 1;
212 break;
213 case 'S':
214 if (action != NONE) {
215 warnx(
216 "Only one of -C, -D or -S may be specified");
217 usage();
218 }
219 action = PRINT_SCHEMA;
220 break;
221 case '?':
222 warnx("Unrecognized argument '-%c'\n", optopt);
223 usage();
224 break;
225 }
226 }
227
228 if (device != NULL && filename != NULL) {
229 warnx("Only one of the -d and -f flags may be specified");
230 usage();
231 }
232
233 if (device == NULL && filename == NULL) {
234 warnx("Either the -d or -f flag must be specified");
235 usage();
236 }
237
238 switch (action) {
239 case CONFIG:
240 if (filename == NULL) {
241 warnx("-d flag cannot be used with the -C flag");
242 usage();
243 }
244 config_action(filename, dryrun);
245 break;
246 case DELETE:
247 if (device == NULL)
248 device = find_device(filename);
249 delete_action(device, dryrun);
250 free(device);
251 break;
252 case PRINT_SCHEMA:
253 if (dryrun) {
254 warnx("-n flag cannot be used with the -S flag");
255 usage();
256 }
257 if (device == NULL)
258 device = find_device(filename);
259 print_schema(device);
260 free(device);
261 break;
262 default:
263 usage();
264 break;
265 }
266
267 exit(0);
268}
269
270static void
271config_action(const char *filename, int dryrun)
272{
273 char *dev;
274 nvlist_t *schema, *config;
275 int fd;
276
277 dev = find_device(filename);
278 fd = open(dev, O_RDWR);
279 if (fd < 0)
280 err(1, "Could not open device '%s'", dev);
281
282 schema = get_schema(fd);
283 config = parse_config_file(filename, schema);
284 if (config == NULL)
285 errx(1, "Could not parse config");
286
287 config_iov(fd, dev, config, dryrun);
288
289 nvlist_destroy(config);
290 nvlist_destroy(schema);
291 free(dev);
292 close(fd);
293}
294
295static void
296delete_action(const char *dev_name, int dryrun)
297{
298 int fd, error;
299
300 fd = open_device(dev_name);
301
302 if (dryrun)
303 printf("Would attempt to delete all VF children of '%s'\n",
304 dev_name);
305 else {
306 error = ioctl(fd, IOV_DELETE);
307 if (error != 0)
308 err(1, "Failed to delete VFs");
309 }
310
311 close(fd);
312}
313
314static void
315print_default_value(const nvlist_t *parameter, const char *type)
316{
317 const uint8_t *mac;
318 size_t size;
319
320 if (strcasecmp(type, "bool") == 0)
321 printf(" (default = %s)",
322 nvlist_get_bool(parameter, DEFAULT_SCHEMA_NAME) ? "true" :
323 "false");
324 else if (strcasecmp(type, "string") == 0)
325 printf(" (default = %s)",
326 nvlist_get_string(parameter, DEFAULT_SCHEMA_NAME));
327 else if (strcasecmp(type, "uint8_t") == 0)
328 printf(" (default = %ju)",
329 (uintmax_t)nvlist_get_number(parameter,
330 DEFAULT_SCHEMA_NAME));
331 else if (strcasecmp(type, "uint16_t") == 0)
332 printf(" (default = %ju)",
333 (uintmax_t)nvlist_get_number(parameter,
334 DEFAULT_SCHEMA_NAME));
335 else if (strcasecmp(type, "uint32_t") == 0)
336 printf(" (default = %ju)",
337 (uintmax_t)nvlist_get_number(parameter,
338 DEFAULT_SCHEMA_NAME));
339 else if (strcasecmp(type, "uint64_t") == 0)
340 printf(" (default = %ju)",
341 (uintmax_t)nvlist_get_number(parameter,
342 DEFAULT_SCHEMA_NAME));
343 else if (strcasecmp(type, "unicast-mac") == 0) {
344 mac = nvlist_get_binary(parameter, DEFAULT_SCHEMA_NAME, &size);
345 printf(" (default = %02x:%02x:%02x:%02x:%02x:%02x)", mac[0],
346 mac[1], mac[2], mac[3], mac[4], mac[5]);
347 } else
348 errx(1, "Unexpected type in schema: '%s'", type);
349}
350
351static void
352print_subsystem_schema(const nvlist_t * subsystem_schema)
353{
354 const char *name, *type;
355 const nvlist_t *parameter;
356 void *it;
357 int nvtype;
358
359 it = NULL;
360 while ((name = nvlist_next(subsystem_schema, &nvtype, &it)) != NULL) {
361 parameter = nvlist_get_nvlist(subsystem_schema, name);
362 type = nvlist_get_string(parameter, TYPE_SCHEMA_NAME);
363
364 printf("\t%s : %s", name, type);
365 if (dnvlist_get_bool(parameter, REQUIRED_SCHEMA_NAME, false))
366 printf(" (required)");
367 else if (nvlist_exists(parameter, DEFAULT_SCHEMA_NAME))
368 print_default_value(parameter, type);
369 else
370 printf(" (optional)");
371 printf("\n");
372 }
373}
374
375static void
376print_schema(const char *dev_name)
377{
378 nvlist_t *schema;
379 const nvlist_t *iov_schema, *driver_schema, *pf_schema, *vf_schema;
380 int fd;
381
382 fd = open_device(dev_name);
383 schema = get_schema(fd);
384
385 pf_schema = nvlist_get_nvlist(schema, PF_CONFIG_NAME);
386 iov_schema = nvlist_get_nvlist(pf_schema, IOV_CONFIG_NAME);
387 driver_schema = nvlist_get_nvlist(pf_schema, DRIVER_CONFIG_NAME);
388 printf(
389"The following configuration parameters may be configured on the PF:\n");
390 print_subsystem_schema(iov_schema);
391 print_subsystem_schema(driver_schema);
392
393 vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME);
394 iov_schema = nvlist_get_nvlist(vf_schema, IOV_CONFIG_NAME);
395 driver_schema = nvlist_get_nvlist(vf_schema, DRIVER_CONFIG_NAME);
396 printf(
397"\nThe following configuration parameters may be configured on a VF:\n");
398 print_subsystem_schema(iov_schema);
399 print_subsystem_schema(driver_schema);
400
401 nvlist_destroy(schema);
402 close(fd);
403}
38#include <regex.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43
44#include "iovctl.h"
45
46static void config_action(const char *filename, int dryrun);
47static void delete_action(const char *device, int dryrun);
48static void print_schema(const char *device);
49
50/*
51 * Fetch the config schema from the kernel via ioctl. This function has to
52 * call the ioctl twice: the first returns the amount of memory that we need
53 * to allocate for the schema, and the second actually fetches the schema.
54 */
55static nvlist_t *
56get_schema(int fd)
57{
58 struct pci_iov_schema arg;
59 nvlist_t *schema;
60 int error;
61
62 /* Do the ioctl() once to fetch the size of the schema. */
63 arg.schema = NULL;
64 arg.len = 0;
65 arg.error = 0;
66 error = ioctl(fd, IOV_GET_SCHEMA, &arg);
67 if (error != 0)
68 err(1, "Could not fetch size of config schema");
69
70 arg.schema = malloc(arg.len);
71 if (arg.schema == NULL)
72 err(1, "Could not allocate %zu bytes for schema",
73 arg.len);
74
75 /* Now do the ioctl() for real to get the schema. */
76 error = ioctl(fd, IOV_GET_SCHEMA, &arg);
77 if (error != 0 || arg.error != 0) {
78 if (arg.error != 0)
79 errno = arg.error;
80 err(1, "Could not fetch config schema");
81 }
82
83 schema = nvlist_unpack(arg.schema, arg.len, NV_FLAG_IGNORE_CASE);
84 if (schema == NULL)
85 err(1, "Could not unpack schema");
86
87 free(arg.schema);
88 return (schema);
89}
90
91/*
92 * Call the ioctl that activates SR-IOV and creates the VFs.
93 */
94static void
95config_iov(int fd, const char *dev_name, const nvlist_t *config, int dryrun)
96{
97 struct pci_iov_arg arg;
98 int error;
99
100 arg.config = nvlist_pack(config, &arg.len);
101 if (arg.config == NULL)
102 err(1, "Could not pack configuration");
103
104 if (dryrun) {
105 printf("Would enable SR-IOV on device '%s'.\n", dev_name);
106 printf(
107 "The following configuration parameters would be used:\n");
108 nvlist_fdump(config, stdout);
109 printf(
110 "The configuration parameters consume %zu bytes when packed.\n",
111 arg.len);
112 } else {
113 error = ioctl(fd, IOV_CONFIG, &arg);
114 if (error != 0)
115 err(1, "Failed to configure SR-IOV");
116 }
117
118 free(arg.config);
119}
120
121static int
122open_device(const char *dev_name)
123{
124 char *dev;
125 int fd;
126 size_t copied, size;
127 long path_max;
128
129 path_max = pathconf("/dev", _PC_PATH_MAX);
130 if (path_max < 0)
131 err(1, "Could not get maximum path length");
132
133 size = path_max;
134 dev = malloc(size);
135 if (dev == NULL)
136 err(1, "Could not allocate memory for device path");
137
138 if (dev_name[0] == '/')
139 copied = strlcpy(dev, dev_name, size);
140 else
141 copied = snprintf(dev, size, "/dev/iov/%s", dev_name);
142
143 /* >= to account for null terminator. */
144 if (copied >= size)
145 errx(1, "Provided file name too long");
146
147 fd = open(dev, O_RDWR);
148 if (fd < 0)
149 err(1, "Could not open device '%s'", dev);
150
151 free(dev);
152 return (fd);
153}
154
155static void
156usage(void)
157{
158
159 warnx("Usage: iovctl -C -f <config file> [-n]");
160 warnx(" iovctl -D [-d <PF device> | -f <config file>] [-n]");
161 warnx(" iovctl -S [-d <PF device> | -f <config file>]");
162 exit(1);
163
164}
165
166enum main_action {
167 NONE,
168 CONFIG,
169 DELETE,
170 PRINT_SCHEMA,
171};
172
173int
174main(int argc, char **argv)
175{
176 char *device;
177 const char *filename;
178 int ch, dryrun;
179 enum main_action action;
180
181 device = NULL;
182 filename = NULL;
183 dryrun = 0;
184 action = NONE;
185
186 while ((ch = getopt(argc, argv, "Cd:Df:nS")) != -1) {
187 switch (ch) {
188 case 'C':
189 if (action != NONE) {
190 warnx(
191 "Only one of -C, -D or -S may be specified");
192 usage();
193 }
194 action = CONFIG;
195 break;
196 case 'd':
197 device = strdup(optarg);
198 break;
199 case 'D':
200 if (action != NONE) {
201 warnx(
202 "Only one of -C, -D or -S may be specified");
203 usage();
204 }
205 action = DELETE;
206 break;
207 case 'f':
208 filename = optarg;
209 break;
210 case 'n':
211 dryrun = 1;
212 break;
213 case 'S':
214 if (action != NONE) {
215 warnx(
216 "Only one of -C, -D or -S may be specified");
217 usage();
218 }
219 action = PRINT_SCHEMA;
220 break;
221 case '?':
222 warnx("Unrecognized argument '-%c'\n", optopt);
223 usage();
224 break;
225 }
226 }
227
228 if (device != NULL && filename != NULL) {
229 warnx("Only one of the -d and -f flags may be specified");
230 usage();
231 }
232
233 if (device == NULL && filename == NULL) {
234 warnx("Either the -d or -f flag must be specified");
235 usage();
236 }
237
238 switch (action) {
239 case CONFIG:
240 if (filename == NULL) {
241 warnx("-d flag cannot be used with the -C flag");
242 usage();
243 }
244 config_action(filename, dryrun);
245 break;
246 case DELETE:
247 if (device == NULL)
248 device = find_device(filename);
249 delete_action(device, dryrun);
250 free(device);
251 break;
252 case PRINT_SCHEMA:
253 if (dryrun) {
254 warnx("-n flag cannot be used with the -S flag");
255 usage();
256 }
257 if (device == NULL)
258 device = find_device(filename);
259 print_schema(device);
260 free(device);
261 break;
262 default:
263 usage();
264 break;
265 }
266
267 exit(0);
268}
269
270static void
271config_action(const char *filename, int dryrun)
272{
273 char *dev;
274 nvlist_t *schema, *config;
275 int fd;
276
277 dev = find_device(filename);
278 fd = open(dev, O_RDWR);
279 if (fd < 0)
280 err(1, "Could not open device '%s'", dev);
281
282 schema = get_schema(fd);
283 config = parse_config_file(filename, schema);
284 if (config == NULL)
285 errx(1, "Could not parse config");
286
287 config_iov(fd, dev, config, dryrun);
288
289 nvlist_destroy(config);
290 nvlist_destroy(schema);
291 free(dev);
292 close(fd);
293}
294
295static void
296delete_action(const char *dev_name, int dryrun)
297{
298 int fd, error;
299
300 fd = open_device(dev_name);
301
302 if (dryrun)
303 printf("Would attempt to delete all VF children of '%s'\n",
304 dev_name);
305 else {
306 error = ioctl(fd, IOV_DELETE);
307 if (error != 0)
308 err(1, "Failed to delete VFs");
309 }
310
311 close(fd);
312}
313
314static void
315print_default_value(const nvlist_t *parameter, const char *type)
316{
317 const uint8_t *mac;
318 size_t size;
319
320 if (strcasecmp(type, "bool") == 0)
321 printf(" (default = %s)",
322 nvlist_get_bool(parameter, DEFAULT_SCHEMA_NAME) ? "true" :
323 "false");
324 else if (strcasecmp(type, "string") == 0)
325 printf(" (default = %s)",
326 nvlist_get_string(parameter, DEFAULT_SCHEMA_NAME));
327 else if (strcasecmp(type, "uint8_t") == 0)
328 printf(" (default = %ju)",
329 (uintmax_t)nvlist_get_number(parameter,
330 DEFAULT_SCHEMA_NAME));
331 else if (strcasecmp(type, "uint16_t") == 0)
332 printf(" (default = %ju)",
333 (uintmax_t)nvlist_get_number(parameter,
334 DEFAULT_SCHEMA_NAME));
335 else if (strcasecmp(type, "uint32_t") == 0)
336 printf(" (default = %ju)",
337 (uintmax_t)nvlist_get_number(parameter,
338 DEFAULT_SCHEMA_NAME));
339 else if (strcasecmp(type, "uint64_t") == 0)
340 printf(" (default = %ju)",
341 (uintmax_t)nvlist_get_number(parameter,
342 DEFAULT_SCHEMA_NAME));
343 else if (strcasecmp(type, "unicast-mac") == 0) {
344 mac = nvlist_get_binary(parameter, DEFAULT_SCHEMA_NAME, &size);
345 printf(" (default = %02x:%02x:%02x:%02x:%02x:%02x)", mac[0],
346 mac[1], mac[2], mac[3], mac[4], mac[5]);
347 } else
348 errx(1, "Unexpected type in schema: '%s'", type);
349}
350
351static void
352print_subsystem_schema(const nvlist_t * subsystem_schema)
353{
354 const char *name, *type;
355 const nvlist_t *parameter;
356 void *it;
357 int nvtype;
358
359 it = NULL;
360 while ((name = nvlist_next(subsystem_schema, &nvtype, &it)) != NULL) {
361 parameter = nvlist_get_nvlist(subsystem_schema, name);
362 type = nvlist_get_string(parameter, TYPE_SCHEMA_NAME);
363
364 printf("\t%s : %s", name, type);
365 if (dnvlist_get_bool(parameter, REQUIRED_SCHEMA_NAME, false))
366 printf(" (required)");
367 else if (nvlist_exists(parameter, DEFAULT_SCHEMA_NAME))
368 print_default_value(parameter, type);
369 else
370 printf(" (optional)");
371 printf("\n");
372 }
373}
374
375static void
376print_schema(const char *dev_name)
377{
378 nvlist_t *schema;
379 const nvlist_t *iov_schema, *driver_schema, *pf_schema, *vf_schema;
380 int fd;
381
382 fd = open_device(dev_name);
383 schema = get_schema(fd);
384
385 pf_schema = nvlist_get_nvlist(schema, PF_CONFIG_NAME);
386 iov_schema = nvlist_get_nvlist(pf_schema, IOV_CONFIG_NAME);
387 driver_schema = nvlist_get_nvlist(pf_schema, DRIVER_CONFIG_NAME);
388 printf(
389"The following configuration parameters may be configured on the PF:\n");
390 print_subsystem_schema(iov_schema);
391 print_subsystem_schema(driver_schema);
392
393 vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME);
394 iov_schema = nvlist_get_nvlist(vf_schema, IOV_CONFIG_NAME);
395 driver_schema = nvlist_get_nvlist(vf_schema, DRIVER_CONFIG_NAME);
396 printf(
397"\nThe following configuration parameters may be configured on a VF:\n");
398 print_subsystem_schema(iov_schema);
399 print_subsystem_schema(driver_schema);
400
401 nvlist_destroy(schema);
402 close(fd);
403}