16691 zfstest: rootpool tests do not make sense when rootfs is not zfs
[illumos-gate.git] / usr / src / lib / libdladm / common / libdlmgmt.c
blobfe14c8b66a07569bb565d32f361e42bc16b06495
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Joyent, Inc.
24 * Copyright 2023 Oxide Computer Company
27 #include <door.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <zone.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/aggr.h>
39 #include <sys/mman.h>
40 #include <fcntl.h>
41 #include <libdladm.h>
42 #include <libdladm_impl.h>
43 #include <libdllink.h>
44 #include <libdlmgmt.h>
47 * Table of data type sizes indexed by dladm_datatype_t.
49 static size_t dladm_datatype_size[] = {
50 0, /* DLADM_TYPE_STR, use strnlen() */
51 sizeof (boolean_t), /* DLADM_TYPE_BOOLEAN */
52 sizeof (uint64_t) /* DLADM_TYPE_UINT64 */
55 static dladm_status_t
56 dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf,
57 size_t *rsizep)
59 door_arg_t darg;
60 int door_fd;
61 dladm_status_t status;
62 boolean_t reopen = B_FALSE;
64 darg.data_ptr = arg;
65 darg.data_size = asize;
66 darg.desc_ptr = NULL;
67 darg.desc_num = 0;
68 darg.rbuf = rbuf;
69 darg.rsize = *rsizep;
71 reopen:
72 /* The door descriptor is opened if it isn't already */
73 if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK)
74 return (status);
75 if (door_call(door_fd, &darg) == -1) {
77 * Stale door descriptor is possible if dlmgmtd was re-started
78 * since last door_fd open so try re-opening door file.
80 if (!reopen && errno == EBADF) {
81 (void) close(handle->door_fd);
82 handle->door_fd = -1;
83 reopen = B_TRUE;
84 goto reopen;
86 status = dladm_errno2status(errno);
88 if (status != DLADM_STATUS_OK)
89 return (status);
91 if (darg.rbuf != rbuf) {
93 * The size of the input rbuf is not big enough so that
94 * the door allocate the rbuf itself. In this case, return
95 * the required size to the caller.
97 (void) munmap(darg.rbuf, darg.rsize);
98 *rsizep = darg.rsize;
99 return (DLADM_STATUS_TOOSMALL);
100 } else if (darg.rsize != *rsizep) {
101 return (DLADM_STATUS_FAILED);
104 return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err));
108 * Allocate a new linkid with the given name. Return the new linkid.
110 dladm_status_t
111 dladm_create_datalink_id(dladm_handle_t handle, const char *link,
112 datalink_class_t class, uint32_t media, uint32_t flags,
113 datalink_id_t *linkidp)
115 dlmgmt_door_createid_t createid;
116 dlmgmt_createid_retval_t retval;
117 uint32_t dlmgmt_flags;
118 dladm_status_t status;
119 size_t sz = sizeof (retval);
121 if (link == NULL || class == DATALINK_CLASS_ALL ||
122 !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) ||
123 linkidp == NULL) {
124 return (DLADM_STATUS_BADARG);
127 if (getzoneid() != GLOBAL_ZONEID) {
129 * If we're creating this link in a non-global zone, then do
130 * not allow it to be persistent, and flag it as transient so
131 * that it will be automatically cleaned up on zone shutdown,
132 * rather than being moved to the GZ.
134 if (flags & DLADM_OPT_PERSIST)
135 return (DLADM_STATUS_TEMPONLY);
136 flags |= DLADM_OPT_TRANSIENT;
139 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
140 dlmgmt_flags |= (flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0;
141 dlmgmt_flags |= (flags & DLADM_OPT_TRANSIENT) ? DLMGMT_TRANSIENT : 0;
143 (void) strlcpy(createid.ld_link, link, MAXLINKNAMELEN);
144 createid.ld_class = class;
145 createid.ld_media = media;
146 createid.ld_flags = dlmgmt_flags;
147 createid.ld_cmd = DLMGMT_CMD_CREATE_LINKID;
148 createid.ld_prefix = (flags & DLADM_OPT_PREFIX);
150 if ((status = dladm_door_call(handle, &createid, sizeof (createid),
151 &retval, &sz)) == DLADM_STATUS_OK) {
152 *linkidp = retval.lr_linkid;
154 return (status);
158 * Destroy the given link ID.
160 dladm_status_t
161 dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
162 uint32_t flags)
164 dlmgmt_door_destroyid_t destroyid;
165 dlmgmt_destroyid_retval_t retval;
166 uint32_t dlmgmt_flags;
167 size_t sz = sizeof (retval);
169 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
170 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
172 destroyid.ld_cmd = DLMGMT_CMD_DESTROY_LINKID;
173 destroyid.ld_linkid = linkid;
174 destroyid.ld_flags = dlmgmt_flags;
176 return (dladm_door_call(handle, &destroyid, sizeof (destroyid),
177 &retval, &sz));
181 * Remap a given link ID to a new name.
183 dladm_status_t
184 dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid,
185 const char *link)
187 dlmgmt_door_remapid_t remapid;
188 dlmgmt_remapid_retval_t retval;
189 size_t sz = sizeof (retval);
191 remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID;
192 remapid.ld_linkid = linkid;
193 (void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN);
195 return (dladm_door_call(handle, &remapid, sizeof (remapid),
196 &retval, &sz));
200 * Make a given link ID active.
202 dladm_status_t
203 dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid)
205 dlmgmt_door_upid_t upid;
206 dlmgmt_upid_retval_t retval;
207 size_t sz = sizeof (retval);
209 upid.ld_cmd = DLMGMT_CMD_UP_LINKID;
210 upid.ld_linkid = linkid;
212 return (dladm_door_call(handle, &upid, sizeof (upid), &retval, &sz));
216 * Create a new link with the given name. Return the new link's handle
218 dladm_status_t
219 dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid,
220 datalink_class_t class, uint32_t media, dladm_conf_t *confp)
222 dlmgmt_door_createconf_t createconf;
223 dlmgmt_createconf_retval_t retval;
224 dladm_status_t status;
225 size_t sz = sizeof (retval);
227 if (link == NULL || confp == NULL)
228 return (DLADM_STATUS_BADARG);
230 (void) strlcpy(createconf.ld_link, link, MAXLINKNAMELEN);
231 createconf.ld_class = class;
232 createconf.ld_media = media;
233 createconf.ld_linkid = linkid;
234 createconf.ld_cmd = DLMGMT_CMD_CREATECONF;
235 confp->ds_confid = DLADM_INVALID_CONF;
237 if ((status = dladm_door_call(handle, &createconf, sizeof (createconf),
238 &retval, &sz)) == DLADM_STATUS_OK) {
239 confp->ds_readonly = B_FALSE;
240 confp->ds_confid = retval.lr_confid;
242 return (status);
246 * An active physical link reported by the dlmgmtd daemon might not be active
247 * anymore as this link might be removed during system shutdown. Check its
248 * real status by calling dladm_phys_info().
250 dladm_status_t
251 i_dladm_phys_status(dladm_handle_t handle, datalink_id_t linkid,
252 uint32_t *flagsp)
254 dladm_phys_attr_t dpa;
255 dladm_status_t status;
257 assert((*flagsp) & DLMGMT_ACTIVE);
259 status = dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE);
260 if (status == DLADM_STATUS_NOTFOUND) {
262 * No active status, this link was removed. Update its status
263 * in the daemon and delete all active linkprops.
265 * Note that the operation could fail. If it does, return
266 * failure now since otherwise dladm_set_linkprop() might
267 * call back to i_dladm_phys_status() recursively.
269 if ((status = dladm_destroy_datalink_id(handle, linkid,
270 DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
271 return (status);
273 (void) dladm_set_linkprop(handle, linkid, NULL, NULL, 0,
274 DLADM_OPT_ACTIVE);
276 (*flagsp) &= ~DLMGMT_ACTIVE;
277 status = DLADM_STATUS_OK;
279 return (status);
283 * Walk each entry in the data link configuration repository and
284 * call fn on the linkid and arg.
286 dladm_status_t
287 dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *),
288 dladm_handle_t handle, void *argp, datalink_class_t class,
289 datalink_media_t dmedia, uint32_t flags)
291 dlmgmt_door_getnext_t getnext;
292 dlmgmt_getnext_retval_t retval;
293 uint32_t dlmgmt_flags;
294 datalink_id_t linkid = DATALINK_INVALID_LINKID;
295 dladm_status_t status = DLADM_STATUS_OK;
296 size_t sz = sizeof (retval);
298 if (fn == NULL)
299 return (DLADM_STATUS_BADARG);
301 dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0;
302 dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0);
303 dlmgmt_flags |= ((flags & DLADM_OPT_TRANSIENT) ? DLMGMT_TRANSIENT : 0);
305 getnext.ld_cmd = DLMGMT_CMD_GETNEXT;
306 getnext.ld_class = class;
307 getnext.ld_dmedia = dmedia;
308 getnext.ld_flags = dlmgmt_flags;
310 do {
311 getnext.ld_linkid = linkid;
312 if ((status = dladm_door_call(handle, &getnext,
313 sizeof (getnext), &retval, &sz)) != DLADM_STATUS_OK) {
315 * Done with walking. If no next datalink is found,
316 * return success.
318 if (status == DLADM_STATUS_NOTFOUND)
319 status = DLADM_STATUS_OK;
320 break;
323 linkid = retval.lr_linkid;
324 if ((retval.lr_class == DATALINK_CLASS_PHYS) &&
325 (retval.lr_flags & DLMGMT_ACTIVE)) {
327 * An active physical link reported by the dlmgmtd
328 * daemon might not be active anymore. Check its
329 * real status.
331 if (i_dladm_phys_status(handle, linkid,
332 &retval.lr_flags) != DLADM_STATUS_OK) {
333 continue;
336 if (!(dlmgmt_flags & retval.lr_flags))
337 continue;
340 if (fn(handle, linkid, argp) == DLADM_WALK_TERMINATE)
341 break;
342 } while (linkid != DATALINK_INVALID_LINKID);
344 return (status);
348 * Get a handle of a copy of the link configuration (kept in the daemon)
349 * for the given link so it can be updated later by dladm_write_conf().
351 dladm_status_t
352 dladm_open_conf(dladm_handle_t handle, datalink_id_t linkid,
353 dladm_conf_t *confp)
355 dlmgmt_door_openconf_t openconf;
356 dlmgmt_openconf_retval_t retval;
357 dladm_status_t status;
358 size_t sz;
360 if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
361 return (DLADM_STATUS_BADARG);
363 sz = sizeof (retval);
364 openconf.ld_linkid = linkid;
365 openconf.ld_cmd = DLMGMT_CMD_OPENCONF;
366 confp->ds_confid = DLADM_INVALID_CONF;
367 if ((status = dladm_door_call(handle, &openconf,
368 sizeof (openconf), &retval, &sz)) == DLADM_STATUS_OK) {
369 confp->ds_readonly = B_FALSE;
370 confp->ds_confid = retval.lr_confid;
373 return (status);
377 * Get the handle of a local snapshot of the link configuration. Note that
378 * any operations with this handle are read-only, i.e., one can not update
379 * the configuration with this handle.
381 dladm_status_t
382 dladm_getsnap_conf(dladm_handle_t handle, datalink_id_t linkid,
383 dladm_conf_t *confp)
385 dlmgmt_door_getconfsnapshot_t snapshot;
386 dlmgmt_getconfsnapshot_retval_t *retvalp;
387 char *nvlbuf;
388 dladm_status_t status;
389 int err;
390 size_t sz;
392 if (linkid == DATALINK_INVALID_LINKID || confp == NULL)
393 return (DLADM_STATUS_BADARG);
395 sz = sizeof (dlmgmt_getconfsnapshot_retval_t);
396 snapshot.ld_linkid = linkid;
397 snapshot.ld_cmd = DLMGMT_CMD_GETCONFSNAPSHOT;
398 again:
399 if ((retvalp = malloc(sz)) == NULL)
400 return (DLADM_STATUS_NOMEM);
402 if ((status = dladm_door_call(handle, &snapshot, sizeof (snapshot),
403 retvalp, &sz)) == DLADM_STATUS_TOOSMALL) {
404 free(retvalp);
405 goto again;
408 if (status != DLADM_STATUS_OK) {
409 free(retvalp);
410 return (status);
413 confp->ds_readonly = B_TRUE;
414 nvlbuf = (char *)retvalp + sizeof (dlmgmt_getconfsnapshot_retval_t);
415 if ((err = nvlist_unpack(nvlbuf, retvalp->lr_nvlsz,
416 &(confp->ds_nvl), 0)) != 0) {
417 status = dladm_errno2status(err);
419 free(retvalp);
420 return (status);
424 * Commit the given link to the data link configuration repository so
425 * that it will persist across reboots.
427 dladm_status_t
428 dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf)
430 dlmgmt_door_writeconf_t writeconf;
431 dlmgmt_writeconf_retval_t retval;
432 size_t sz = sizeof (retval);
434 if (conf.ds_confid == DLADM_INVALID_CONF)
435 return (DLADM_STATUS_BADARG);
437 if (conf.ds_readonly)
438 return (DLADM_STATUS_DENIED);
440 writeconf.ld_cmd = DLMGMT_CMD_WRITECONF;
441 writeconf.ld_confid = conf.ds_confid;
443 return (dladm_door_call(handle, &writeconf, sizeof (writeconf),
444 &retval, &sz));
448 * Given a dladm_conf_t, get the specific configuration field
450 * If the specified dladm_conf_t is a read-only snapshot of the configuration,
451 * get a specific link propertie from that snapshot (nvl), otherwise, get
452 * the link protperty from the dlmgmtd daemon using the given confid.
454 dladm_status_t
455 dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
456 void *attrval, size_t attrsz)
458 dladm_status_t status = DLADM_STATUS_OK;
460 if (attrval == NULL || attrsz == 0 || attr == NULL)
461 return (DLADM_STATUS_BADARG);
463 if (conf.ds_readonly) {
464 uchar_t *oattrval;
465 uint32_t oattrsz;
466 int err;
468 if ((err = nvlist_lookup_byte_array(conf.ds_nvl, (char *)attr,
469 &oattrval, &oattrsz)) != 0) {
470 return (dladm_errno2status(err));
472 if (oattrsz > attrsz)
473 return (DLADM_STATUS_TOOSMALL);
475 bcopy(oattrval, attrval, oattrsz);
476 } else {
477 dlmgmt_door_getattr_t getattr;
478 dlmgmt_getattr_retval_t retval;
479 size_t sz = sizeof (retval);
481 if (conf.ds_confid == DLADM_INVALID_CONF)
482 return (DLADM_STATUS_BADARG);
484 getattr.ld_cmd = DLMGMT_CMD_GETATTR;
485 getattr.ld_confid = conf.ds_confid;
486 (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN);
488 if ((status = dladm_door_call(handle, &getattr,
489 sizeof (getattr), &retval, &sz)) != DLADM_STATUS_OK) {
490 return (status);
493 if (retval.lr_attrsz > attrsz)
494 return (DLADM_STATUS_TOOSMALL);
496 bcopy(retval.lr_attrval, attrval, retval.lr_attrsz);
498 return (status);
502 * Get next property attribute from data link configuration repository.
503 * If last_attr is "", return the first property.
505 dladm_status_t
506 dladm_getnext_conf_linkprop(dladm_handle_t handle __unused, dladm_conf_t conf,
507 const char *last_attr, char *attr, void *attrval, size_t attrsz,
508 size_t *attrszp)
510 nvlist_t *nvl = conf.ds_nvl;
511 nvpair_t *last = NULL, *nvp;
512 uchar_t *oattrval;
513 uint32_t oattrsz;
514 int err;
516 if (nvl == NULL || attrval == NULL || attrsz == 0 || attr == NULL ||
517 !conf.ds_readonly)
518 return (DLADM_STATUS_BADARG);
520 while ((nvp = nvlist_next_nvpair(nvl, last)) != NULL) {
521 if (last_attr[0] == '\0')
522 break;
523 if (last != NULL && strcmp(last_attr, nvpair_name(last)) == 0)
524 break;
525 last = nvp;
528 if (nvp == NULL)
529 return (DLADM_STATUS_NOTFOUND);
531 if ((err = nvpair_value_byte_array(nvp, (uchar_t **)&oattrval,
532 &oattrsz)) != 0) {
533 return (dladm_errno2status(err));
536 *attrszp = oattrsz;
537 if (oattrsz > attrsz)
538 return (DLADM_STATUS_TOOSMALL);
540 (void) strlcpy(attr, nvpair_name(nvp), MAXLINKATTRLEN);
541 bcopy(oattrval, attrval, oattrsz);
542 return (DLADM_STATUS_OK);
546 * Get the link ID that is associated with the given name.
548 dladm_status_t
549 dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp,
550 uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap)
552 dlmgmt_door_getlinkid_t getlinkid;
553 dlmgmt_getlinkid_retval_t retval;
554 datalink_id_t linkid;
555 dladm_status_t status;
556 size_t sz = sizeof (retval);
558 getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID;
559 (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN);
561 if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid),
562 &retval, &sz)) != DLADM_STATUS_OK) {
563 return (status);
566 linkid = retval.lr_linkid;
567 if (retval.lr_class == DATALINK_CLASS_PHYS &&
568 retval.lr_flags & DLMGMT_ACTIVE) {
570 * An active physical link reported by the dlmgmtd daemon
571 * might not be active anymore. Check and set its real status.
573 status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
574 if (status != DLADM_STATUS_OK)
575 return (status);
578 if (linkidp != NULL)
579 *linkidp = linkid;
580 if (flagp != NULL) {
581 *flagp = (retval.lr_flags & DLMGMT_ACTIVE) ?
582 DLADM_OPT_ACTIVE : 0;
583 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
584 DLADM_OPT_PERSIST : 0;
585 *flagp |= (retval.lr_flags & DLMGMT_TRANSIENT) ?
586 DLADM_OPT_TRANSIENT : 0;
588 if (classp != NULL)
589 *classp = retval.lr_class;
590 if (mediap != NULL)
591 *mediap = retval.lr_media;
593 return (DLADM_STATUS_OK);
597 * Get the link name that is associated with the given id.
599 dladm_status_t
600 dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid,
601 uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap, char *link,
602 size_t len)
604 dlmgmt_door_getname_t getname;
605 dlmgmt_getname_retval_t retval;
606 dladm_status_t status;
607 size_t sz = sizeof (retval);
609 if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) ||
610 (link == NULL && len != 0)) {
611 return (DLADM_STATUS_BADARG);
614 getname.ld_cmd = DLMGMT_CMD_GETNAME;
615 getname.ld_linkid = linkid;
616 if ((status = dladm_door_call(handle, &getname, sizeof (getname),
617 &retval, &sz)) != DLADM_STATUS_OK) {
618 return (status);
621 if (len != 0 && (strlen(retval.lr_link) + 1 > len))
622 return (DLADM_STATUS_TOOSMALL);
624 if (retval.lr_class == DATALINK_CLASS_PHYS &&
625 retval.lr_flags & DLMGMT_ACTIVE) {
627 * An active physical link reported by the dlmgmtd daemon
628 * might not be active anymore. Check and set its real status.
630 status = i_dladm_phys_status(handle, linkid, &retval.lr_flags);
631 if (status != DLADM_STATUS_OK)
632 return (status);
635 if (link != NULL)
636 (void) strlcpy(link, retval.lr_link, len);
637 if (classp != NULL)
638 *classp = retval.lr_class;
639 if (mediap != NULL)
640 *mediap = retval.lr_media;
641 if (flagp != NULL) {
642 *flagp = (retval.lr_flags & DLMGMT_ACTIVE) ?
643 DLADM_OPT_ACTIVE : 0;
644 *flagp |= (retval.lr_flags & DLMGMT_PERSIST) ?
645 DLADM_OPT_PERSIST : 0;
646 *flagp |= (retval.lr_flags & DLMGMT_TRANSIENT) ?
647 DLADM_OPT_TRANSIENT : 0;
649 return (DLADM_STATUS_OK);
653 * Set the given attr with the given attrval for the given link.
655 dladm_status_t
656 dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr,
657 dladm_datatype_t type, const void *attrval)
659 dlmgmt_door_setattr_t setattr;
660 dlmgmt_setattr_retval_t retval;
661 size_t attrsz;
662 size_t sz = sizeof (retval);
664 if (attr == NULL || attrval == NULL)
665 return (DLADM_STATUS_BADARG);
667 if (conf.ds_readonly)
668 return (DLADM_STATUS_DENIED);
670 if (type == DLADM_TYPE_STR)
671 attrsz = strlen(attrval) + 1;
672 else
673 attrsz = dladm_datatype_size[type];
675 if (attrsz > MAXLINKATTRVALLEN)
676 return (DLADM_STATUS_TOOSMALL);
678 setattr.ld_cmd = DLMGMT_CMD_SETATTR;
679 setattr.ld_confid = conf.ds_confid;
680 (void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN);
681 setattr.ld_attrsz = (uint32_t)attrsz;
682 setattr.ld_type = type;
683 bcopy(attrval, &setattr.ld_attrval, attrsz);
685 return (dladm_door_call(handle, &setattr, sizeof (setattr),
686 &retval, &sz));
690 * Unset the given attr the given link.
692 dladm_status_t
693 dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf,
694 const char *attr)
696 dlmgmt_door_unsetattr_t unsetattr;
697 dlmgmt_unsetattr_retval_t retval;
698 size_t sz = sizeof (retval);
700 if (attr == NULL)
701 return (DLADM_STATUS_BADARG);
703 if (conf.ds_readonly)
704 return (DLADM_STATUS_DENIED);
706 unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR;
707 unsetattr.ld_confid = conf.ds_confid;
708 (void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN);
710 return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr),
711 &retval, &sz));
715 * Remove the given link ID and its entry from the data link configuration
716 * repository.
718 dladm_status_t
719 dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid)
721 dlmgmt_door_removeconf_t removeconf;
722 dlmgmt_removeconf_retval_t retval;
723 size_t sz = sizeof (retval);
725 removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF;
726 removeconf.ld_linkid = linkid;
728 return (dladm_door_call(handle, &removeconf, sizeof (removeconf),
729 &retval, &sz));
733 * Free the contents of the link structure.
735 void
736 dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf)
738 dlmgmt_door_destroyconf_t dconf;
739 dlmgmt_destroyconf_retval_t retval;
740 size_t sz = sizeof (retval);
742 if (conf.ds_readonly) {
743 nvlist_free(conf.ds_nvl);
744 } else {
745 if (conf.ds_confid == DLADM_INVALID_CONF)
746 return;
748 dconf.ld_cmd = DLMGMT_CMD_DESTROYCONF;
749 dconf.ld_confid = conf.ds_confid;
751 (void) dladm_door_call(handle, &dconf, sizeof (dconf),
752 &retval, &sz);
756 dladm_status_t
757 dladm_zone_boot(dladm_handle_t handle, zoneid_t zoneid)
759 dlmgmt_door_zoneboot_t zoneboot;
760 dlmgmt_zoneboot_retval_t retval;
761 size_t sz = sizeof (retval);
763 zoneboot.ld_cmd = DLMGMT_CMD_ZONEBOOT;
764 zoneboot.ld_zoneid = zoneid;
765 return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot),
766 &retval, &sz));
769 dladm_status_t
770 dladm_zone_halt(dladm_handle_t handle, zoneid_t zoneid)
772 dlmgmt_door_zonehalt_t zonehalt;
773 dlmgmt_zonehalt_retval_t retval;
774 size_t sz = sizeof (retval);
776 zonehalt.ld_cmd = DLMGMT_CMD_ZONEHALT;
777 zonehalt.ld_zoneid = zoneid;
778 return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt),
779 &retval, &sz));