summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorCathy Zhou <Cathy.Zhou@Sun.COM>2010-07-14 15:39:08 -0400
committerCathy Zhou <Cathy.Zhou@Sun.COM>2010-07-14 15:39:08 -0400
commit327151705b7439cb7ab35c370f682cac7ef9523a (patch)
treedc70b1e9458066faef68e56f0be54073920c112c /usr
parent442384bb4f40e4893df0a79549264f04218e1d9f (diff)
downloadillumos-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')
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/bridged/events.c12
-rw-r--r--usr/src/cmd/dladm/dladm.c2
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_db.c52
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_door.c301
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_impl.h6
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_util.c55
-rw-r--r--usr/src/cmd/rcm_daemon/common/vlan_rcm.c6
-rw-r--r--usr/src/cmd/rcm_daemon/common/vnic_rcm.c6
-rw-r--r--usr/src/lib/libdladm/common/libdladm.h13
-rw-r--r--usr/src/lib/libdladm/common/libdlaggr.c17
-rw-r--r--usr/src/lib/libdladm/common/libdlbridge.c15
-rw-r--r--usr/src/lib/libdladm/common/libdlib.c6
-rw-r--r--usr/src/lib/libdladm/common/libdliptun.c10
-rw-r--r--usr/src/lib/libdladm/common/libdllink.c8
-rw-r--r--usr/src/lib/libdladm/common/libdllink.h7
-rw-r--r--usr/src/lib/libdladm/common/libdlmgmt.c286
-rw-r--r--usr/src/lib/libdladm/common/libdlmgmt.h57
-rw-r--r--usr/src/lib/libdladm/common/libdlsim.c11
-rw-r--r--usr/src/lib/libdladm/common/libdlvnic.c8
-rw-r--r--usr/src/lib/libdladm/common/linkprop.c6
-rw-r--r--usr/src/lib/libdladm/common/mapfile-vers3
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;