diff options
author | Cathy Zhou <Cathy.Zhou@Sun.COM> | 2010-07-14 15:39:08 -0400 |
---|---|---|
committer | Cathy Zhou <Cathy.Zhou@Sun.COM> | 2010-07-14 15:39:08 -0400 |
commit | 327151705b7439cb7ab35c370f682cac7ef9523a (patch) | |
tree | dc70b1e9458066faef68e56f0be54073920c112c /usr | |
parent | 442384bb4f40e4893df0a79549264f04218e1d9f (diff) | |
download | illumos-gate-327151705b7439cb7ab35c370f682cac7ef9523a.tar.gz |
6953249 memory leak in dlmgmtd
6949971 dlmgmtd keeps consuming memory
6826131 dlmgmtd's parse_linkprops() suffers from memory mismanagement
6846855 vlan rcm support could use a code review
Diffstat (limited to 'usr')
21 files changed, 546 insertions, 341 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/bridged/events.c b/usr/src/cmd/cmd-inet/usr.lib/bridged/events.c index fe64506d1e..dee468df9a 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/bridged/events.c +++ b/usr/src/cmd/cmd-inet/usr.lib/bridged/events.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -323,18 +322,10 @@ static int update_link(dladm_handle_t handle, datalink_id_t linkid, void *arg) { dladm_status_t status; - dladm_conf_t conf; char bridge[MAXLINKNAMELEN], linkname[MAXLINKNAMELEN]; char pointless[DLADM_STRSIZE]; datalink_class_t class; - status = dladm_read_conf(handle, linkid, &conf); - if (status != DLADM_STATUS_OK) { - syslog(LOG_DEBUG, "can't get status on link ID %u: %s", linkid, - dladm_status2str(status, pointless)); - return (DLADM_WALK_CONTINUE); - } - status = dladm_bridge_getlink(handle, linkid, bridge, sizeof (bridge)); if (status == DLADM_STATUS_OK && strcmp(bridge, instance_name) == 0) { status = dladm_datalink_id2info(handle, linkid, NULL, &class, @@ -354,7 +345,6 @@ update_link(dladm_handle_t handle, datalink_id_t linkid, void *arg) syslog(LOG_DEBUG, "link ID %u is on bridge %s, not %s", linkid, bridge, instance_name); } - dladm_destroy_conf(handle, conf); return (DLADM_WALK_CONTINUE); } diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index c07fc2cb49..c6c19724a4 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -9142,7 +9142,7 @@ print_part(show_part_state_t *state, datalink_id_t linkid) * we want up-part to always succeed even if the port is currently down * or P_Key is not yet available in the subnet. */ - if ((status = dladm_read_conf(handle, linkid, &conf)) == + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) == DLADM_STATUS_OK) { (void) dladm_get_conf_field(handle, conf, FFORCE, &force_in_conf, sizeof (boolean_t)); diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_db.c b/usr/src/cmd/dlmgmtd/dlmgmt_db.c index 7a97985de3..7cb9e2ce78 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_db.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_db.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <assert.h> @@ -711,7 +710,6 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) boolean_t found_type = B_FALSE; dladm_datatype_t type = DLADM_TYPE_STR; int i, len; - int err = 0; char *curr; char attr_name[MAXLINKATTRLEN]; size_t attr_buf_len = 0; @@ -720,7 +718,7 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) curr = buf; len = strlen(buf); attr_name[0] = '\0'; - for (i = 0; i < len && err == 0; i++) { + for (i = 0; i < len; i++) { char c = buf[i]; boolean_t match = (c == '=' || (c == ',' && !found_type) || c == ';'); @@ -751,26 +749,36 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) goto parse_fail; if (strcmp(attr_name, "linkid") == 0) { - (void) read_int64(curr, &attr_buf); + if (read_int64(curr, &attr_buf) == 0) + goto parse_fail; linkp->ll_linkid = (datalink_class_t)*(int64_t *)attr_buf; } else if (strcmp(attr_name, "name") == 0) { - (void) read_str(curr, &attr_buf); + if (read_str(curr, &attr_buf) == 0) + goto parse_fail; (void) snprintf(linkp->ll_link, MAXLINKNAMELEN, "%s", attr_buf); } else if (strcmp(attr_name, "class") == 0) { - (void) read_int64(curr, &attr_buf); + if (read_int64(curr, &attr_buf) == 0) + goto parse_fail; linkp->ll_class = (datalink_class_t)*(int64_t *)attr_buf; } else if (strcmp(attr_name, "media") == 0) { - (void) read_int64(curr, &attr_buf); + if (read_int64(curr, &attr_buf) == 0) + goto parse_fail; linkp->ll_media = (uint32_t)*(int64_t *)attr_buf; } else { attr_buf_len = translators[type].read_func(curr, &attr_buf); - err = linkattr_set(&(linkp->ll_head), attr_name, - attr_buf, attr_buf_len, type); + if (attr_buf_len == 0) + goto parse_fail; + + if (linkattr_set(&(linkp->ll_head), attr_name, + attr_buf, attr_buf_len, type) != 0) { + free(attr_buf); + goto parse_fail; + } } free(attr_buf); @@ -806,9 +814,13 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) curr = buf + i + 1; } - return (err); + return (0); parse_fail: + /* + * Free linkp->ll_head (link attribute list) + */ + linkattr_destroy(linkp); return (-1); } @@ -986,6 +998,12 @@ process_db_write(dlmgmt_db_req_t *req, FILE *fp, FILE *nfp) while (err == 0 && fgets(buf, sizeof (buf), fp) != NULL && process_link_line(buf, &link_in_file)) { + /* + * Only the link name is needed. Free the memory allocated for + * the link attributes list of link_in_file. + */ + linkattr_destroy(&link_in_file); + if (link_in_file.ll_link[0] == '\0' || done) { /* * this is a comment line or we are done updating the @@ -1089,12 +1107,16 @@ process_db_read(dlmgmt_db_req_t *req, FILE *fp) /* * Skip the comment line. */ - if (link_in_file.ll_link[0] == '\0') + if (link_in_file.ll_link[0] == '\0') { + linkattr_destroy(&link_in_file); continue; + } if ((req->ls_flags & DLMGMT_ACTIVE) && - link_in_file.ll_linkid == DATALINK_INVALID_LINKID) + link_in_file.ll_linkid == DATALINK_INVALID_LINKID) { + linkattr_destroy(&link_in_file); continue; + } link_in_file.ll_zoneid = req->ls_zoneid; link_in_db = avl_find(&dlmgmt_name_avl, &link_in_file, @@ -1110,6 +1132,7 @@ process_db_read(dlmgmt_db_req_t *req, FILE *fp) dlmgmt_log(LOG_WARNING, "Duplicate links " "in the repository: %s", link_in_file.ll_link); + linkattr_destroy(&link_in_file); } else { if (req->ls_flags & DLMGMT_PERSIST) { /* @@ -1119,6 +1142,8 @@ process_db_read(dlmgmt_db_req_t *req, FILE *fp) assert(link_in_db->ll_head == NULL); link_in_db->ll_head = link_in_file.ll_head; + } else { + linkattr_destroy(&link_in_file); } link_in_db->ll_flags |= req->ls_flags; } @@ -1132,6 +1157,7 @@ process_db_read(dlmgmt_db_req_t *req, FILE *fp) dlmgmt_log(LOG_WARNING, "Unable to allocate " "memory to create new link %s", link_in_file.ll_link); + linkattr_destroy(&link_in_file); continue; } bcopy(&link_in_file, newlink, sizeof (*newlink)); diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c index 904dcbbd98..11e4329669 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -61,7 +60,8 @@ #include <librcm.h> #include "dlmgmt_impl.h" -typedef void dlmgmt_door_handler_t(void *, void *, zoneid_t, ucred_t *); +typedef void dlmgmt_door_handler_t(void *, void *, size_t *, zoneid_t, + ucred_t *); typedef struct dlmgmt_door_info_s { uint_t di_cmd; @@ -136,8 +136,10 @@ done: nvlist_free(nvl); } +/* ARGSUSED */ static void -dlmgmt_upcall_create(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_upcall_create(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_upcall_arg_create_t *create = argp; dlmgmt_create_retval_t *retvalp = retp; @@ -274,8 +276,10 @@ noupdate: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_upcall_update(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_upcall_update(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_upcall_arg_update_t *update = argp; dlmgmt_update_retval_t *retvalp = retp; @@ -348,8 +352,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_upcall_destroy(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_upcall_destroy(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_upcall_arg_destroy_t *destroy = argp; dlmgmt_destroy_retval_t *retvalp = retp; @@ -396,7 +402,8 @@ done: /* ARGSUSED */ static void -dlmgmt_getname(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_getname(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_getname_t *getname = argp; dlmgmt_getname_retval_t *retvalp = retp; @@ -424,7 +431,8 @@ dlmgmt_getname(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) /* ARGSUSED */ static void -dlmgmt_getlinkid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_getlinkid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_getlinkid_t *getlinkid = argp; dlmgmt_getlinkid_retval_t *retvalp = retp; @@ -456,7 +464,8 @@ done: /* ARGSUSED */ static void -dlmgmt_getnext(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_getnext(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_getnext_t *getnext = argp; dlmgmt_getnext_retval_t *retvalp = retp; @@ -498,7 +507,8 @@ dlmgmt_getnext(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) /* ARGSUSED */ static void -dlmgmt_upcall_getattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_upcall_getattr(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_upcall_arg_getattr_t *getattr = argp; dlmgmt_getattr_retval_t *retvalp = retp; @@ -517,8 +527,10 @@ dlmgmt_upcall_getattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) dlmgmt_table_unlock(); } +/* ARGSUSED */ static void -dlmgmt_createid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_createid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_createid_t *createid = argp; dlmgmt_createid_retval_t *retvalp = retp; @@ -566,8 +578,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_destroyid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_destroyid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_destroyid_t *destroyid = argp; dlmgmt_destroyid_retval_t *retvalp = retp; @@ -605,8 +619,10 @@ done: * (ld_linkid) to a non-existent link2 (ld_link): rename link1's name to * the given link name. */ +/* ARGSUSED */ static void -dlmgmt_remapid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_remapid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_remapid_t *remapid = argp; dlmgmt_remapid_retval_t *retvalp = retp; @@ -671,8 +687,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_upid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_upid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_upid_t *upid = argp; dlmgmt_upid_retval_t *retvalp = retp; @@ -705,8 +723,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_createconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_createconf(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_createconf_t *createconf = argp; dlmgmt_createconf_retval_t *retvalp = retp; @@ -726,15 +746,17 @@ dlmgmt_createconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) if (err == 0) { avl_add(&dlmgmt_dlconf_avl, dlconfp); dlmgmt_advance_dlconfid(dlconfp); - retvalp->lr_conf = (dladm_conf_t)dlconfp->ld_id; + retvalp->lr_confid = dlconfp->ld_id; } done: dlmgmt_dlconf_table_unlock(); retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_setattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_setattr(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_setattr_t *setattr = argp; dlmgmt_setattr_retval_t *retvalp = retp; @@ -746,7 +768,7 @@ dlmgmt_setattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) */ dlmgmt_dlconf_table_lock(B_TRUE); - dlconf.ld_id = (int)setattr->ld_conf; + dlconf.ld_id = setattr->ld_confid; dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL); if (dlconfp == NULL || zoneid != dlconfp->ld_zoneid) { err = ENOENT; @@ -764,8 +786,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_unsetconfattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_unsetconfattr(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_unsetattr_t *unsetattr = argp; dlmgmt_unsetattr_retval_t *retvalp = retp; @@ -777,7 +801,7 @@ dlmgmt_unsetconfattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) */ dlmgmt_dlconf_table_lock(B_TRUE); - dlconf.ld_id = (int)unsetattr->ld_conf; + dlconf.ld_id = unsetattr->ld_confid; dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL); if (dlconfp == NULL || zoneid != dlconfp->ld_zoneid) { err = ENOENT; @@ -795,19 +819,21 @@ done: } /* - * Note that dlmgmt_readconf() returns a conf ID of a conf AVL tree entry, + * Note that dlmgmt_openconf() returns a conf ID of a conf AVL tree entry, * which is managed by dlmgmtd. The ID is used to find the conf entry when * dlmgmt_write_conf() is called. The conf entry contains an ld_gen value * (which is the generation number - ll_gen) of the dlmgmt_link_t at the time - * of dlmgmt_readconf(), and ll_gen changes every time the dlmgmt_link_t + * of dlmgmt_openconf(), and ll_gen changes every time the dlmgmt_link_t * changes its attributes. Therefore, dlmgmt_write_conf() can compare ld_gen * in the conf entry against the latest dlmgmt_link_t ll_gen value to see if - * anything has changed between the dlmgmt_read_conf() and dlmgmt_writeconf() + * anything has changed between the dlmgmt_openconf() and dlmgmt_writeconf() * calls. If so, EAGAIN is returned. This mechanism can ensures atomicity * across the pair of dladm_read_conf() and dladm_write_conf() calls. */ +/* ARGSUSED */ static void -dlmgmt_writeconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_writeconf(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_writeconf_t *writeconf = argp; dlmgmt_writeconf_retval_t *retvalp = retp; @@ -817,11 +843,11 @@ dlmgmt_writeconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) int err = 0; /* - * Hold the read lock to access the dlconf table. + * Hold the lock to access the dlconf table. */ dlmgmt_dlconf_table_lock(B_TRUE); - dlconf.ld_id = (int)writeconf->ld_conf; + dlconf.ld_id = writeconf->ld_confid; dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL); if (dlconfp == NULL || zoneid != dlconfp->ld_zoneid) { err = ENOENT; @@ -885,8 +911,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_removeconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_removeconf(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_removeconf_t *removeconf = argp; dlmgmt_removeconf_retval_t *retvalp = retp; @@ -916,8 +944,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_destroyconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_destroyconf(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_destroyconf_t *destroyconf = argp; dlmgmt_destroyconf_retval_t *retvalp = retp; @@ -929,7 +959,7 @@ dlmgmt_destroyconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) */ dlmgmt_dlconf_table_lock(B_TRUE); - dlconf.ld_id = (int)destroyconf->ld_conf; + dlconf.ld_id = destroyconf->ld_confid; dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL); if (dlconfp == NULL || zoneid != dlconfp->ld_zoneid) { err = ENOENT; @@ -948,17 +978,23 @@ done: } /* - * See the comments above dladm_write_conf() to see how ld_gen is used to - * ensure atomicity across the {dlmgmt_readconf(), dlmgmt_writeconf()} pair. + * dlmgmt_openconf() returns a handle of the current configuration, which + * is then used to update the configuration by dlmgmt_writeconf(). Therefore, + * it requires privileges. + * + * Further, please see the comments above dladm_write_conf() to see how + * ld_gen is used to ensure atomicity across the {dlmgmt_openconf(), + * dlmgmt_writeconf()} pair. */ /* ARGSUSED */ static void -dlmgmt_readconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_openconf(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { - dlmgmt_door_readconf_t *readconf = argp; - dlmgmt_readconf_retval_t *retvalp = retp; + dlmgmt_door_openconf_t *openconf = argp; + dlmgmt_openconf_retval_t *retvalp = retp; dlmgmt_link_t *linkp; - datalink_id_t linkid = readconf->ld_linkid; + datalink_id_t linkid = openconf->ld_linkid; dlmgmt_dlconf_t *dlconfp; dlmgmt_linkattr_t *attrp; int err = 0; @@ -987,6 +1023,9 @@ dlmgmt_readconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) goto done; } + if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0) + goto done; + if ((err = dlconf_create(linkp->ll_link, linkp->ll_linkid, linkp->ll_class, linkp->ll_media, zoneid, &dlconfp)) != 0) goto done; @@ -1002,7 +1041,7 @@ dlmgmt_readconf(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) avl_add(&dlmgmt_dlconf_avl, dlconfp); dlmgmt_advance_dlconfid(dlconfp); - retvalp->lr_conf = (dladm_conf_t)dlconfp->ld_id; + retvalp->lr_confid = dlconfp->ld_id; done: dlmgmt_table_unlock(); dlmgmt_dlconf_table_unlock(); @@ -1010,36 +1049,117 @@ done: } /* - * Note: the caller must free *retvalpp in case of success. + * dlmgmt_getconfsnapshot() returns a read-only snapshot of all the + * configuration, and requires no privileges. + * + * If the given size cannot hold all the configuration, set the size + * that is needed, and return ENOSPC. */ /* ARGSUSED */ static void -dlmgmt_getattr(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_getconfsnapshot(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) +{ + dlmgmt_door_getconfsnapshot_t *snapshot = argp; + dlmgmt_getconfsnapshot_retval_t *retvalp = retp; + dlmgmt_link_t *linkp; + datalink_id_t linkid = snapshot->ld_linkid; + dlmgmt_linkattr_t *attrp; + char *buf; + size_t nvlsz; + nvlist_t *nvl = NULL; + int err = 0; + + assert(*sz >= sizeof (dlmgmt_getconfsnapshot_retval_t)); + + /* + * Hold the reader lock to access the link + */ + dlmgmt_table_lock(B_FALSE); + linkp = link_by_id(linkid, zoneid); + if ((linkp == NULL) || !(linkp->ll_flags & DLMGMT_PERSIST)) { + /* The persistent link configuration does not exist. */ + err = ENOENT; + goto done; + } + if (linkp->ll_onloan && zoneid != GLOBAL_ZONEID) { + /* + * The caller is in a non-global zone and the persistent + * configuration belongs to the global zone. + */ + err = EACCES; + goto done; + } + + err = nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0); + if (err != 0) + goto done; + + for (attrp = linkp->ll_head; attrp != NULL; attrp = attrp->lp_next) { + if ((err = nvlist_add_byte_array(nvl, attrp->lp_name, + attrp->lp_val, attrp->lp_sz)) != 0) { + goto done; + } + } + + if ((err = nvlist_size(nvl, &nvlsz, NV_ENCODE_NATIVE)) != 0) + goto done; + + if (nvlsz + sizeof (dlmgmt_getconfsnapshot_retval_t) > *sz) { + *sz = nvlsz + sizeof (dlmgmt_getconfsnapshot_retval_t); + err = ENOSPC; + goto done; + } + + /* + * pack the the nvlist into the return value. + */ + *sz = nvlsz + sizeof (dlmgmt_getconfsnapshot_retval_t); + retvalp->lr_nvlsz = nvlsz; + buf = (char *)retvalp + sizeof (dlmgmt_getconfsnapshot_retval_t); + err = nvlist_pack(nvl, &buf, &nvlsz, NV_ENCODE_NATIVE, 0); + +done: + dlmgmt_table_unlock(); + nvlist_free(nvl); + retvalp->lr_err = err; +} + +/* ARGSUSED */ +static void +dlmgmt_getattr(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_getattr_t *getattr = argp; dlmgmt_getattr_retval_t *retvalp = retp; dlmgmt_dlconf_t dlconf, *dlconfp; + int err; /* * Hold the read lock to access the dlconf table. */ dlmgmt_dlconf_table_lock(B_FALSE); - dlconf.ld_id = (int)getattr->ld_conf; + dlconf.ld_id = getattr->ld_confid; if ((dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL)) == NULL || zoneid != dlconfp->ld_zoneid) { retvalp->lr_err = ENOENT; } else { - retvalp->lr_err = dlmgmt_getattr_common(&dlconfp->ld_head, - getattr->ld_attr, retvalp); + if ((err = dlmgmt_checkprivs(dlconfp->ld_class, cred)) != 0) { + retvalp->lr_err = err; + } else { + retvalp->lr_err = dlmgmt_getattr_common( + &dlconfp->ld_head, getattr->ld_attr, retvalp); + } } dlmgmt_dlconf_table_unlock(); } +/* ARGSUSED */ static void -dlmgmt_upcall_linkprop_init(void *argp, void *retp, zoneid_t zoneid, - ucred_t *cred) +dlmgmt_upcall_linkprop_init(void *argp, void *retp, size_t *sz, + zoneid_t zoneid, ucred_t *cred) { dlmgmt_door_linkprop_init_t *lip = argp; dlmgmt_linkprop_init_retval_t *retvalp = retp; @@ -1068,57 +1188,10 @@ dlmgmt_upcall_linkprop_init(void *argp, void *retp, zoneid_t zoneid, retvalp->lr_err = err; } -/* - * Get the link property that follows ld_last_attr. - * If ld_last_attr is empty, return the first property. - */ /* ARGSUSED */ static void -dlmgmt_linkprop_getnext(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) -{ - dlmgmt_door_linkprop_getnext_t *getnext = argp; - dlmgmt_linkprop_getnext_retval_t *retvalp = retp; - dlmgmt_dlconf_t dlconf, *dlconfp; - char *attr; - void *attrval; - size_t attrsz; - dladm_datatype_t attrtype; - int err = 0; - - /* - * Hold the read lock to access the dlconf table. - */ - dlmgmt_dlconf_table_lock(B_FALSE); - - dlconf.ld_id = (int)getnext->ld_conf; - dlconfp = avl_find(&dlmgmt_dlconf_avl, &dlconf, NULL); - if (dlconfp == NULL) { - err = ENOENT; - goto done; - } - - err = linkprop_getnext(&dlconfp->ld_head, getnext->ld_last_attr, - &attr, &attrval, &attrsz, &attrtype); - if (err != 0) - goto done; - - if (attrsz > MAXLINKATTRVALLEN) { - err = EINVAL; - goto done; - } - - (void) strlcpy(retvalp->lr_attr, attr, MAXLINKATTRLEN); - retvalp->lr_type = attrtype; - retvalp->lr_attrsz = attrsz; - bcopy(attrval, retvalp->lr_attrval, attrsz); - -done: - dlmgmt_dlconf_table_unlock(); - retvalp->lr_err = err; -} - -static void -dlmgmt_setzoneid(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_setzoneid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { dlmgmt_door_setzoneid_t *setzoneid = argp; dlmgmt_setzoneid_retval_t *retvalp = retp; @@ -1196,8 +1269,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_zoneboot(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_zoneboot(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { int err; dlmgmt_door_zoneboot_t *zoneboot = argp; @@ -1226,8 +1301,10 @@ done: retvalp->lr_err = err; } +/* ARGSUSED */ static void -dlmgmt_zonehalt(void *argp, void *retp, zoneid_t zoneid, ucred_t *cred) +dlmgmt_zonehalt(void *argp, void *retp, size_t *sz, zoneid_t zoneid, + ucred_t *cred) { int err = 0; dlmgmt_door_zonehalt_t *zonehalt = argp; @@ -1270,8 +1347,8 @@ static dlmgmt_door_info_t i_dlmgmt_door_info_tbl[] = { sizeof (dlmgmt_remapid_retval_t), dlmgmt_remapid }, { DLMGMT_CMD_CREATECONF, sizeof (dlmgmt_door_createconf_t), sizeof (dlmgmt_createconf_retval_t), dlmgmt_createconf }, - { DLMGMT_CMD_READCONF, sizeof (dlmgmt_door_readconf_t), - sizeof (dlmgmt_readconf_retval_t), dlmgmt_readconf }, + { DLMGMT_CMD_OPENCONF, sizeof (dlmgmt_door_openconf_t), + sizeof (dlmgmt_openconf_retval_t), dlmgmt_openconf }, { DLMGMT_CMD_WRITECONF, sizeof (dlmgmt_door_writeconf_t), sizeof (dlmgmt_writeconf_retval_t), dlmgmt_writeconf }, { DLMGMT_CMD_UP_LINKID, sizeof (dlmgmt_door_upid_t), @@ -1286,12 +1363,11 @@ static dlmgmt_door_info_t i_dlmgmt_door_info_tbl[] = { sizeof (dlmgmt_destroyconf_retval_t), dlmgmt_destroyconf }, { DLMGMT_CMD_GETATTR, sizeof (dlmgmt_door_getattr_t), sizeof (dlmgmt_getattr_retval_t), dlmgmt_getattr }, + { DLMGMT_CMD_GETCONFSNAPSHOT, sizeof (dlmgmt_door_getconfsnapshot_t), + sizeof (dlmgmt_getconfsnapshot_retval_t), dlmgmt_getconfsnapshot }, { DLMGMT_CMD_LINKPROP_INIT, sizeof (dlmgmt_door_linkprop_init_t), sizeof (dlmgmt_linkprop_init_retval_t), dlmgmt_upcall_linkprop_init }, - { DLMGMT_CMD_LINKPROP_GETNEXT, sizeof (dlmgmt_door_linkprop_getnext_t), - sizeof (dlmgmt_linkprop_getnext_retval_t), - dlmgmt_linkprop_getnext }, { DLMGMT_CMD_SETZONEID, sizeof (dlmgmt_door_setzoneid_t), sizeof (dlmgmt_setzoneid_retval_t), dlmgmt_setzoneid }, { DLMGMT_CMD_ZONEBOOT, sizeof (dlmgmt_door_zoneboot_t), @@ -1324,7 +1400,8 @@ dlmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, dlmgmt_retval_t retval; ucred_t *cred = NULL; zoneid_t zoneid; - void *retvalp; + void *retvalp = NULL; + size_t sz, acksz; int err = 0; infop = dlmgmt_getcmdinfo(door_arg->ld_cmd); @@ -1339,17 +1416,31 @@ dlmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, } /* - * We cannot use malloc() here because door_return never returns, and - * memory allocated by malloc() would get leaked. Use alloca() instead. + * Note that malloc() cannot be used here because door_return + * never returns, and memory allocated by malloc() would get leaked. + * Use alloca() instead. */ - retvalp = alloca(infop->di_acksz); - infop->di_handler(argp, retvalp, zoneid, cred); + acksz = infop->di_acksz; + +again: + retvalp = alloca(acksz); + sz = acksz; + infop->di_handler(argp, retvalp, &acksz, zoneid, cred); + if (acksz > sz) { + /* + * If the specified buffer size is not big enough to hold the + * return value, reallocate the buffer and try to get the + * result one more time. + */ + assert(((dlmgmt_retval_t *)retvalp)->lr_err == ENOSPC); + goto again; + } done: if (cred != NULL) ucred_free(cred); if (err == 0) { - (void) door_return(retvalp, infop->di_acksz, NULL, 0); + (void) door_return(retvalp, acksz, NULL, 0); } else { retval.lr_err = err; (void) door_return((char *)&retval, sizeof (retval), NULL, 0); diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h index eb7f6410b2..cdfd0d8a4d 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h +++ b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -103,8 +102,7 @@ int linkattr_set(dlmgmt_linkattr_t **, const char *, void *, size_t, dladm_datatype_t); int linkattr_get(dlmgmt_linkattr_t **, const char *, void **, size_t *, dladm_datatype_t *); -int linkprop_getnext(dlmgmt_linkattr_t **, const char *, - char **, void **, size_t *, dladm_datatype_t *); +void linkattr_destroy(dlmgmt_link_t *); void link_destroy(dlmgmt_link_t *); int link_activate(dlmgmt_link_t *); diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_util.c b/usr/src/cmd/dlmgmtd/dlmgmt_util.c index 58e44b9182..96b2b3b826 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_util.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_util.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -275,8 +274,11 @@ linkattr_unset(dlmgmt_linkattr_t **headp, const char *attr) { dlmgmt_linkattr_t *attrp; - if ((attrp = linkattr_find(*headp, attr)) != NULL) + if ((attrp = linkattr_find(*headp, attr)) != NULL) { linkattr_rm(headp, attrp); + free(attrp->lp_val); + free(attrp); + } } int @@ -295,33 +297,6 @@ linkattr_get(dlmgmt_linkattr_t **headp, const char *attr, void **attrvalp, return (0); } -int -linkprop_getnext(dlmgmt_linkattr_t **headp, const char *lastattr, - char **attrnamep, void **attrvalp, size_t *attrszp, dladm_datatype_t *typep) -{ - dlmgmt_linkattr_t *attrp; - - /* skip to entry following lastattr or pick first if none specified */ - for (attrp = *headp; attrp != NULL; attrp = attrp->lp_next) { - if (!attrp->lp_linkprop) - continue; - if (lastattr[0] == '\0') - break; - if (strcmp(attrp->lp_name, lastattr) == 0) { - attrp = attrp->lp_next; - break; - } - } - if (attrp == NULL) - return (ENOENT); - - *attrnamep = attrp->lp_name; - *attrvalp = attrp->lp_val; - *attrszp = attrp->lp_sz; - *typep = attrp->lp_type; - return (0); -} - boolean_t linkattr_equal(dlmgmt_linkattr_t **headp, const char *attr, void *attrval, size_t attrsz) @@ -336,6 +311,18 @@ linkattr_equal(dlmgmt_linkattr_t **headp, const char *attr, void *attrval, (memcmp(saved_attrval, attrval, attrsz) == 0)); } +void +linkattr_destroy(dlmgmt_link_t *linkp) +{ + dlmgmt_linkattr_t *next, *attrp; + + for (attrp = linkp->ll_head; attrp != NULL; attrp = next) { + next = attrp->lp_next; + free(attrp->lp_val); + free(attrp); + } +} + static int dlmgmt_table_readwritelock(boolean_t write) { @@ -367,13 +354,7 @@ dlmgmt_table_unlock(void) void link_destroy(dlmgmt_link_t *linkp) { - dlmgmt_linkattr_t *next, *attrp; - - for (attrp = linkp->ll_head; attrp != NULL; attrp = next) { - next = attrp->lp_next; - free(attrp->lp_val); - free(attrp); - } + linkattr_destroy(linkp); free(linkp); } diff --git a/usr/src/cmd/rcm_daemon/common/vlan_rcm.c b/usr/src/cmd/rcm_daemon/common/vlan_rcm.c index 31d9cd7358..83a5ea7982 100644 --- a/usr/src/cmd/rcm_daemon/common/vlan_rcm.c +++ b/usr/src/cmd/rcm_daemon/common/vlan_rcm.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -314,7 +313,8 @@ vlan_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, node = cache_lookup(hd, rsrc, CACHE_REFRESH); if (node == NULL) { /* should not happen because the resource is registered. */ - vlan_log_err(node->vc_linkid, errorp, "unrecognized resource"); + vlan_log_err(DATALINK_INVALID_LINKID, errorp, + "unrecognized resource"); (void) mutex_unlock(&cache_lock); return (RCM_SUCCESS); } diff --git a/usr/src/cmd/rcm_daemon/common/vnic_rcm.c b/usr/src/cmd/rcm_daemon/common/vnic_rcm.c index 42d80667b9..18bd4118a9 100644 --- a/usr/src/cmd/rcm_daemon/common/vnic_rcm.c +++ b/usr/src/cmd/rcm_daemon/common/vnic_rcm.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -314,7 +313,8 @@ vnic_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags, node = cache_lookup(hd, rsrc, CACHE_REFRESH); if (node == NULL) { /* should not happen because the resource is registered. */ - vnic_log_err(node->vc_linkid, errorp, "unrecognized resource"); + vnic_log_err(DATALINK_INVALID_LINKID, errorp, + "unrecognized resource"); (void) mutex_unlock(&cache_lock); return (RCM_SUCCESS); } diff --git a/usr/src/lib/libdladm/common/libdladm.h b/usr/src/lib/libdladm/common/libdladm.h index eb3ca9c225..f0811ae5df 100644 --- a/usr/src/lib/libdladm/common/libdladm.h +++ b/usr/src/lib/libdladm/common/libdladm.h @@ -28,6 +28,7 @@ #include <sys/dls_mgmt.h> #include <sys/dld.h> #include <sys/dlpi.h> +#include <libnvpair.h> /* * This file includes structures, macros and common routines shared by all @@ -180,7 +181,17 @@ typedef enum { DLADM_TYPE_UINT64 } dladm_datatype_t; -typedef int dladm_conf_t; +typedef struct { + boolean_t ds_readonly; + union { + int dsu_confid; + nvlist_t *dsu_nvl; + } ds_u; +} dladm_conf_t; + +#define ds_confid ds_u.dsu_confid +#define ds_nvl ds_u.dsu_nvl + #define DLADM_INVALID_CONF 0 /* opaque dladm handle to libdladm functions */ diff --git a/usr/src/lib/libdladm/common/libdlaggr.c b/usr/src/lib/libdladm/common/libdlaggr.c index 8c91c41ce1..d54920d432 100644 --- a/usr/src/lib/libdladm/common/libdlaggr.c +++ b/usr/src/lib/libdladm/common/libdlaggr.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdio.h> @@ -276,7 +275,7 @@ i_dladm_aggr_info_persist(dladm_handle_t handle, datalink_id_t linkid, char macstr[ETHERADDRL * 3]; attrp->lg_linkid = linkid; - if ((status = dladm_read_conf(handle, linkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) != DLADM_STATUS_OK) return (status); @@ -413,7 +412,7 @@ i_dladm_aggr_add_rmv(dladm_handle_t handle, datalink_id_t linkid, * PORT_DELIMITER (':'). */ if (flags & DLADM_OPT_PERSIST) { - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_open_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); @@ -573,7 +572,7 @@ done: * persistent configuration if we've changed that. */ if ((status != DLADM_STATUS_OK) && (flags & DLADM_OPT_PERSIST)) { - if (dladm_read_conf(handle, linkid, &conf) == DLADM_STATUS_OK) { + if (dladm_open_conf(handle, linkid, &conf) == DLADM_STATUS_OK) { u64 = orig_nports; if ((dladm_set_conf_field(handle, conf, FNPORTS, DLADM_TYPE_UINT64, &u64) == DLADM_STATUS_OK) && @@ -1013,7 +1012,7 @@ dladm_aggr_persist_aggr_conf(dladm_handle_t handle, const char *link, const uchar_t *mac_addr, aggr_lacp_mode_t lacp_mode, aggr_lacp_timer_t lacp_timer, boolean_t force) { - dladm_conf_t conf = DLADM_INVALID_CONF; + dladm_conf_t conf; char *portstr = NULL; char macstr[ETHERADDRL * 3]; dladm_status_t status; @@ -1302,7 +1301,7 @@ dladm_aggr_modify(dladm_handle_t handle, datalink_id_t linkid, bcopy(mac_addr, new_attr.ld_mac, ETHERADDRL); if (flags & DLADM_OPT_PERSIST) { - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_open_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); @@ -1330,7 +1329,7 @@ done: status = i_dladm_aggr_modify_sys(handle, linkid, modify_mask, &new_attr); if ((status != DLADM_STATUS_OK) && (flags & DLADM_OPT_PERSIST)) { - if (dladm_read_conf(handle, linkid, &conf) == DLADM_STATUS_OK) { + if (dladm_open_conf(handle, linkid, &conf) == DLADM_STATUS_OK) { if (i_dladm_aggr_set_aggr_attr(handle, conf, modify_mask, &old_attr) == DLADM_STATUS_OK) { (void) dladm_write_conf(handle, conf); @@ -1463,7 +1462,7 @@ i_dladm_walk_key2linkid(dladm_handle_t handle, datalink_id_t linkid, void *arg) i_walk_key_state_t *statep = (i_walk_key_state_t *)arg; uint64_t u64; - if (dladm_read_conf(handle, linkid, &conf) != 0) + if (dladm_getsnap_conf(handle, linkid, &conf) != DLADM_STATUS_OK) return (DLADM_WALK_CONTINUE); status = dladm_get_conf_field(handle, conf, FKEY, &u64, sizeof (u64)); diff --git a/usr/src/lib/libdladm/common/libdlbridge.c b/usr/src/lib/libdladm/common/libdlbridge.c index 5ad371ae93..bbf8fe762e 100644 --- a/usr/src/lib/libdladm/common/libdlbridge.c +++ b/usr/src/lib/libdladm/common/libdlbridge.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdio.h> @@ -624,7 +623,7 @@ static dladm_status_t dladm_bridge_persist_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid) { - dladm_conf_t conf = DLADM_INVALID_CONF; + dladm_conf_t conf; dladm_status_t status; status = dladm_create_conf(handle, link, linkid, DATALINK_CLASS_BRIDGE, @@ -1050,8 +1049,8 @@ dladm_bridge_setlink(dladm_handle_t handle, datalink_id_t linkid, if (*bridge != '\0' && !dladm_valid_bridgename(bridge)) return (DLADM_STATUS_FAILED); - if ((status = dladm_read_conf(handle, linkid, &conf)) != - DLADM_STATUS_OK) + status = dladm_open_conf(handle, linkid, &conf); + if (status != DLADM_STATUS_OK) return (status); has_oldbridge = B_FALSE; @@ -1105,7 +1104,7 @@ dladm_bridge_getlink(dladm_handle_t handle, datalink_id_t linkid, char *bridge, dladm_status_t status; dladm_conf_t conf; - if ((status = dladm_read_conf(handle, linkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) != DLADM_STATUS_OK) return (status); @@ -1143,9 +1142,9 @@ i_dladm_bridge_is_held(dladm_handle_t handle, datalink_id_t linkid, void *arg) dladm_status_t status = DLADM_STATUS_FAILED; dladm_conf_t conf; char bridge[MAXLINKNAMELEN]; - bridge_held_arg_t *bha = arg; + bridge_held_arg_t *bha = arg; - if ((status = dladm_read_conf(handle, linkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) != DLADM_STATUS_OK) return (DLADM_WALK_CONTINUE); status = dladm_get_conf_field(handle, conf, FBRIDGE, bridge, diff --git a/usr/src/lib/libdladm/common/libdlib.c b/usr/src/lib/libdladm/common/libdlib.c index 24cbd81d54..27ec4cf6cd 100644 --- a/usr/src/lib/libdladm/common/libdlib.c +++ b/usr/src/lib/libdladm/common/libdlib.c @@ -171,7 +171,7 @@ i_dladm_part_info_persist(dladm_handle_t handle, datalink_id_t linkid, bzero(attrp, sizeof (*attrp)); attrp->dia_partlinkid = linkid; - if ((status = dladm_read_conf(handle, linkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) != DLADM_STATUS_OK) return (status); @@ -622,7 +622,7 @@ i_dladm_part_up(dladm_handle_t handle, datalink_id_t plinkid, void *arg) * persistent configuration entry for this datalink ID. If this datalink * ID is not present in the persistent configuration return. */ - if ((status = dladm_read_conf(handle, plinkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, plinkid, &conf)) != DLADM_STATUS_OK) return (status); @@ -679,7 +679,7 @@ i_dladm_part_up(dladm_handle_t handle, datalink_id_t plinkid, void *arg) /* Create the active IB Partition object. */ if (i_dladm_part_create(handle, &pattr) == DLADM_STATUS_OK && dladm_up_datalink_id(handle, plinkid) != DLADM_STATUS_OK) - (void) i_dladm_part_delete(handle, linkid); + (void) i_dladm_part_delete(handle, linkid); done: dladm_destroy_conf(handle, conf); diff --git a/usr/src/lib/libdladm/common/libdliptun.c b/usr/src/lib/libdladm/common/libdliptun.c index f73c0d1ecb..21c4f5dbd1 100644 --- a/usr/src/lib/libdladm/common/libdliptun.c +++ b/usr/src/lib/libdladm/common/libdliptun.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <assert.h> @@ -252,9 +251,10 @@ i_iptun_get_dbparams(dladm_handle_t handle, iptun_params_t *params) if (class != DATALINK_CLASS_IPTUN) return (DLADM_STATUS_LINKINVAL); - status = dladm_read_conf(handle, params->iptun_param_linkid, &conf); - if (status != DLADM_STATUS_OK) + if ((status = dladm_getsnap_conf(handle, params->iptun_param_linkid, + &conf)) != DLADM_STATUS_OK) { return (status); + } params->iptun_param_flags = 0; @@ -374,7 +374,7 @@ i_iptun_modify_db(dladm_handle_t handle, const iptun_params_t *params) if (params->iptun_param_flags & ~(IPTUN_PARAM_LADDR|IPTUN_PARAM_RADDR)) return (DLADM_STATUS_BADARG); - status = dladm_read_conf(handle, params->iptun_param_linkid, &conf); + status = dladm_open_conf(handle, params->iptun_param_linkid, &conf); if (status != DLADM_STATUS_OK) return (status); diff --git a/usr/src/lib/libdladm/common/libdllink.c b/usr/src/lib/libdladm/common/libdllink.c index 159df78068..8a3c5759ee 100644 --- a/usr/src/lib/libdladm/common/libdllink.c +++ b/usr/src/lib/libdladm/common/libdllink.c @@ -523,7 +523,7 @@ i_dladm_rename_link_c2(dladm_handle_t handle, datalink_id_t linkid1, (void) dladm_set_linkprop(handle, linkid1, NULL, NULL, 0, DLADM_OPT_ACTIVE); - if (((status = dladm_read_conf(handle, linkid1, &conf1)) != + if (((status = dladm_getsnap_conf(handle, linkid1, &conf1)) != DLADM_STATUS_OK) || ((status = dladm_get_conf_field(handle, conf1, FDEVNAME, devname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) || @@ -531,7 +531,7 @@ i_dladm_rename_link_c2(dladm_handle_t handle, datalink_id_t linkid1, sizeof (uint64_t))) != DLADM_STATUS_OK) || ((status = dladm_get_conf_field(handle, conf1, FPHYINST, &phyinst, sizeof (uint64_t))) != DLADM_STATUS_OK) || - ((status = dladm_read_conf(handle, linkid2, &conf2)) != + ((status = dladm_open_conf(handle, linkid2, &conf2)) != DLADM_STATUS_OK)) { dir.dir_linkid1 = linkid2; dir.dir_linkid2 = linkid1; @@ -601,7 +601,7 @@ i_dladm_rename_link_c3(dladm_handle_t handle, const char *link1, if (!dladm_valid_linkname(link1)) return (DLADM_STATUS_LINKINVAL); - status = dladm_read_conf(handle, linkid2, &conf); + status = dladm_open_conf(handle, linkid2, &conf); if (status != DLADM_STATUS_OK) goto done; @@ -823,7 +823,7 @@ dladm_phys_info(dladm_handle_t handle, datalink_id_t linkid, case DLADM_OPT_PERSIST: { dladm_conf_t conf; - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_getsnap_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); diff --git a/usr/src/lib/libdladm/common/libdllink.h b/usr/src/lib/libdladm/common/libdllink.h index 9d5d19a898..a2830b5e37 100644 --- a/usr/src/lib/libdladm/common/libdllink.h +++ b/usr/src/lib/libdladm/common/libdllink.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LIBDLLINK_H @@ -180,7 +179,9 @@ extern dladm_status_t dladm_walk_datalink_id(int (*)(dladm_handle_t, extern dladm_status_t dladm_create_conf(dladm_handle_t, const char *, datalink_id_t, datalink_class_t, uint32_t, dladm_conf_t *); -extern dladm_status_t dladm_read_conf(dladm_handle_t, datalink_id_t, +extern dladm_status_t dladm_open_conf(dladm_handle_t, datalink_id_t, + dladm_conf_t *); +extern dladm_status_t dladm_getsnap_conf(dladm_handle_t, datalink_id_t, dladm_conf_t *); extern dladm_status_t dladm_write_conf(dladm_handle_t, dladm_conf_t); extern dladm_status_t dladm_remove_conf(dladm_handle_t, datalink_id_t); diff --git a/usr/src/lib/libdladm/common/libdlmgmt.c b/usr/src/lib/libdladm/common/libdlmgmt.c index 1827bfb504..49c70b4c6e 100644 --- a/usr/src/lib/libdladm/common/libdlmgmt.c +++ b/usr/src/lib/libdladm/common/libdlmgmt.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <door.h> @@ -53,7 +52,7 @@ static size_t dladm_datatype_size[] = { static dladm_status_t dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf, - size_t rsize) + size_t *rsizep) { door_arg_t darg; int door_fd; @@ -64,7 +63,7 @@ dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf, darg.desc_ptr = NULL; darg.desc_num = 0; darg.rbuf = rbuf; - darg.rsize = rsize; + darg.rsize = *rsizep; /* The door descriptor is opened if it isn't already */ if ((status = dladm_door_fd(handle, &door_fd)) != DLADM_STATUS_OK) @@ -77,14 +76,15 @@ dladm_door_call(dladm_handle_t handle, void *arg, size_t asize, void *rbuf, if (darg.rbuf != rbuf) { /* * The size of the input rbuf is not big enough so that - * the door allocate the rbuf itself. In this case, simply - * think something wrong with the door call. + * the door allocate the rbuf itself. In this case, return + * the required size to the caller. */ (void) munmap(darg.rbuf, darg.rsize); + *rsizep = darg.rsize; return (DLADM_STATUS_TOOSMALL); - } - if (darg.rsize != rsize) + } else if (darg.rsize != *rsizep) { return (DLADM_STATUS_FAILED); + } return (dladm_errno2status(((dlmgmt_retval_t *)rbuf)->lr_err)); } @@ -101,6 +101,7 @@ dladm_create_datalink_id(dladm_handle_t handle, const char *link, dlmgmt_createid_retval_t retval; uint32_t dlmgmt_flags; dladm_status_t status; + size_t sz = sizeof (retval); if (link == NULL || class == DATALINK_CLASS_ALL || !(flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST)) || @@ -119,7 +120,7 @@ dladm_create_datalink_id(dladm_handle_t handle, const char *link, createid.ld_prefix = (flags & DLADM_OPT_PREFIX); if ((status = dladm_door_call(handle, &createid, sizeof (createid), - &retval, sizeof (retval))) == DLADM_STATUS_OK) { + &retval, &sz)) == DLADM_STATUS_OK) { *linkidp = retval.lr_linkid; } return (status); @@ -135,6 +136,7 @@ dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid, dlmgmt_door_destroyid_t destroyid; dlmgmt_destroyid_retval_t retval; uint32_t dlmgmt_flags; + size_t sz = sizeof (retval); dlmgmt_flags = (flags & DLADM_OPT_ACTIVE) ? DLMGMT_ACTIVE : 0; dlmgmt_flags |= ((flags & DLADM_OPT_PERSIST) ? DLMGMT_PERSIST : 0); @@ -143,8 +145,8 @@ dladm_destroy_datalink_id(dladm_handle_t handle, datalink_id_t linkid, destroyid.ld_linkid = linkid; destroyid.ld_flags = dlmgmt_flags; - return (dladm_door_call(handle, &destroyid, sizeof (destroyid), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &destroyid, sizeof (destroyid), + &retval, &sz)); } /* @@ -156,13 +158,14 @@ dladm_remap_datalink_id(dladm_handle_t handle, datalink_id_t linkid, { dlmgmt_door_remapid_t remapid; dlmgmt_remapid_retval_t retval; + size_t sz = sizeof (retval); remapid.ld_cmd = DLMGMT_CMD_REMAP_LINKID; remapid.ld_linkid = linkid; (void) strlcpy(remapid.ld_link, link, MAXLINKNAMELEN); - return (dladm_door_call(handle, &remapid, sizeof (remapid), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &remapid, sizeof (remapid), + &retval, &sz)); } /* @@ -173,12 +176,12 @@ dladm_up_datalink_id(dladm_handle_t handle, datalink_id_t linkid) { dlmgmt_door_upid_t upid; dlmgmt_upid_retval_t retval; + size_t sz = sizeof (retval); upid.ld_cmd = DLMGMT_CMD_UP_LINKID; upid.ld_linkid = linkid; - return (dladm_door_call(handle, &upid, sizeof (upid), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &upid, sizeof (upid), &retval, &sz)); } /* @@ -191,6 +194,7 @@ dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid, dlmgmt_door_createconf_t createconf; dlmgmt_createconf_retval_t retval; dladm_status_t status; + size_t sz = sizeof (retval); if (link == NULL || confp == NULL) return (DLADM_STATUS_BADARG); @@ -200,10 +204,12 @@ dladm_create_conf(dladm_handle_t handle, const char *link, datalink_id_t linkid, createconf.ld_media = media; createconf.ld_linkid = linkid; createconf.ld_cmd = DLMGMT_CMD_CREATECONF; + confp->ds_confid = DLADM_INVALID_CONF; if ((status = dladm_door_call(handle, &createconf, sizeof (createconf), - &retval, sizeof (retval))) == DLADM_STATUS_OK) { - *confp = retval.lr_conf; + &retval, &sz)) == DLADM_STATUS_OK) { + confp->ds_readonly = B_FALSE; + confp->ds_confid = retval.lr_confid; } return (status); } @@ -259,6 +265,7 @@ dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *), uint32_t dlmgmt_flags; datalink_id_t linkid = DATALINK_INVALID_LINKID; dladm_status_t status = DLADM_STATUS_OK; + size_t sz = sizeof (retval); if (fn == NULL) return (DLADM_STATUS_BADARG); @@ -274,8 +281,7 @@ dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *), do { getnext.ld_linkid = linkid; if ((status = dladm_door_call(handle, &getnext, - sizeof (getnext), &retval, sizeof (retval))) != - DLADM_STATUS_OK) { + sizeof (getnext), &retval, &sz)) != DLADM_STATUS_OK) { /* * Done with walking. If no next datalink is found, * return success. @@ -310,26 +316,78 @@ dladm_walk_datalink_id(int (*fn)(dladm_handle_t, datalink_id_t, void *), } /* - * Get the link properties structure for the given link. + * Get a handle of a copy of the link configuration (kept in the daemon) + * for the given link so it can be updated later by dladm_write_conf(). + */ +dladm_status_t +dladm_open_conf(dladm_handle_t handle, datalink_id_t linkid, + dladm_conf_t *confp) +{ + dlmgmt_door_openconf_t openconf; + dlmgmt_openconf_retval_t retval; + dladm_status_t status; + size_t sz; + + if (linkid == DATALINK_INVALID_LINKID || confp == NULL) + return (DLADM_STATUS_BADARG); + + sz = sizeof (retval); + openconf.ld_linkid = linkid; + openconf.ld_cmd = DLMGMT_CMD_OPENCONF; + confp->ds_confid = DLADM_INVALID_CONF; + if ((status = dladm_door_call(handle, &openconf, + sizeof (openconf), &retval, &sz)) == DLADM_STATUS_OK) { + confp->ds_readonly = B_FALSE; + confp->ds_confid = retval.lr_confid; + } + + return (status); +} + +/* + * Get the handle of a local snapshot of the link configuration. Note that + * any operations with this handle are read-only, i.e., one can not update + * the configuration with this handle. */ dladm_status_t -dladm_read_conf(dladm_handle_t handle, datalink_id_t linkid, +dladm_getsnap_conf(dladm_handle_t handle, datalink_id_t linkid, dladm_conf_t *confp) { - dlmgmt_door_readconf_t readconf; - dlmgmt_readconf_retval_t retval; + dlmgmt_door_getconfsnapshot_t snapshot; + dlmgmt_getconfsnapshot_retval_t *retvalp; + char *nvlbuf; dladm_status_t status; + int err; + size_t sz; if (linkid == DATALINK_INVALID_LINKID || confp == NULL) return (DLADM_STATUS_BADARG); - readconf.ld_linkid = linkid; - readconf.ld_cmd = DLMGMT_CMD_READCONF; + sz = sizeof (dlmgmt_getconfsnapshot_retval_t); + snapshot.ld_linkid = linkid; + snapshot.ld_cmd = DLMGMT_CMD_GETCONFSNAPSHOT; +again: + if ((retvalp = malloc(sz)) == NULL) + return (DLADM_STATUS_NOMEM); + + if ((status = dladm_door_call(handle, &snapshot, sizeof (snapshot), + retvalp, &sz)) == DLADM_STATUS_TOOSMALL) { + free(retvalp); + goto again; + } + + if (status != DLADM_STATUS_OK) { + free(retvalp); + return (status); + } - if ((status = dladm_door_call(handle, &readconf, sizeof (readconf), - &retval, sizeof (retval))) == DLADM_STATUS_OK) { - *confp = retval.lr_conf; + confp->ds_readonly = B_TRUE; + nvlbuf = (char *)retvalp + sizeof (dlmgmt_getconfsnapshot_retval_t); + if ((err = nvlist_unpack(nvlbuf, retvalp->lr_nvlsz, + &(confp->ds_nvl), NV_ENCODE_NATIVE)) != 0) { + status = dladm_errno2status(err); } + free(retvalp); return (status); } @@ -342,83 +400,117 @@ dladm_write_conf(dladm_handle_t handle, dladm_conf_t conf) { dlmgmt_door_writeconf_t writeconf; dlmgmt_writeconf_retval_t retval; + size_t sz = sizeof (retval); - if (conf == DLADM_INVALID_CONF) + if (conf.ds_confid == DLADM_INVALID_CONF) return (DLADM_STATUS_BADARG); + if (conf.ds_readonly) + return (DLADM_STATUS_DENIED); + writeconf.ld_cmd = DLMGMT_CMD_WRITECONF; - writeconf.ld_conf = conf; + writeconf.ld_confid = conf.ds_confid; - return (dladm_door_call(handle, &writeconf, sizeof (writeconf), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &writeconf, sizeof (writeconf), + &retval, &sz)); } /* - * Given a link ID and a key, get the matching information from - * data link configuration repository. + * Given a dladm_conf_t, get the specific configuration field + * + * If the specified dladm_conf_t is a read-only snapshot of the configuration, + * get a specific link propertie from that snapshot (nvl), otherwise, get + * the link protperty from the dlmgmtd daemon using the given confid. */ dladm_status_t dladm_get_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, void *attrval, size_t attrsz) { - dlmgmt_door_getattr_t getattr; - dlmgmt_getattr_retval_t retval; - dladm_status_t status; + dladm_status_t status = DLADM_STATUS_OK; - if (conf == DLADM_INVALID_CONF || attrval == NULL || - attrsz == 0 || attr == NULL) { + if (attrval == NULL || attrsz == 0 || attr == NULL) return (DLADM_STATUS_BADARG); - } - getattr.ld_cmd = DLMGMT_CMD_GETATTR; - getattr.ld_conf = conf; - (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); + if (conf.ds_readonly) { + uchar_t *oattrval; + uint32_t oattrsz; + int err; - if ((status = dladm_door_call(handle, &getattr, sizeof (getattr), - &retval, sizeof (retval))) != DLADM_STATUS_OK) { - return (status); - } + if ((err = nvlist_lookup_byte_array(conf.ds_nvl, (char *)attr, + &oattrval, &oattrsz)) != 0) { + return (dladm_errno2status(err)); + } + if (oattrsz > attrsz) + return (DLADM_STATUS_TOOSMALL); - if (retval.lr_attrsz > attrsz) - return (DLADM_STATUS_TOOSMALL); + bcopy(oattrval, attrval, oattrsz); + } else { + dlmgmt_door_getattr_t getattr; + dlmgmt_getattr_retval_t retval; + size_t sz = sizeof (retval); - bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); - return (DLADM_STATUS_OK); + if (conf.ds_confid == DLADM_INVALID_CONF) + return (DLADM_STATUS_BADARG); + + getattr.ld_cmd = DLMGMT_CMD_GETATTR; + getattr.ld_confid = conf.ds_confid; + (void) strlcpy(getattr.ld_attr, attr, MAXLINKATTRLEN); + + if ((status = dladm_door_call(handle, &getattr, + sizeof (getattr), &retval, &sz)) != DLADM_STATUS_OK) { + return (status); + } + + if (retval.lr_attrsz > attrsz) + return (DLADM_STATUS_TOOSMALL); + + bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); + } + return (status); } /* * Get next property attribute from data link configuration repository. + * If last_attr is "", return the first property. */ +/* ARGSUSED */ dladm_status_t dladm_getnext_conf_linkprop(dladm_handle_t handle, dladm_conf_t conf, const char *last_attr, char *attr, void *attrval, size_t attrsz, size_t *attrszp) { - dlmgmt_door_linkprop_getnext_t getnext; - dlmgmt_linkprop_getnext_retval_t retval; - dladm_status_t status; - - if (conf == DLADM_INVALID_CONF || attrval == NULL || - attrsz == 0 || attr == NULL) { + nvlist_t *nvl = conf.ds_nvl; + nvpair_t *last = NULL, *nvp; + uchar_t *oattrval; + uint32_t oattrsz; + int err; + + if (nvl == NULL || attrval == NULL || attrsz == 0 || attr == NULL || + !conf.ds_readonly) return (DLADM_STATUS_BADARG); + + while ((nvp = nvlist_next_nvpair(nvl, last)) != NULL) { + if (last_attr[0] == '\0') + break; + if (last != NULL && strcmp(last_attr, nvpair_name(last)) == 0) + break; + last = nvp; } - getnext.ld_cmd = DLMGMT_CMD_LINKPROP_GETNEXT; - getnext.ld_conf = conf; - (void) strlcpy(getnext.ld_last_attr, last_attr, MAXLINKATTRLEN); + if (nvp == NULL) + return (DLADM_STATUS_NOTFOUND); - if ((status = dladm_door_call(handle, &getnext, sizeof (getnext), - &retval, sizeof (retval))) != DLADM_STATUS_OK) { - return (status); + if ((err = nvpair_value_byte_array(nvp, (uchar_t **)&oattrval, + &oattrsz)) != NULL) { + return (dladm_errno2status(err)); } - *attrszp = retval.lr_attrsz; - if (retval.lr_attrsz > attrsz) { + *attrszp = oattrsz; + if (oattrsz > attrsz) return (DLADM_STATUS_TOOSMALL); - } - (void) strlcpy(attr, retval.lr_attr, MAXLINKATTRLEN); - bcopy(retval.lr_attrval, attrval, retval.lr_attrsz); + (void) strlcpy(attr, nvpair_name(nvp), MAXLINKATTRLEN); + bcopy(oattrval, attrval, oattrsz); return (DLADM_STATUS_OK); } @@ -433,12 +525,13 @@ dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp, dlmgmt_getlinkid_retval_t retval; datalink_id_t linkid; dladm_status_t status; + size_t sz = sizeof (retval); getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid), - &retval, sizeof (retval))) != DLADM_STATUS_OK) { + &retval, &sz)) != DLADM_STATUS_OK) { return (status); } @@ -480,6 +573,7 @@ dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid, dlmgmt_door_getname_t getname; dlmgmt_getname_retval_t retval; dladm_status_t status; + size_t sz = sizeof (retval); if ((linkid == DATALINK_INVALID_LINKID) || (link != NULL && len == 0) || (link == NULL && len != 0)) { @@ -489,7 +583,7 @@ dladm_datalink_id2info(dladm_handle_t handle, datalink_id_t linkid, getname.ld_cmd = DLMGMT_CMD_GETNAME; getname.ld_linkid = linkid; if ((status = dladm_door_call(handle, &getname, sizeof (getname), - &retval, sizeof (retval))) != DLADM_STATUS_OK) { + &retval, &sz)) != DLADM_STATUS_OK) { return (status); } @@ -532,10 +626,14 @@ dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, dlmgmt_door_setattr_t setattr; dlmgmt_setattr_retval_t retval; size_t attrsz; + size_t sz = sizeof (retval); if (attr == NULL || attrval == NULL) return (DLADM_STATUS_BADARG); + if (conf.ds_readonly) + return (DLADM_STATUS_DENIED); + if (type == DLADM_TYPE_STR) attrsz = strlen(attrval) + 1; else @@ -545,14 +643,14 @@ dladm_set_conf_field(dladm_handle_t handle, dladm_conf_t conf, const char *attr, return (DLADM_STATUS_TOOSMALL); setattr.ld_cmd = DLMGMT_CMD_SETATTR; - setattr.ld_conf = conf; + setattr.ld_confid = conf.ds_confid; (void) strlcpy(setattr.ld_attr, attr, MAXLINKATTRLEN); setattr.ld_attrsz = attrsz; setattr.ld_type = type; bcopy(attrval, &setattr.ld_attrval, attrsz); - return (dladm_door_call(handle, &setattr, sizeof (setattr), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &setattr, sizeof (setattr), + &retval, &sz)); } /* @@ -564,16 +662,20 @@ dladm_unset_conf_field(dladm_handle_t handle, dladm_conf_t conf, { dlmgmt_door_unsetattr_t unsetattr; dlmgmt_unsetattr_retval_t retval; + size_t sz = sizeof (retval); if (attr == NULL) return (DLADM_STATUS_BADARG); + if (conf.ds_readonly) + return (DLADM_STATUS_DENIED); + unsetattr.ld_cmd = DLMGMT_CMD_UNSETATTR; - unsetattr.ld_conf = conf; + unsetattr.ld_confid = conf.ds_confid; (void) strlcpy(unsetattr.ld_attr, attr, MAXLINKATTRLEN); - return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &unsetattr, sizeof (unsetattr), + &retval, &sz)); } /* @@ -585,12 +687,13 @@ dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid) { dlmgmt_door_removeconf_t removeconf; dlmgmt_removeconf_retval_t retval; + size_t sz = sizeof (retval); removeconf.ld_cmd = DLMGMT_CMD_REMOVECONF; removeconf.ld_linkid = linkid; return (dladm_door_call(handle, &removeconf, sizeof (removeconf), - &retval, sizeof (retval))); + &retval, &sz)); } /* @@ -599,17 +702,22 @@ dladm_remove_conf(dladm_handle_t handle, datalink_id_t linkid) void dladm_destroy_conf(dladm_handle_t handle, dladm_conf_t conf) { - dlmgmt_door_destroyconf_t destroyconf; + dlmgmt_door_destroyconf_t dconf; dlmgmt_destroyconf_retval_t retval; + size_t sz = sizeof (retval); - if (conf == DLADM_INVALID_CONF) - return; + if (conf.ds_readonly) { + nvlist_free(conf.ds_nvl); + } else { + if (conf.ds_confid == DLADM_INVALID_CONF) + return; - destroyconf.ld_cmd = DLMGMT_CMD_DESTROYCONF; - destroyconf.ld_conf = conf; + dconf.ld_cmd = DLMGMT_CMD_DESTROYCONF; + dconf.ld_confid = conf.ds_confid; - (void) dladm_door_call(handle, &destroyconf, sizeof (destroyconf), - &retval, sizeof (retval)); + (void) dladm_door_call(handle, &dconf, sizeof (dconf), + &retval, &sz); + } } dladm_status_t @@ -617,11 +725,12 @@ dladm_zone_boot(dladm_handle_t handle, zoneid_t zoneid) { dlmgmt_door_zoneboot_t zoneboot; dlmgmt_zoneboot_retval_t retval; + size_t sz = sizeof (retval); zoneboot.ld_cmd = DLMGMT_CMD_ZONEBOOT; zoneboot.ld_zoneid = zoneid; - return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &zoneboot, sizeof (zoneboot), + &retval, &sz)); } dladm_status_t @@ -629,9 +738,10 @@ dladm_zone_halt(dladm_handle_t handle, zoneid_t zoneid) { dlmgmt_door_zonehalt_t zonehalt; dlmgmt_zonehalt_retval_t retval; + size_t sz = sizeof (retval); zonehalt.ld_cmd = DLMGMT_CMD_ZONEHALT; zonehalt.ld_zoneid = zoneid; - return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt), &retval, - sizeof (retval))); + return (dladm_door_call(handle, &zonehalt, sizeof (zonehalt), + &retval, &sz)); } diff --git a/usr/src/lib/libdladm/common/libdlmgmt.h b/usr/src/lib/libdladm/common/libdlmgmt.h index c170629647..2e208209e8 100644 --- a/usr/src/lib/libdladm/common/libdlmgmt.h +++ b/usr/src/lib/libdladm/common/libdlmgmt.h @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -49,7 +48,7 @@ extern "C" { #define DLMGMT_CMD_DESTROY_LINKID (DLMGMT_CMD_BASE + 1) #define DLMGMT_CMD_REMAP_LINKID (DLMGMT_CMD_BASE + 2) #define DLMGMT_CMD_CREATECONF (DLMGMT_CMD_BASE + 3) -#define DLMGMT_CMD_READCONF (DLMGMT_CMD_BASE + 4) +#define DLMGMT_CMD_OPENCONF (DLMGMT_CMD_BASE + 4) #define DLMGMT_CMD_WRITECONF (DLMGMT_CMD_BASE + 5) #define DLMGMT_CMD_UP_LINKID (DLMGMT_CMD_BASE + 6) #define DLMGMT_CMD_SETATTR (DLMGMT_CMD_BASE + 7) @@ -57,7 +56,7 @@ extern "C" { #define DLMGMT_CMD_REMOVECONF (DLMGMT_CMD_BASE + 9) #define DLMGMT_CMD_DESTROYCONF (DLMGMT_CMD_BASE + 10) #define DLMGMT_CMD_GETATTR (DLMGMT_CMD_BASE + 11) -#define DLMGMT_CMD_LINKPROP_GETNEXT (DLMGMT_CMD_BASE + 12) +#define DLMGMT_CMD_GETCONFSNAPSHOT (DLMGMT_CMD_BASE + 12) #define DLMGMT_CMD_ZONEBOOT (DLMGMT_CMD_BASE + 13) #define DLMGMT_CMD_ZONEHALT (DLMGMT_CMD_BASE + 14) @@ -97,7 +96,7 @@ typedef struct dlmgmt_door_createconf_s { typedef struct dlmgmt_door_setattr_s { int ld_cmd; - dladm_conf_t ld_conf; + int ld_confid; char ld_attr[MAXLINKATTRLEN]; size_t ld_attrsz; dladm_datatype_t ld_type; @@ -106,13 +105,13 @@ typedef struct dlmgmt_door_setattr_s { typedef struct dlmgmt_door_unsetattr_s { int ld_cmd; - dladm_conf_t ld_conf; + int ld_confid; char ld_attr[MAXLINKATTRLEN]; } dlmgmt_door_unsetattr_t; typedef struct dlmgmt_door_writeconf_s { int ld_cmd; - dladm_conf_t ld_conf; + int ld_confid; } dlmgmt_door_writeconf_t; typedef struct dlmgmt_door_removeconf_s { @@ -122,38 +121,40 @@ typedef struct dlmgmt_door_removeconf_s { typedef struct dlmgmt_door_destroyconf_s { int ld_cmd; - dladm_conf_t ld_conf; + int ld_confid; } dlmgmt_door_destroyconf_t; -typedef struct dlmgmt_door_readconf_s { +typedef struct dlmgmt_door_openconf_s { int ld_cmd; datalink_id_t ld_linkid; -} dlmgmt_door_readconf_t; +} dlmgmt_door_openconf_t; + +typedef struct dlmgmt_door_getconfsnapshot_s { + int ld_cmd; + datalink_id_t ld_linkid; +} dlmgmt_door_getconfsnapshot_t; typedef struct dlmgmt_door_getattr_s { int ld_cmd; - dladm_conf_t ld_conf; + int ld_confid; char ld_attr[MAXLINKATTRLEN]; } dlmgmt_door_getattr_t; -typedef struct dlmgmt_handle_retval_s { - uint_t lr_err; - dladm_conf_t lr_conf; -} dlmgmt_createconf_retval_t, dlmgmt_readconf_retval_t; - -typedef struct dlmgmt_door_linkprop_getnext_s { - int ld_cmd; - dladm_conf_t ld_conf; - char ld_last_attr[MAXLINKATTRLEN]; -} dlmgmt_door_linkprop_getnext_t; - -typedef struct dlmgmt_linkprop_getnext_retval_s { +typedef struct dlmgmt_createconf_retval_s { uint_t lr_err; - char lr_attr[MAXLINKATTRLEN]; - uint_t lr_type; - uint_t lr_attrsz; - char lr_attrval[MAXLINKATTRVALLEN]; -} dlmgmt_linkprop_getnext_retval_t; + int lr_confid; +} dlmgmt_createconf_retval_t; + +typedef struct dlmgmt_openconf_retval_s { + uint_t lr_err; + int lr_confid; +} dlmgmt_openconf_retval_t; + +typedef struct dlmgmt_getconfsnapshot_retval_s { + uint_t lr_err; + size_t lr_nvlsz; + /* buffer for nvl */ +} dlmgmt_getconfsnapshot_retval_t; typedef struct dlmgmt_door_zone_s { int ld_cmd; diff --git a/usr/src/lib/libdladm/common/libdlsim.c b/usr/src/lib/libdladm/common/libdlsim.c index a588073bfb..7b8c515875 100644 --- a/usr/src/lib/libdladm/common/libdlsim.c +++ b/usr/src/lib/libdladm/common/libdlsim.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/types.h> @@ -142,8 +141,8 @@ i_dladm_get_simnet_info_persist(dladm_handle_t handle, uint64_t u64; boolean_t mac_fixed; - if ((status = dladm_read_conf(handle, attrp->sna_link_id, &conf)) != - DLADM_STATUS_OK) + if ((status = dladm_getsnap_conf(handle, attrp->sna_link_id, + &conf)) != DLADM_STATUS_OK) return (status); status = dladm_get_conf_field(handle, conf, FSIMNETTYPE, &u64, @@ -228,7 +227,7 @@ i_dladm_simnet_update_conf(dladm_handle_t handle, datalink_id_t simnet_id, dladm_conf_t conf; char simnetpeer[MAXLINKNAMELEN]; - status = dladm_read_conf(handle, simnet_id, &conf); + status = dladm_open_conf(handle, simnet_id, &conf); if (status != DLADM_STATUS_OK) return (status); @@ -474,7 +473,7 @@ static dladm_status_t dladm_simnet_persist_conf(dladm_handle_t handle, const char *name, dladm_simnet_attr_t *attrp) { - dladm_conf_t conf = DLADM_INVALID_CONF; + dladm_conf_t conf; dladm_status_t status; char mstr[ETHERADDRL * 3]; uint64_t u64; diff --git a/usr/src/lib/libdladm/common/libdlvnic.c b/usr/src/lib/libdladm/common/libdlvnic.c index 7ff9563e1a..6dba8d6fad 100644 --- a/usr/src/lib/libdladm/common/libdlvnic.c +++ b/usr/src/lib/libdladm/common/libdlvnic.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdio.h> @@ -199,7 +198,7 @@ i_dladm_vnic_info_persist(dladm_handle_t handle, datalink_id_t linkid, datalink_class_t class; attrp->va_vnic_id = linkid; - if ((status = dladm_read_conf(handle, linkid, &conf)) != + if ((status = dladm_getsnap_conf(handle, linkid, &conf)) != DLADM_STATUS_OK) return (status); @@ -279,7 +278,6 @@ i_dladm_vnic_info_persist(dladm_handle_t handle, datalink_id_t linkid, sizeof (u64)); attrp->va_vid = ((status == DLADM_STATUS_OK) ? (uint16_t)u64 : 0); - status = DLADM_STATUS_OK; done: dladm_destroy_conf(handle, conf); @@ -663,7 +661,7 @@ static dladm_status_t dladm_vnic_persist_conf(dladm_handle_t handle, const char *name, dladm_vnic_attr_t *attrp, datalink_class_t class) { - dladm_conf_t conf = DLADM_INVALID_CONF; + dladm_conf_t conf; dladm_status_t status; char macstr[ETHERADDRL * 3]; char linkover[MAXLINKNAMELEN]; diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index b9f38012ed..4a7865d0e6 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -3309,7 +3309,7 @@ i_dladm_set_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, dladm_conf_t conf; dladm_status_t status; - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_open_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); @@ -3349,7 +3349,7 @@ i_dladm_get_linkprop_db(dladm_handle_t handle, datalink_id_t linkid, dladm_conf_t conf; dladm_status_t status; - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_getsnap_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); @@ -3391,7 +3391,7 @@ i_dladm_walk_linkprop_priv_db(dladm_handle_t handle, datalink_id_t linkid, if (linkid == DATALINK_INVALID_LINKID || func == NULL) return (DLADM_STATUS_BADARG); - status = dladm_read_conf(handle, linkid, &conf); + status = dladm_getsnap_conf(handle, linkid, &conf); if (status != DLADM_STATUS_OK) return (status); diff --git a/usr/src/lib/libdladm/common/mapfile-vers b/usr/src/lib/libdladm/common/mapfile-vers index 10128b43a1..b781c93aff 100644 --- a/usr/src/lib/libdladm/common/mapfile-vers +++ b/usr/src/lib/libdladm/common/mapfile-vers @@ -137,7 +137,8 @@ SYMBOL_VERSION SUNWprivate_1.1 { dladm_datalink_id2info; dladm_walk_datalink_id; dladm_create_conf; - dladm_read_conf; + dladm_open_conf; + dladm_getsnap_conf; dladm_write_conf; dladm_remove_conf; dladm_destroy_conf; |