diff options
Diffstat (limited to 'usr/src/cmd')
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/bridged/events.c | 12 | ||||
| -rw-r--r-- | usr/src/cmd/dladm/dladm.c | 2 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_db.c | 52 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_door.c | 301 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_impl.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_util.c | 55 | ||||
| -rw-r--r-- | usr/src/cmd/rcm_daemon/common/vlan_rcm.c | 6 | ||||
| -rw-r--r-- | usr/src/cmd/rcm_daemon/common/vnic_rcm.c | 6 |
8 files changed, 263 insertions, 177 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); } |
