diff options
| author | Mike Christensen <Michael.Christensen@Sun.COM> | 2010-03-01 18:02:46 -0800 |
|---|---|---|
| committer | Mike Christensen <Michael.Christensen@Sun.COM> | 2010-03-01 18:02:46 -0800 |
| commit | 82629e3015252bf18319ba3815c773df23e21436 (patch) | |
| tree | babd90f2440f44cae78e40aef052d2760e973ca9 /usr/src | |
| parent | d78a6b7e13de1e122f6c7e0d539522698d83ec22 (diff) | |
| download | illumos-joyent-82629e3015252bf18319ba3815c773df23e21436.tar.gz | |
PSARC 2010/004 Logical Domains Information API and ldminfo
FWARC 2009/680 Domain UUID property
FWARC 2010/058 Logical Domains Agent Chassis Serial Number Message
6680702 RFE: Want a mechanism for Solaris to know if it is an LDOM and if so what type
6873151 RFE: unique ID for LDOMs to facillitate asset tracking
6712763 RFE: Need information about control domain from within a guest domain
Diffstat (limited to 'usr/src')
24 files changed, 1901 insertions, 47 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index 8600211ab7..1e8379a42e 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -497,12 +497,14 @@ sparc_SUBDIRS= \ cmd/prtdscp \ cmd/prtfru \ cmd/sckmd \ + cmd/virtinfo \ cmd/vntsd \ lib/libds \ lib/libdscp \ lib/libpri \ lib/libpcp \ lib/libtsalarm \ + lib/libv12n \ lib/storage \ stand diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 440a3856ce..f9b5f93981 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -500,6 +500,7 @@ sparc_SUBDIRS= \ scadm \ sckmd \ sf880drd \ + virtinfo \ vntsd # @@ -759,6 +760,7 @@ sparc_MSGSUBDIRS= \ fruadm \ prtdscp \ prtfru \ + virtinfo \ vntsd i386_MSGSUBDIRS= \ diff --git a/usr/src/cmd/ldmad/Makefile b/usr/src/cmd/ldmad/Makefile index c54c0b2ccc..49282b1739 100644 --- a/usr/src/cmd/ldmad/Makefile +++ b/usr/src/cmd/ldmad/Makefile @@ -30,25 +30,45 @@ SVCMETHOD= ldoms-agents include ../Makefile.cmd -SRCS= ldmad.c \ + +LOCAL_SRCS= ldmad.c \ ldma_log.c \ ldma_device.c \ ldma_system.c \ ldma_dio.c \ mdesc_lib.c +LOCAL_OBJS= $(LOCAL_SRCS:%.c=%.o) + +COMMONBASE = ../../common + +COMMON_SRCS = mdesc_findname.c \ + mdesc_findnodeprop.c \ + mdesc_fini.c \ + mdesc_getpropval.c \ + mdesc_getpropstr.c \ + mdesc_init_intern.c \ + mdesc_nodecount.c \ + mdesc_rootnode.c \ + mdesc_scandag.c + +COMMON_OBJS = $(COMMON_SRCS:%.c=%.o) -OBJS= $(SRCS:%.c=%.o) +OBJS = $(LOCAL_OBJS) $(COMMON_OBJS) +SRCS = $(LOCAL_SRCS) $(COMMON_SRCS:%.c=$(COMMONBASE)/mdesc/%.c) ROOTCMDDIR= $(ROOTLIB)/ldoms ROOTMANIFESTDIR= $(ROOTSVCPLATFORMSUN4V) $(ROOTMANIFEST) := FILEMODE= 444 -LDLIBS += -lds -ldladm -ldevinfo +LDLIBS += -lds -ldladm -ldevinfo -lpri INCS += -I$(ROOT)/usr/platform/sun4v/include/sys +INCS += -I$(SRC)/uts/sun4v CPPFLAGS += $(INCS) C99MODE = $(C99_ENABLE) +LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN + .KEEP_STATE: all: $(PROG) @@ -67,3 +87,8 @@ clean: $(RM) $(PROG) $(OBJS) $(LINT_FILES) include ../Makefile.targ + +%.o: $(COMMONBASE)/mdesc/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + diff --git a/usr/src/cmd/ldmad/ldma.h b/usr/src/cmd/ldmad/ldma.h index 3d05eeb5d8..f0253b6af7 100644 --- a/usr/src/cmd/ldmad/ldma.h +++ b/usr/src/cmd/ldmad/ldma.h @@ -73,6 +73,7 @@ extern "C" { #define LDMA_NAME_SYSTEM "agent-system" #define LDMA_MSGSYS_GET_SYSINFO 0x01 /* get system info request */ +#define LDMA_MSGSYS_GET_CHASSISNO 0x02 /* get chassis sno request */ /* * LDoms Direct IO Agent @@ -134,8 +135,27 @@ typedef enum ldma_request_status_t { typedef ldma_request_status_t (ldm_msg_func_t)(ds_ver_t *, ldma_message_header_t *, size_t, ldma_message_header_t **, size_t *); +/* + * The domain service framework only allows connexion of a domain with + * the control domain. So agents not running in the control domain can + * only receive requests from the control domain. But, agents running + * on the control can receive requests from any domain. + * + * For agents running in the control domain, the LDMA_MSGFLG_ACCESS_* + * flags control whether messages sent by domains different from the + * control domain should be processed or not. + * + * If a message handler is defined with LDMA_MSGFLG_ACCESS_CONTROL then + * only messages sent by the control domain should be processed. Otherwise + * if a message handler is defined with LDMA_MSGFLG_ACCESS_ANY then messages + * sent by any domain can be processed. + */ +#define LDMA_MSGFLG_ACCESS_CONTROL 0x00 +#define LDMA_MSGFLG_ACCESS_ANY 0x01 + typedef struct ldma_msg_handler { uint32_t msg_type; /* message type */ + uint32_t msg_flags; /* message flags */ ldm_msg_func_t *msg_handler; /* message handler */ } ldma_msg_handler_t; diff --git a/usr/src/cmd/ldmad/ldma_device.c b/usr/src/cmd/ldmad/ldma_device.c index 1a73d7743d..da16405e3a 100644 --- a/usr/src/cmd/ldmad/ldma_device.c +++ b/usr/src/cmd/ldmad/ldma_device.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -54,8 +54,10 @@ static ldm_msg_func_t ldma_dev_validate_nic; static ds_ver_t ldma_versions[] = { { 1, 0 } }; static ldma_msg_handler_t ldma_handlers[] = { - { LDMA_MSGDEV_VALIDATE_PATH, ldma_dev_validate_path }, - { LDMA_MSGDEV_VALIDATE_NIC, ldma_dev_validate_nic } + { LDMA_MSGDEV_VALIDATE_PATH, LDMA_MSGFLG_ACCESS_CONTROL, + ldma_dev_validate_path }, + { LDMA_MSGDEV_VALIDATE_NIC, LDMA_MSGFLG_ACCESS_CONTROL, + ldma_dev_validate_nic } }; ldma_agent_info_t ldma_device_info = { diff --git a/usr/src/cmd/ldmad/ldma_dio.c b/usr/src/cmd/ldmad/ldma_dio.c index 3959f95677..e5e6bd1aec 100644 --- a/usr/src/cmd/ldmad/ldma_dio.c +++ b/usr/src/cmd/ldmad/ldma_dio.c @@ -68,7 +68,8 @@ static ds_ver_t ldma_dio_vers[] = { {1, 0} }; static ldm_msg_func_t ldma_dio_pcidev_info_handler; static ldma_msg_handler_t ldma_dio_handlers[] = { - {MSGDIO_PCIDEV_INFO, ldma_dio_pcidev_info_handler}, + {MSGDIO_PCIDEV_INFO, LDMA_MSGFLG_ACCESS_CONTROL, + ldma_dio_pcidev_info_handler }, }; ldma_agent_info_t ldma_dio_info = { diff --git a/usr/src/cmd/ldmad/ldma_system.c b/usr/src/cmd/ldmad/ldma_system.c index 1db750e650..62a597f515 100644 --- a/usr/src/cmd/ldmad/ldma_system.c +++ b/usr/src/cmd/ldmad/ldma_system.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,12 +29,20 @@ */ #include <errno.h> +#include <fcntl.h> #include <libds.h> #include <stdio.h> +#include <stdlib.h> #include <strings.h> +#include <synch.h> +#include <thread.h> +#include <unistd.h> #include <sys/utsname.h> +#include <sys/mdesc.h> +#include <sys/mdesc_impl.h> #include "ldma.h" +#include "pri.h" #define LDMA_MODULE LDMA_NAME_SYSTEM @@ -42,11 +50,19 @@ #define LDMA_NHANDLERS (sizeof (ldma_handlers) / sizeof (ldma_msg_handler_t)) static ldm_msg_func_t ldma_sys_get_sysinfo; +static ldm_msg_func_t ldma_sys_get_chassisno; + +/* ptr to cached value of chassisno */ +static char *ldma_sys_chassisno = NULL; +mutex_t ldma_chassisno_lock = DEFAULTMUTEX; static ds_ver_t ldma_versions[] = { { 1, 0 } }; static ldma_msg_handler_t ldma_handlers[] = { - { LDMA_MSGSYS_GET_SYSINFO, ldma_sys_get_sysinfo } + { LDMA_MSGSYS_GET_SYSINFO, LDMA_MSGFLG_ACCESS_ANY, + ldma_sys_get_sysinfo }, + { LDMA_MSGSYS_GET_CHASSISNO, LDMA_MSGFLG_ACCESS_ANY, + ldma_sys_get_chassisno } }; ldma_agent_info_t ldma_system_info = { @@ -126,3 +142,160 @@ done: LDMA_DBG("GET_SYSINFO: return error %d", status); return (status); } + +/* + * Wrapper for MD free: need unused size argument. + */ +/* ARGSUSED */ +static void +ldma_md_free(void *buf, size_t n) +{ + free(buf); +} + +/* + * Wrapper for MD init: read PRI MD and invoke md_init_intern. + */ +static md_t * +ldma_md_init() +{ + md_t *mdp; + uint64_t *buf = NULL; + uint64_t token; + ssize_t status; + + if (pri_init() == -1) + return (NULL); + + status = pri_get(PRI_GET, &token, &buf, malloc, ldma_md_free); + pri_fini(); + + if (status == (ssize_t)(-1)) + return (NULL); + + mdp = md_init_intern(buf, malloc, ldma_md_free); + + return (mdp); +} + +/* + * Wrapper for md_fini. Allow NULL md ptr and free MD buffer. + */ +static void +ldma_md_fini(void *md) +{ + md_impl_t *mdp = (md_impl_t *)md; + + if (mdp) { + free(mdp->caddr); + (void) md_fini(md); + } +} + +static int +ldma_get_chassis_serialno(char **strp) +{ + md_t *mdp; + mde_cookie_t *component_nodes, rootnode; + int list_size, ncomponents, num_nodes, i; + char *component_type, *serialno; + int rv = 0; + + (void) mutex_lock(&ldma_chassisno_lock); + if (ldma_sys_chassisno != NULL) { + *strp = ldma_sys_chassisno; + (void) mutex_unlock(&ldma_chassisno_lock); + return (1); + } + + mdp = ldma_md_init(); + if (mdp == NULL) { + (void) mutex_unlock(&ldma_chassisno_lock); + return (0); + } + + num_nodes = md_node_count(mdp); + list_size = num_nodes * sizeof (mde_cookie_t); + component_nodes = malloc(list_size); + if (component_nodes == NULL) { + (void) mutex_unlock(&ldma_chassisno_lock); + ldma_md_fini(mdp); + return (0); + } + + rootnode = md_root_node(mdp); + + ncomponents = md_scan_dag(mdp, rootnode, md_find_name(mdp, "component"), + md_find_name(mdp, "fwd"), component_nodes); + + for (i = 0; i < ncomponents; i++) { + if (md_get_prop_str(mdp, component_nodes[i], "type", + &component_type)) + continue; + if (strcmp(component_type, "chassis") != 0) + continue; + if (md_get_prop_str(mdp, component_nodes[i], + "serial_number", &serialno) == 0) { + ldma_sys_chassisno = strdup(serialno); + *strp = ldma_sys_chassisno; + rv = 1; + break; + } + } + (void) mutex_unlock(&ldma_chassisno_lock); + free(component_nodes); + ldma_md_fini(mdp); + return (rv); +} + +/*ARGSUSED*/ +static ldma_request_status_t +ldma_sys_get_chassisno(ds_ver_t *ver, ldma_message_header_t *request, + size_t request_dlen, ldma_message_header_t **replyp, size_t *reply_dlenp) +{ + ldma_message_header_t *reply; + char *str; + size_t rlen; + char *data; + int status; + + LDMA_DBG("GET_CHASSISNO"); + + if (request->msg_info != 0 || request_dlen != 0) { + status = LDMA_REQ_INVALID; + goto done; + } + + if (ldma_get_chassis_serialno(&str) == 0) { + LDMA_DBG("GET_CHASSISNO: ldma_get_chassisno failed " + "with error %d", errno); + status = LDMA_REQ_FAILED; + goto done; + } + + rlen = strlen(str) + 1; + + reply = ldma_alloc_result_msg(request, rlen); + + if (reply == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + reply->msg_info = rlen; + + data = LDMA_HDR2DATA(reply); + + (void) strcpy(data, str); + + LDMA_DBG("GET_CHASSISNO: return info=%u, {%s}", rlen, str); + + *replyp = reply; + *reply_dlenp = rlen; + + return (LDMA_REQ_COMPLETED); + +done: + LDMA_DBG("GET_CHASSISNO: return error %d", status); + return (status); +} diff --git a/usr/src/cmd/ldmad/ldmad.c b/usr/src/cmd/ldmad/ldmad.c index b5d5247538..0eabe5385d 100644 --- a/usr/src/cmd/ldmad/ldmad.c +++ b/usr/src/cmd/ldmad/ldmad.c @@ -55,8 +55,12 @@ #include <stdio.h> #include <stdlib.h> #include <strings.h> +#include <synch.h> #include <syslog.h> +#include <thread.h> #include <unistd.h> +#include <sys/debug.h> +#include <sys/ldoms.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> @@ -66,12 +70,17 @@ #define LDMA_MODULE "ldm-agent-daemon" #define LDMA_CONTROL_DOMAIN_DHDL 0 /* id of the control domain */ -#define LDMA_DOMAIN_NAME_MAXLEN MAXNAMELEN + +typedef struct ldma_connexion_t { + ds_hdl_t hdl; /* connexion handle */ + ds_domain_hdl_t dhdl; /* connexion domain handle */ + ds_ver_t ver; /* connexion version */ +} ldma_connexion_t; typedef struct ldma_agent { ldma_agent_info_t *info; /* agent information */ - ds_hdl_t conn_hdl; /* connexion handler */ - ds_ver_t conn_ver; /* connexion version */ + mutex_t conn_lock; /* connexion table lock */ + ldma_connexion_t conn[LDOMS_MAX_DOMAINS]; /* connexions */ } ldma_agent_t; /* information about existing agents */ @@ -93,6 +102,106 @@ static char *cmdname; static pid_t daemon_pid = 0; /* + * Lookup connexion in agent connexion table. + */ +static ldma_connexion_t * +ldma_connexion_lookup(ldma_agent_t *agent, ds_hdl_t hdl) +{ + ldma_connexion_t *connp; + int i; + + ASSERT(MUTEX_HELD(&agent->conn_lock)); + for (connp = agent->conn, i = 0; i < LDOMS_MAX_DOMAINS; i++, connp++) { + if (connp->hdl == hdl) + return (connp); + } + return (NULL); +} + +/* + * Add connextion to agent connexion table. + */ +static int +ldma_connexion_add(ldma_agent_t *agent, ds_hdl_t hdl, ds_domain_hdl_t dhdl, + ds_ver_t *verp) +{ + ldma_connexion_t *connp; + ldma_connexion_t *availp = NULL; + int i; + + (void) mutex_lock(&agent->conn_lock); + for (connp = agent->conn, i = 0; i < LDOMS_MAX_DOMAINS; i++, connp++) { + if (connp->hdl == hdl) + break; + if (availp == NULL && connp->hdl == DS_INVALID_HDL) + availp = connp; + } + + if (i < LDOMS_MAX_DOMAINS) { + (void) mutex_unlock(&agent->conn_lock); + LDMA_INFO("agent %s hdl %llx already exists", agent->info->name, + hdl); + return (0); + } + + if (!availp) { + (void) mutex_unlock(&agent->conn_lock); + LDMA_INFO("agent %s too many connections", agent->info->name); + return (0); + } + + LDMA_DBG("agent %s adding connection (%x) %llx, %llx, %d.%d", + agent->info->name, availp, hdl, dhdl, verp->major, verp->minor); + + availp->hdl = hdl; + availp->dhdl = dhdl; + availp->ver = *verp; + (void) mutex_unlock(&agent->conn_lock); + return (1); +} + +/* + * Delete connexion from agent connexion table. + */ +static int +ldma_connexion_delete(ldma_agent_t *agent, ds_hdl_t hdl) +{ + ldma_connexion_t *connp; + + (void) mutex_lock(&agent->conn_lock); + if ((connp = ldma_connexion_lookup(agent, hdl)) == NULL) { + (void) mutex_unlock(&agent->conn_lock); + LDMA_INFO("agent %s connection delete failed to find %llx", + agent->info->name, hdl); + return (0); + } + + LDMA_DBG("agent %s deleting connection (%x) %llx", agent->info->name, + connp, hdl); + + connp->hdl = DS_INVALID_HDL; + connp->dhdl = 0; + connp->ver.major = 0; + connp->ver.minor = 0; + (void) mutex_unlock(&agent->conn_lock); + return (1); +} + +/* + * Initialize connexion table. + */ +static void +ldma_connexion_init(ldma_agent_t *agent) +{ + ldma_connexion_t *connp; + int i; + + for (connp = agent->conn, i = 0; i < LDOMS_MAX_DOMAINS; i++, connp++) { + connp->hdl = DS_INVALID_HDL; + } +} + +/* * Allocate a new message with the specified message number (msg_num), * message type (msg_type) and message data length (msg_dlen). Return * NULL if the allocation has failed. @@ -141,9 +250,9 @@ ldma_reg_cb(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver, ds_domain_hdl_t dhdl) { ldma_agent_t *agent = (ldma_agent_t *)arg; - char dname[LDMA_DOMAIN_NAME_MAXLEN]; + char dname[LDOMS_MAX_NAME_LEN]; - if (ds_dom_hdl_to_name(dhdl, dname, LDMA_DOMAIN_NAME_MAXLEN) != 0) { + if (ds_dom_hdl_to_name(dhdl, dname, LDOMS_MAX_NAME_LEN) != 0) { (void) strcpy(dname, "<unknown>"); } @@ -151,19 +260,11 @@ ldma_reg_cb(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver, agent->info->name, hdl, dhdl, dname, ver->major, ver->minor); /* - * Record client information if the connexion is from the control - * domain. The domain service framework only allows connexion of a - * domain with the control domain. However, if the agent is running - * on the control domain then it can see connexions coming from any - * domains. That's why we explicitly have to check if the connexion - * is effectively with the control domain. + * Record client information. Access control is done on a + * message-by-message basis upon receipt of the message. */ - if (dhdl == LDMA_CONTROL_DOMAIN_DHDL) { - agent->conn_hdl = hdl; - agent->conn_ver.major = ver->major; - agent->conn_ver.minor = ver->minor; - } else { - LDMA_INFO("agent %s will ignore any request from distrusted " + if (!ldma_connexion_add(agent, hdl, dhdl, ver)) { + LDMA_INFO("agent %s failed to add connection from " "domain %s", agent->info->name, dname); } } @@ -179,13 +280,9 @@ ldma_unreg_cb(ds_hdl_t hdl, ds_cb_arg_t arg) LDMA_DBG("%s: UNREGISTER hdl=%llx", agent->info->name, hdl); - if (agent->conn_hdl == hdl) { - agent->conn_hdl = 0; - agent->conn_ver.major = 0; - agent->conn_ver.minor = 0; - } else { - LDMA_INFO("agent %s has unregistered consumer from " - "distrusted domain", agent->info->name); + if (!ldma_connexion_delete(agent, hdl)) { + LDMA_INFO("agent %s failed to unregister handle %llx", + agent->info->name, hdl); } } @@ -203,6 +300,9 @@ ldma_data_cb(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, size_t len) ldma_msg_handler_t *handler; ldma_message_header_t *request = buf; ldma_message_header_t *reply = NULL; + ldma_connexion_t *connp; + ds_ver_t conn_ver; + ds_domain_hdl_t conn_dhdl; ldma_request_status_t status; size_t request_dlen, reply_len, reply_dlen = 0; int i; @@ -220,8 +320,16 @@ ldma_data_cb(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, size_t len) "dlen=%d", agent->info->name, hdl, request->msg_num, request->msg_type, request->msg_info, request_dlen); - /* reject any request which is not from the control domain */ - if (hdl != agent->conn_hdl) { + (void) mutex_lock(&agent->conn_lock); + connp = ldma_connexion_lookup(agent, hdl); + if (connp != NULL) { + conn_dhdl = connp->dhdl; + conn_ver = connp->ver; + } + (void) mutex_unlock(&agent->conn_lock); + + /* reject any request which is not in the connexion table */ + if (connp == NULL) { LDMA_DBG("%s: DATA hdl=%llx, rejecting request from a " "distrusted domain", agent->info->name, hdl); status = LDMA_REQ_DENIED; @@ -245,6 +353,15 @@ ldma_data_cb(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, size_t len) goto do_reply; } + /* reject any request from a guest which is not allowed */ + if ((conn_dhdl != LDMA_CONTROL_DOMAIN_DHDL) && + (handler->msg_flags & LDMA_MSGFLG_ACCESS_ANY) == 0) { + LDMA_DBG("%s: DATA hdl=%llx, rejecting request from a " + "distrusted domain", agent->info->name, hdl); + status = LDMA_REQ_DENIED; + goto do_reply; + } + if (handler->msg_handler == NULL) { /* * This type of message is defined by the agent but it @@ -259,8 +376,8 @@ ldma_data_cb(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, size_t len) } /* invoke the message handler of the agent */ - status = (*handler->msg_handler)(&agent->conn_ver, request, - request_dlen, &reply, &reply_dlen); + status = (*handler->msg_handler)(&conn_ver, request, request_dlen, + &reply, &reply_dlen); LDMA_DBG("%s: DATA hdl=%llx, handler stat=%d reply=%p rlen=%d", agent->info->name, hdl, status, (void *)reply, reply_dlen); @@ -330,9 +447,8 @@ ldma_register(ldma_agent_info_t *agent_info) goto register_fail; agent->info = agent_info; - agent->conn_hdl = 0; - agent->conn_ver.major = 0; - agent->conn_ver.minor = 0; + (void) mutex_init(&agent->conn_lock, USYNC_THREAD, NULL); + ldma_connexion_init(agent); ds_cap.svc_id = agent_info->name; ds_cap.vers = agent_info->vers; diff --git a/usr/src/cmd/virtinfo/Makefile b/usr/src/cmd/virtinfo/Makefile new file mode 100644 index 0000000000..3dd4733934 --- /dev/null +++ b/usr/src/cmd/virtinfo/Makefile @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= virtinfo + +include ../Makefile.cmd + +POFILES = virtinfo.po + +LDLIBS += -lv12n -luuid + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTUSRSBINPROG) + +clean: + $(RM) $(PROG) $(LINT_FILES) + +lint: lint_PROG + +include ../Makefile.targ diff --git a/usr/src/cmd/virtinfo/virtinfo.c b/usr/src/cmd/virtinfo/virtinfo.c new file mode 100644 index 0000000000..9aff0fcbdc --- /dev/null +++ b/usr/src/cmd/virtinfo/virtinfo.c @@ -0,0 +1,226 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> +#include <libgen.h> +#include <libintl.h> +#include <libv12n.h> +#include <zone.h> +#include <sys/types.h> +#include <sys/param.h> +#include <uuid/uuid.h> + +static char *cmdname; + +char *options = "acdpstu"; + +static void +virtinfo_usage() +{ + (void) fprintf(stderr, gettext("usage: %s [-%s]\n"), cmdname, options); + exit(1); +} + +static char * +virtinfo_cap_to_impl(int cap) +{ + if (cap & V12N_CAP_IMPL_LDOMS) + return ("LDoms"); + return ("Unknown"); +} + + +int +main(int argc, char *argv[]) +{ + int cap; + int roles; + size_t rv; + int opt; + int errflg = 0; + int aflg = 0, cflg = 0, dflg = 0, pflg = 0, sflg = 0, tflg = 0, + uflg = 0; + + cmdname = basename(argv[0]); + + /* disable getopt error messages */ + opterr = 0; + + while ((opt = getopt(argc, argv, options)) != EOF) { + + switch (opt) { + case 'a': + aflg = 1; + break; + case 'c': + cflg = 1; + break; + case 'd': + dflg = 1; + break; + case 'p': + pflg = 1; + break; + case 's': + sflg = 1; + break; + case 't': + tflg = 1; + break; + case 'u': + uflg = 1; + break; + case '?': + default: + errflg = 1; + break; + } + } + + if (errflg || optind != argc) + virtinfo_usage(); + + if (aflg) { + /* aflg -> set all flags except -p */ + cflg = dflg = sflg = tflg = uflg = 1; + } else if (cflg == 0 && dflg == 0 && sflg == 0 && tflg == 0 && + uflg == 0) { + /* no flag set, default to '-t' */ + tflg = 1; + } + + if (getzoneid() != GLOBAL_ZONEID) { + (void) printf(gettext( + "%s can only be run from the global zone\n"), cmdname); + exit(0); + } + + cap = v12n_capabilities(); + if ((cap & V12N_CAP_SUPPORTED) == 0) { + (void) printf(gettext("Virtual machines are not supported\n")); + exit(0); + } else if ((cap & V12N_CAP_ENABLED) == 0) { + (void) printf(gettext( + "Virtual machines (%s) are supported but not enabled\n"), + virtinfo_cap_to_impl(cap)); + exit(0); + } + + if (pflg) { + (void) printf("VERSION 1.0\n"); + } + + if (tflg) { + char *impl = "", *role = "", *io = "", *service = "", + *root = ""; + + roles = v12n_domain_roles(); + + if (roles == -1 || (cap & V12N_CAP_IMPL_LDOMS) == 0) { + if (pflg) + impl = "impl=Unknown"; + else + impl = "Unknown"; + } else if (pflg) { + impl = "impl=LDoms"; + role = (roles & V12N_ROLE_CONTROL) ? + "|control=true" : "|control=false"; + io = (roles & V12N_ROLE_IO) ? + "|io=true" : "|io=false"; + service = (roles & V12N_ROLE_SERVICE) ? + "|service=true" : "|service=false"; + root = (roles & V12N_ROLE_ROOT) ? + "|root=true" : "|root=false"; + } else { + impl = "LDoms"; + role = (roles & V12N_ROLE_CONTROL) ? + " control" : " guest"; + io = (roles & V12N_ROLE_IO) ? + " I/O" : ""; + service = (roles & V12N_ROLE_SERVICE) ? + " service" : ""; + root = (roles & V12N_ROLE_ROOT) ? + " root" : ""; + } + (void) printf("%s%s%s%s%s%s\n", pflg ? "DOMAINROLE|" : + gettext("Domain role: "), impl, role, io, service, root); + } + + if (dflg) { + char domain_name[V12N_NAME_MAX]; + + rv = v12n_domain_name(domain_name, sizeof (domain_name)); + if (rv == (size_t)(-1)) { + (void) strcpy(domain_name, "Unknown"); + } + (void) printf("%s%s\n", pflg ? "DOMAINNAME|name=" : + gettext("Domain name: "), domain_name); + } + + if (uflg) { + uuid_t uuid; + char uuid_str[UUID_PRINTABLE_STRING_LENGTH]; + + rv = v12n_domain_uuid(uuid); + + if (rv == (size_t)(-1)) { + (void) strcpy(uuid_str, "Unknown"); + } else { + uuid_unparse(uuid, uuid_str); + } + (void) printf("%s%s\n", pflg ? "DOMAINUUID|uuid=" : + gettext("Domain UUID: "), uuid_str); + } + + if (cflg) { + char ctrl_name[V12N_NAME_MAX]; + + rv = v12n_ctrl_domain(ctrl_name, sizeof (ctrl_name)); + + if (rv == (size_t)(-1)) { + (void) strcpy(ctrl_name, "Unknown"); + } + (void) printf("%s%s\n", pflg ? "DOMAINCONTROL|name=" : + gettext("Control domain: "), ctrl_name); + } + + if (sflg) { + char serial_no[V12N_NAME_MAX]; + + rv = v12n_chassis_serialno(serial_no, sizeof (serial_no)); + + if (rv == (size_t)(-1)) { + (void) strcpy(serial_no, "Unknown"); + } + (void) printf("%s%s\n", pflg ? "DOMAINCHASSIS|serialno=" : + gettext("Chassis serial#: "), serial_no); + } + return (0); +} diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index fd5a1b90c7..b4c910a1ed 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -285,7 +285,8 @@ sparc_SUBDIRS= .WAIT \ librsc \ storage \ libpcp \ - libtsalarm + libtsalarm \ + libv12n FM_sparc_DEPLIBS= libpri @@ -518,6 +519,7 @@ sparc_HDRSUBDIRS= \ libds \ libdscp \ libpri \ + libv12n \ storage all := TARGET= all @@ -584,6 +586,7 @@ libdladm: libdevinfo libinetutil libsocket libscf librcm libnvpair \ libexacct libnsl libkstat libcurses libdll: libast libdlpi: libinetutil libdladm +libds: libsysevent libdscfg: libnsctl libunistat libsocket libnsl libdtrace: libproc libgen libctf libdtrace_jni: libuutil libdtrace @@ -648,6 +651,7 @@ libexacct/demo: libexacct libproject libsocket libnsl libtsalarm: libpcp smbsrv: libsocket libnsl libmd libxnet libpthread librt \ libshare libidmap pkcs11 libsqlite libcryptoutil +libv12n: libds libuuid libvrrpadm: libsocket libdladm libscf libvscan: libscf scsi: libnvpair diff --git a/usr/src/lib/libv12n/Makefile b/usr/src/lib/libv12n/Makefile new file mode 100644 index 0000000000..eceddb2405 --- /dev/null +++ b/usr/src/lib/libv12n/Makefile @@ -0,0 +1,58 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +include ../Makefile.lib + +HDRS = libv12n.h +HDRDIR = common + +ROOTHDRDIR = $(ROOT)/usr/include + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber lint: $(SUBDIRS) + +check: $(CHECKHDRS) + +install: all .WAIT $(SUBDIRS) + +install_h: $(ROOTHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/libv12n/Makefile.com b/usr/src/lib/libv12n/Makefile.com new file mode 100644 index 0000000000..869beaf2d5 --- /dev/null +++ b/usr/src/lib/libv12n/Makefile.com @@ -0,0 +1,54 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +LIBRARY = libv12n.a +VERS = .1 + +OBJECTS = $(MACHCOBJS) $(CMNOBJS) + +include ../../Makefile.lib + +LIBS = $(DYNLIB) $(LINTLIB) + +SRCDIR = ../common +SRCS = $(MACHCOBJS:%.o=../$(MACH)/%.c) + +CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS) +CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) + +$(LINTLIB) := SRCS = ../common/llib-lv12n + +.KEEP_STATE: + +all: $(LIBS) + +lint: $(LINTLIB) lintcheck + +pics/%.o: ../$(MACH)/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + +include ../../Makefile.targ diff --git a/usr/src/lib/libv12n/common/libv12n.h b/usr/src/lib/libv12n/common/libv12n.h new file mode 100644 index 0000000000..b854d011c9 --- /dev/null +++ b/usr/src/lib/libv12n/common/libv12n.h @@ -0,0 +1,61 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_LIBV12N_H +#define _SYS_LIBV12N_H + +#include <sys/types.h> +#include <uuid/uuid.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Max length of an v12n name/uuid/serialno */ +#define V12N_NAME_MAX 1024 + +/* Virtualization capabilities - bit mask */ +#define V12N_CAP_SUPPORTED 0x1 /* Virtualization supported */ +#define V12N_CAP_ENABLED 0x2 /* Virtualization enabled */ +#define V12N_CAP_IMPL_LDOMS 0x4 /* LDoms Implementation */ + +/* LDoms Domain role types - bit mask */ +#define V12N_ROLE_CONTROL 0x1 /* LDoms Ctrl domain (zero = Guest) */ +#define V12N_ROLE_IO 0x2 /* I/O domain */ +#define V12N_ROLE_SERVICE 0x4 /* Service domain */ +#define V12N_ROLE_ROOT 0x8 /* Root domain */ + +int v12n_capabilities(void); +int v12n_domain_roles(void); +int v12n_domain_uuid(uuid_t); +size_t v12n_domain_name(char *, size_t); +size_t v12n_ctrl_domain(char *, size_t); +size_t v12n_chassis_serialno(char *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_LIBV12N_H */ diff --git a/usr/src/lib/libv12n/common/llib-lv12n b/usr/src/lib/libv12n/common/llib-lv12n new file mode 100644 index 0000000000..904f11528d --- /dev/null +++ b/usr/src/lib/libv12n/common/llib-lv12n @@ -0,0 +1,29 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include "libv12n.h" diff --git a/usr/src/lib/libv12n/common/mapfile-vers b/usr/src/lib/libv12n/common/mapfile-vers new file mode 100644 index 0000000000..582b964fe7 --- /dev/null +++ b/usr/src/lib/libv12n/common/mapfile-vers @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +SUNW_1.1 { + global: + v12n_capabilities; + v12n_domain_roles; + v12n_domain_name; + v12n_ctrl_domain; + v12n_domain_uuid; + v12n_chassis_serialno; + local: + *; +}; diff --git a/usr/src/lib/libv12n/sparc/Makefile b/usr/src/lib/libv12n/sparc/Makefile new file mode 100644 index 0000000000..2d76647e9f --- /dev/null +++ b/usr/src/lib/libv12n/sparc/Makefile @@ -0,0 +1,53 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +MACHCOBJS = libv12n.o + +CMNOBJS= mdesc_findname.o \ + mdesc_findnodeprop.o \ + mdesc_fini.o \ + mdesc_getpropval.o \ + mdesc_getpropstr.o \ + mdesc_init_intern.o \ + mdesc_nodecount.o \ + mdesc_rootnode.o \ + mdesc_scandag.o + +OBJS += $(CMNOBJS) + +include ../Makefile.com + +C99MODE = $(C99_ENABLE) + +LDLIBS += -luuid -lc + +CPPFLAGS += -I. -I$(SRC)/lib/libds/common -I$(SRC)/cmd/ldmad + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) + +pics/%.o: $(SRC)/common/mdesc/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) diff --git a/usr/src/lib/libv12n/sparc/libv12n.c b/usr/src/lib/libv12n/sparc/libv12n.c new file mode 100644 index 0000000000..8a2dd7892a --- /dev/null +++ b/usr/src/lib/libv12n/sparc/libv12n.c @@ -0,0 +1,870 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <synch.h> +#include <thread.h> +#include <unistd.h> +#include <utility.h> +#include <sys/mdesc.h> +#include <sys/mdesc_impl.h> +#include <sys/debug.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> + +#include "ldma.h" +#include "libds.h" +#include "libv12n.h" + +/* + * sun4 support for libv12n. + * + * Non-sun4v support is minimal. The v12n_capabilities() function will + * only return 0 (not supported, not enabled, no implementation). + * + * For sun4v the support for v12n_capabilities(), v12n_domain_roles(), + * v12n_domain_name() and v12n_domain_uuid() are supported by scanning the + * MD from /dev/mdesc for specific properties. For v12n_ctrl_domain() and + * v12n_chassis_serialno(), the ldoms agent daemon (ldmad) on the control + * domain supplies the required information via the "agent-system" domain + * service. + */ + +/* libds statics */ +static void *v12n_ds_dlhdl = NULL; +static int (*v12n_ds_send_msg)(ds_hdl_t, void *, size_t) = NULL; +static int (*v12n_ds_clnt_reg)(ds_capability_t *, ds_ops_t *); +static int (*v12n_ds_unreg_svc)(char *, boolean_t); + +/* + * Defines to support the 'agent-system' domain service. + */ + +#define LDMA_SYSTEM_NVERS \ + (sizeof (v12n_ldma_system_vers) / sizeof (ds_ver_t)) +static ds_ver_t v12n_ldma_system_vers[] = { { 1, 0} }; + +static ds_capability_t v12n_ldma_cap = { + LDMA_NAME_SYSTEM, /* svc_id */ + v12n_ldma_system_vers, /* vers */ + LDMA_SYSTEM_NVERS /* nvers */ +}; + +static void v12n_ldma_register_handler(ds_hdl_t hdl, ds_cb_arg_t arg, + ds_ver_t *ver, ds_domain_hdl_t dhdl); +static void v12n_ldma_data_handler(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, + size_t buflen); + +static ds_ops_t v12n_ldma_ops = { + v12n_ldma_register_handler, /* ds_reg_cb */ + NULL, /* ds_unreg_cb */ + v12n_ldma_data_handler, /* ds_data_cb */ + NULL /* ds_cb_arg */ +}; + +/* v12n_ldma_cv_state values */ +#define V12N_LDMA_CVINVALID -1 /* invalid value for cv_state */ +#define V12N_LDMA_REGWAITING 0 /* waiting for ctrl domain reg */ +#define V12N_LDMA_REGRECEIVED 1 /* received ctrl domain reg */ +#define V12N_LDMA_MSGWAITING 2 /* waiting for message response */ +#define V12N_LDMA_MSGRECEIVED 3 /* received message response */ +#define V12N_LDMA_MSGERROR 4 /* received a bad message */ + +/* 'agent-system' data used in async registration/data message handlers */ +static ds_hdl_t v12n_ldma_ctrl_hdl = DS_INVALID_HDL; +static int v12n_ldma_msgtype; +static char *v12n_ldma_msgstr; +static mutex_t v12n_ldma_lock = DEFAULTMUTEX; +static cond_t v12n_ldma_cv = DEFAULTCV; +static int v12n_ldma_cv_state = V12N_LDMA_CVINVALID; +static mutex_t v12n_ldma_cv_lock = DEFAULTMUTEX; + +/* 'agent-system' timeout values in seconds */ +static int v12n_ldma_timeout = 15; +static int v12n_ldma_sleeptime = 1; + + +#define V12N_LDOMS_SUPPORTED (V12N_CAP_SUPPORTED | V12N_CAP_ENABLED | \ + V12N_CAP_IMPL_LDOMS) + +#define MD_DEVICE "/dev/mdesc" + +/* + * libv12n routines to support /dev/mdesc. + */ + +/* + * Wrapper for MD free: need unused size argument. + */ +/* ARGSUSED */ +static void +v12n_md_free(void *buf, size_t n) +{ + free(buf); +} + +/* + * Wrapper for MD init: read MD and invoke md_init_intern. + */ +static md_t * +v12n_md_init() +{ + md_t *mdp; + char *buf = NULL; + md_header_t mdh; + int md_size; + int fd; + + /* + * Open the Machine Description (MD) + */ + fd = open(MD_DEVICE, O_RDONLY); + if (fd == -1) { + return (NULL); + } + + if (read(fd, &mdh, sizeof (md_header_t)) != sizeof (md_header_t)) + goto errdone; + + md_size = sizeof (md_header_t) + mdh.node_blk_sz + mdh.name_blk_sz + + mdh.data_blk_sz; + + if ((buf = malloc(md_size)) == NULL) + goto errdone; + + (void) memcpy(buf, &mdh, sizeof (md_header_t)); + if (read(fd, buf + sizeof (md_header_t), + md_size - sizeof (md_header_t)) != md_size - sizeof (md_header_t)) { + goto errdone; + } + + mdp = md_init_intern((uint64_t *)((void *)buf), malloc, v12n_md_free); + + (void) close(fd); + + return (mdp); + +errdone: + (void) close(fd); + free(buf); + + return (NULL); +} + +/* + * Wrapper for md_fini. Allow NULL md ptr and free MD buffer. + */ +static void +v12n_md_fini(void *md) +{ + md_impl_t *mdp = (md_impl_t *)md; + + if (mdp) { + free(mdp->caddr); + (void) md_fini(md); + } +} + +/* + * See if LDoms domaining is enabled, returns 1 if enabled. + * Get the value of the 'domaining-enabled' property under the + * 'platform' node. Value of 1 => domaining is enabled. + */ +static int +v12n_domaining_enabled() +{ + mde_cookie_t *nodes, rootnode; + int nnodes; + uint64_t prop_val = 0; + md_t *mdp; + + if ((mdp = v12n_md_init()) == NULL) { + return (0); + } + + nnodes = md_node_count(mdp); + nodes = malloc(nnodes * sizeof (mde_cookie_t)); + if (nodes == NULL) { + v12n_md_fini(mdp); + return (0); + } + + rootnode = md_root_node(mdp); + + nnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"), + md_find_name(mdp, "fwd"), nodes); + + if (nnodes >= 1) { + (void) md_get_prop_val(mdp, nodes[0], "domaining-enabled", + &prop_val); + } + + v12n_md_fini(mdp); + free(nodes); + return (prop_val == 1); +} + +int +v12n_capabilities() +{ + struct utsname uinfo; + struct stat st; + int cap; + + /* + * Check if this is an LDoms system. When using LDoms each + * domain should have a /dev/mdesc device providing access to + * the Machine Description (MD) of the domain. If this device + * does not exist then this is not an LDoms system. + */ + if (uname(&uinfo) == -1 || strcmp(uinfo.machine, "sun4v")) { + /* + * Not sun4v -> LDoms not supported + */ + cap = 0; + } else if (stat(MD_DEVICE, &st) == 0) { + /* + * sun4v + /dev/mdesc exists -> Check if LDoms enabled + * via the 'domaining-enabled' property. + */ + cap = (V12N_CAP_SUPPORTED | V12N_CAP_IMPL_LDOMS | + (v12n_domaining_enabled() ? V12N_CAP_ENABLED : 0)); + } else if (errno == ENOENT) { + /* + * sun4v + /dev/mdesc does not exist -> LDoms supported + * but not enabled. + */ + cap = (V12N_CAP_SUPPORTED | V12N_CAP_IMPL_LDOMS); + } + + return (cap); +} + +/* + * Routines to support v12n_domain_roles. + */ +static int +v12n_scan_md_nodes(md_t *mdp, char *node_name, char *node_str_prop, + char **props) +{ + mde_cookie_t *nodes, rootnode; + int nnodes, i, j; + char *prop_str; + + nnodes = md_node_count(mdp); + nodes = malloc(nnodes * sizeof (mde_cookie_t)); + if (nodes == NULL) { + return (0); + } + + rootnode = md_root_node(mdp); + + nnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, node_name), + md_find_name(mdp, "fwd"), nodes); + + if (node_str_prop == NULL) + return (nnodes > 0); + + for (i = 0; i < nnodes; i++) { + if (md_get_prop_str(mdp, nodes[i], node_str_prop, &prop_str)) + continue; + for (j = 0; props[j] != NULL; j++) { + if (strcmp(prop_str, props[j]) == 0) { + free(nodes); + return (1); + } + } + } + free(nodes); + return (0); +} + +/* + * Check if MD has a hypervisor access point, returns 1 if true. + * Check the MD for a 'virtual-device-port' node whose 'vldc-svc-name' is + * 'hvctl'. + */ +static int +v12n_check_hv_access(md_t *mdp) +{ + static char *hvctl_str[] = { + "hvctl", + NULL + }; + + return (v12n_scan_md_nodes(mdp, "virtual-device-port", "vldc-svc-name", + hvctl_str)); +} + +/* + * Check if MD has a virtual device service (vcc, vsw, vds), returns 1 if true. + * Need to check all the MD 'virtual-device' nodes for a 'device-type' property + * of 'vcc', 'vsw' or 'vds'. + */ +static int +v12n_check_virtual_service(md_t *mdp) +{ + static char *vdevs[] = { + "vcc", + "vsw", + "vds", + NULL + }; + + return (v12n_scan_md_nodes(mdp, "virtual-device", "device-type", + vdevs)); +} + +/* + * Check if MD has an physical I/O device node, returns 1 if true. + */ +static int +v12n_check_io_service(md_t *mdp) +{ + return (v12n_scan_md_nodes(mdp, "iodevice", NULL, NULL)); +} + +/* + * Check if a MD node is root PCI device, returns 1 if true. + * Need to check all the MD 'iodevice' nodes for a 'device-type' property + * of 'pciex'. + */ +static int +v12n_check_root(md_t *mdp) +{ + static char *pciex[] = { + "pciex", + NULL + }; + + return (v12n_scan_md_nodes(mdp, "iodevice", "device-type", pciex)); +} + +/* + * Get the domain roles for the domain. + */ +int +v12n_domain_roles() +{ + md_t *mdp; + int roles = 0; + + if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) { + errno = ENOTSUP; + return (-1); + } + + if ((mdp = v12n_md_init()) == NULL) { + errno = EACCES; + return (-1); + } + + if (v12n_check_hv_access(mdp)) + roles |= V12N_ROLE_CONTROL; + + if (v12n_check_virtual_service(mdp)) + roles |= V12N_ROLE_SERVICE; + + if (v12n_check_io_service(mdp)) + roles |= V12N_ROLE_IO; + + if (v12n_check_root(mdp)) + roles |= V12N_ROLE_ROOT; + + v12n_md_fini(mdp); + + return (roles); +} + +/* + * Get domain name from MD's virtual domain service node, returns 1 on success. + * The domain name is a string property 'vlds-domain-name' under the + * 'virtual-device' device node whose name is 'virtual-domain-service'. + */ +static int +v12n_get_md_domain_name(md_t *mdp, char **vds_dnamep) +{ + mde_cookie_t *vdev_nodes, rootnode; + int list_size, nvdevs, num_nodes, i, rv; + char *vldc_name; + + num_nodes = md_node_count(mdp); + list_size = num_nodes * sizeof (mde_cookie_t); + vdev_nodes = malloc(list_size); + if (vdev_nodes == NULL) { + return (0); + } + + rootnode = md_root_node(mdp); + + nvdevs = md_scan_dag(mdp, rootnode, md_find_name(mdp, "virtual-device"), + md_find_name(mdp, "fwd"), vdev_nodes); + + rv = 0; + for (i = 0; i < nvdevs; i++) { + if (md_get_prop_str(mdp, vdev_nodes[i], "name", &vldc_name)) + continue; + if (strcmp(vldc_name, "virtual-domain-service") == 0) { + rv = (md_get_prop_str(mdp, vdev_nodes[i], + "vlds-domain-name", vds_dnamep) == 0); + break; + } + } + free(vdev_nodes); + return (rv); +} + +/* + * String copyout utility. + */ +static size_t +v12n_string_copyout(char *sout, char *sfrom, size_t count) +{ + size_t ret = strlen(sfrom) + 1; + + if (sout != NULL && count > 0) { + count = MIN(ret, count); + (void) memcpy(sout, sfrom, count); + } + return (ret); +} + +/* + * Get the domain name of this domain. + */ +size_t +v12n_domain_name(char *buf, size_t count) +{ + md_t *mdp = NULL; + char *ldmname; + int rv = -1; + + if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) { + errno = ENOTSUP; + } else if ((mdp = v12n_md_init()) == NULL) { + errno = EACCES; + } else if (!v12n_get_md_domain_name(mdp, &ldmname)) { + errno = ESRCH; + } else { + rv = v12n_string_copyout(buf, ldmname, count); + } + + v12n_md_fini(mdp); + return (rv); +} + +/* + * Get UUID string from MD, returns 1 on success. + * The UUID is a string property 'uuid' under the 'platform' node of the MD. + */ +static int +v12n_get_md_uuid_str(md_t *mdp, char **uuid_strp) +{ + mde_cookie_t *plat_nodes, rootnode; + int list_size, npnodes, num_nodes, rv; + + num_nodes = md_node_count(mdp); + list_size = num_nodes * sizeof (mde_cookie_t); + plat_nodes = malloc(list_size); + if (plat_nodes == NULL) { + return (0); + } + + rootnode = md_root_node(mdp); + + npnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"), + md_find_name(mdp, "fwd"), plat_nodes); + + if (npnodes >= 1) + rv = !md_get_prop_str(mdp, plat_nodes[0], "uuid", uuid_strp); + else + rv = 0; + + free(plat_nodes); + return (rv); +} + +/* + * Get the domain UUID. + */ +int +v12n_domain_uuid(uuid_t uuid) +{ + md_t *mdp = NULL; + char *uuid_str; + int rv = -1; + + if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) { + errno = ENOTSUP; + } else if ((mdp = v12n_md_init()) == NULL) { + errno = EACCES; + } else if (!v12n_get_md_uuid_str(mdp, &uuid_str)) { + errno = ESRCH; + } else { + rv = uuid_parse(uuid_str, uuid); + } + + v12n_md_fini(mdp); + + return (rv); +} + +/* + * Send 'agent-sytem' request message. + */ +static int +v12n_ldma_send_request() +{ + ldma_message_header_t ldmamsg; + + if (v12n_ds_send_msg == NULL || v12n_ldma_ctrl_hdl == DS_INVALID_HDL) + return (ENOENT); + + ldmamsg.msg_num = 0; + ldmamsg.msg_type = v12n_ldma_msgtype; + ldmamsg.msg_info = 0; + return (v12n_ds_send_msg(v12n_ldma_ctrl_hdl, (char *)&ldmamsg, + sizeof (ldmamsg))); +} + +/* + * 'agent-system' registration handler. + * If we get a registration from the control domain (domain 0), then send + * the requested message. Otherwise, ignore the registration. + */ +/* ARGSUSED */ +static void +v12n_ldma_register_handler(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver, + ds_domain_hdl_t dhdl) +{ + + /* got registration from control domain */ + if (dhdl == 0) { + (void) mutex_lock(&v12n_ldma_cv_lock); + if (v12n_ldma_cv_state == V12N_LDMA_REGWAITING) { + v12n_ldma_ctrl_hdl = hdl; + v12n_ldma_cv_state = V12N_LDMA_REGRECEIVED; + (void) cond_signal(&v12n_ldma_cv); + } + (void) mutex_unlock(&v12n_ldma_cv_lock); + } +} + +/* + * 'agent-system' data handler. + */ +/* ARGSUSED */ +static void +v12n_ldma_data_handler(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, + size_t buflen) +{ + char *data; + ldma_message_header_t *ldmp; + int n; + int cv_state = V12N_LDMA_MSGERROR; + + /* + * Ignore any message not from the control domain. + */ + if (v12n_ldma_ctrl_hdl != hdl) + return; + + /* + * Ignore any unexpected message. + */ + if (buflen < LDMA_MESSAGE_HEADER_SIZE) + return; + + /* + * Ignore message with unexpected msgnum. + */ + ldmp = (ldma_message_header_t *)buf; + if (ldmp->msg_num != 0) + return; + + switch (ldmp->msg_type) { + + case LDMA_MSG_RESULT: + if (ldmp->msg_info == 0 || + ldmp->msg_info > LDMA_MESSAGE_DLEN(buflen)) { + cv_state = V12N_LDMA_MSGERROR; + break; + } + data = LDMA_HDR2DATA(buf); + + /* ensure that data ends with a '\0' */ + data[ldmp->msg_info - 1] = '\0'; + switch (v12n_ldma_msgtype) { + + case LDMA_MSGSYS_GET_SYSINFO: + /* + * Control domain nodename is second string in the + * message. Make sure there is enough data in the msg + * to have a second string. + */ + n = strlen(data); + if (LDMA_MESSAGE_DLEN(buflen) <= n + 3) { + cv_state = V12N_LDMA_MSGERROR; + break; + } + data += n + 1; + if ((v12n_ldma_msgstr = strdup(data)) == NULL) + cv_state = V12N_LDMA_MSGERROR; + else + cv_state = V12N_LDMA_MSGRECEIVED; + break; + + case LDMA_MSGSYS_GET_CHASSISNO: + if ((v12n_ldma_msgstr = strdup(data)) == NULL) + cv_state = V12N_LDMA_MSGERROR; + else + cv_state = V12N_LDMA_MSGRECEIVED; + break; + + default: + /* v12n_ldma_msgtype must be valid */ + ASSERT(0); + } + break; + + case LDMA_MSG_ERROR: + cv_state = V12N_LDMA_MSGERROR; + break; + + default: + /* unexpected message, ignored */ + return; + } + + (void) mutex_lock(&v12n_ldma_cv_lock); + v12n_ldma_cv_state = cv_state; + (void) cond_signal(&v12n_ldma_cv); + (void) mutex_unlock(&v12n_ldma_cv_lock); +} + + +/* + * libds doesn't exist on non-sun4v, dynamically load it and get the + * function pointers to the needed lib functions. + */ +static int +v12n_libds_init(void) +{ + if (v12n_ds_dlhdl != NULL) { + if (v12n_ds_clnt_reg == NULL || v12n_ds_send_msg == NULL || + v12n_ds_unreg_svc == NULL) + return (ENOENT); + return (0); + } + + if ((v12n_ds_dlhdl = dlopen("libds.so.1", + RTLD_NOW | RTLD_GLOBAL)) == NULL) + return (ENOENT); + + if ((v12n_ds_clnt_reg = (int (*)(ds_capability_t *, ds_ops_t *)) + dlsym(v12n_ds_dlhdl, "ds_clnt_reg")) == NULL) + return (ENOENT); + + if ((v12n_ds_send_msg = (int (*)(ds_hdl_t, void *, size_t)) + dlsym(v12n_ds_dlhdl, "ds_send_msg")) == NULL) + return (ENOENT); + + if ((v12n_ds_unreg_svc = (int (*)(char *, boolean_t)) + dlsym(v12n_ds_dlhdl, "ds_unreg_svc")) == NULL) + return (ENOENT); + + return (0); +} + +/* + * Initiate and wait for an ldmad 'agent-system' domain service. + * Dynamically load libds, register the client 'agent-system' service + * and wait for a specified amount of time for the 'agent-system' + * service on the control domain to respond to the request. + */ +static int +v12n_get_ldma_system_msg(int msgtype, char **strp) +{ + int tout; + int err = 0; + timestruc_t timeout; + + /* + * Ensure that there's only one thread trying to do a + * 'agent-system' client registration/message at a time. + */ + (void) mutex_lock(&v12n_ldma_lock); + if ((err = v12n_libds_init()) != 0) + goto done; + + v12n_ldma_msgtype = msgtype; + v12n_ldma_msgstr = NULL; + + /* initialize v12n_ldma_cv_state variable before registering service */ + (void) mutex_lock(&v12n_ldma_cv_lock); + v12n_ldma_cv_state = V12N_LDMA_REGWAITING; + (void) mutex_unlock(&v12n_ldma_cv_lock); + + /* + * Other instances may be trying to load the "agent-system" service. + * If a collision happens (EBUSY error), wait and try again. + */ + for (tout = 0; tout < v12n_ldma_timeout; tout += v12n_ldma_sleeptime) { + if ((err = v12n_ds_clnt_reg(&v12n_ldma_cap, + &v12n_ldma_ops)) == 0) + break; + if (err != EALREADY) { + goto done; + } + (void) sleep(v12n_ldma_sleeptime); + } + + if (tout >= v12n_ldma_timeout) { + err = EBUSY; + goto done; + } + + /* + * Wait for control domain registration. + */ + timeout.tv_sec = v12n_ldma_timeout; + timeout.tv_nsec = 0; + + (void) mutex_lock(&v12n_ldma_cv_lock); + while (v12n_ldma_cv_state == V12N_LDMA_REGWAITING) { + if ((err = cond_reltimedwait(&v12n_ldma_cv, + &v12n_ldma_cv_lock, &timeout)) != EINTR) + break; + } + + /* + * Check for timeout or an error. + */ + if (v12n_ldma_cv_state != V12N_LDMA_REGRECEIVED) { + if (err == 0) + err = EPROTO; + (void) mutex_unlock(&v12n_ldma_cv_lock); + goto done; + } + + /* + * Received a registration request, send the request message. + */ + v12n_ldma_cv_state = V12N_LDMA_MSGWAITING; + if ((err = v12n_ldma_send_request()) != 0) { + (void) mutex_unlock(&v12n_ldma_cv_lock); + goto done; + } + + while (v12n_ldma_cv_state == V12N_LDMA_MSGWAITING) { + if ((err = cond_reltimedwait(&v12n_ldma_cv, + &v12n_ldma_cv_lock, &timeout)) != EINTR) + break; + } + + if (v12n_ldma_cv_state != V12N_LDMA_MSGRECEIVED) { + if (err == 0) + err = EPROTO; + (void) mutex_unlock(&v12n_ldma_cv_lock); + goto done; + } + + v12n_ldma_cv_state = V12N_LDMA_CVINVALID; + (void) mutex_unlock(&v12n_ldma_cv_lock); + + /* + * If v12n_ldma_msgstr is set, a valid data response was seen. + */ + if (v12n_ldma_msgstr == NULL) + err = ENODATA; + else { + if (*v12n_ldma_msgstr == '\0' || + (*strp = strdup(v12n_ldma_msgstr)) == NULL) + err = ENODATA; + free(v12n_ldma_msgstr); + v12n_ldma_msgstr = NULL; + } + +done: + v12n_ds_unreg_svc(LDMA_NAME_SYSTEM, B_TRUE); + v12n_ldma_msgtype = -1; + v12n_ldma_ctrl_hdl = DS_INVALID_HDL; + (void) mutex_unlock(&v12n_ldma_lock); + + return (err); +} + +/* + * Get the nodename of the control domain. Returns the equivalent + * of 'uname -n' on the control domain. + * This is obtained via the 'agent-system' domain service provided + * by ldmad. + */ +size_t +v12n_ctrl_domain(char *buf, size_t count) +{ + char *str; + int err; + size_t rv = (size_t)(-1); + + if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) { + errno = ENOTSUP; + } else if ((err = v12n_get_ldma_system_msg(LDMA_MSGSYS_GET_SYSINFO, + &str)) != 0) { + errno = err; + } else { + rv = v12n_string_copyout(buf, str, count); + } + return (rv); +} + +/* + * Get the Chassis serial number from the Control Domain. + * This is obtained via the 'agent-system' domain service provided + * by ldmad. + */ +size_t +v12n_chassis_serialno(char *buf, size_t count) +{ + char *str; + int err; + size_t rv = (size_t)(-1); + + if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) { + errno = ENOTSUP; + } else if ((err = v12n_get_ldma_system_msg(LDMA_MSGSYS_GET_CHASSISNO, + &str)) != 0) { + errno = err; + } else { + rv = v12n_string_copyout(buf, str, count); + } + return (rv); +} diff --git a/usr/src/lib/libv12n/sparcv9/Makefile b/usr/src/lib/libv12n/sparcv9/Makefile new file mode 100644 index 0000000000..a03fd47ade --- /dev/null +++ b/usr/src/lib/libv12n/sparcv9/Makefile @@ -0,0 +1,54 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +MACHCOBJS = libv12n.o + +CMNOBJS= mdesc_findname.o \ + mdesc_findnodeprop.o \ + mdesc_fini.o \ + mdesc_getpropval.o \ + mdesc_getpropstr.o \ + mdesc_init_intern.o \ + mdesc_nodecount.o \ + mdesc_rootnode.o \ + mdesc_scandag.o + +OBJS += $(CMNOBJS) + +include ../Makefile.com +include ../../Makefile.lib.64 + +C99MODE = $(C99_ENABLE) + +LDLIBS += -luuid -lc + +CPPFLAGS += -I. -I$(SRC)/lib/libds/common -I$(SRC)/cmd/ldmad + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) + +pics/%.o: $(SRC)/common/mdesc/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) diff --git a/usr/src/pkgdefs/SUNWarc/prototype_sparc b/usr/src/pkgdefs/SUNWarc/prototype_sparc index 5c5c2b7ae3..4af62113eb 100644 --- a/usr/src/pkgdefs/SUNWarc/prototype_sparc +++ b/usr/src/pkgdefs/SUNWarc/prototype_sparc @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -165,3 +165,6 @@ f none usr/lib/sparcv9/llib-lpasswdutil.ln 644 root bin d none usr/lib/scsi/sparcv9 755 root bin f none usr/lib/scsi/sparcv9/llib-lscsi.ln 644 root bin f none usr/lib/scsi/sparcv9/llib-lses.ln 644 root bin +f none usr/lib/llib-lv12n 644 root bin +f none usr/lib/llib-lv12n.ln 644 root bin +f none usr/lib/sparcv9/llib-lv12n.ln 644 root bin diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_sparc b/usr/src/pkgdefs/SUNWcsl/prototype_sparc index 1ad076bce2..02ba80e96e 100644 --- a/usr/src/pkgdefs/SUNWcsl/prototype_sparc +++ b/usr/src/pkgdefs/SUNWcsl/prototype_sparc @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This required package information file contains a list of package contents. @@ -88,6 +88,8 @@ d none usr/lib/scsi/plugins/ses/framework/sparcv9 755 root bin f none usr/lib/scsi/plugins/ses/framework/sparcv9/libses.so 755 root bin f none usr/lib/scsi/plugins/ses/framework/sparcv9/ses2.so 755 root bin d none usr/lib/scsi/plugins/ses/vendor/sparcv9 755 root bin +f none usr/lib/libv12n.so.1 755 root bin +s none usr/lib/libv12n.so=libv12n.so.1 d none usr/lib/security/sparcv9 755 root bin s none usr/lib/security/64=sparcv9 f none usr/lib/security/sparcv9/crypt_bsdmd5.so.1 755 root bin @@ -339,6 +341,8 @@ s none usr/lib/sparcv9/libtsol.so=../../../lib/sparcv9/libtsol.so.2 s none usr/lib/sparcv9/libumem.so=../../../lib/sparcv9/libumem.so.1 s none usr/lib/sparcv9/libumem.so.1=../../../lib/sparcv9/libumem.so.1 s none usr/lib/sparcv9/libuutil.so.1=../../../lib/sparcv9/libuutil.so.1 +f none usr/lib/sparcv9/libv12n.so.1 755 root bin +s none usr/lib/sparcv9/libv12n.so=libv12n.so.1 f none usr/lib/sparcv9/libvolmgt.so.1 755 root bin s none usr/lib/sparcv9/libvolmgt.so=libvolmgt.so.1 s none usr/lib/sparcv9/libw.so=../../../lib/sparcv9/libw.so.1 diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_sparc b/usr/src/pkgdefs/SUNWcsu/prototype_sparc index 2c4adaf592..79b3ef26df 100644 --- a/usr/src/pkgdefs/SUNWcsu/prototype_sparc +++ b/usr/src/pkgdefs/SUNWcsu/prototype_sparc @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This required package information file contains a list of package contents. @@ -117,6 +117,7 @@ f none usr/lib/sparcv9/libshare.so.1 755 root bin d none usr/lib/fs/nfs 755 root sys d none usr/lib/fs/nfs/sparcv9 755 root sys l none usr/sbin/prtdiag=../../usr/lib/platexec +f none usr/sbin/virtinfo 555 root sys d none usr/sbin/sparcv9 755 root bin f none usr/sbin/sparcv9/add_drv 555 root sys f none usr/sbin/sparcv9/modinfo 555 root sys diff --git a/usr/src/pkgdefs/SUNWhea/prototype_sparc b/usr/src/pkgdefs/SUNWhea/prototype_sparc index 3b040fe240..d1f85deb91 100644 --- a/usr/src/pkgdefs/SUNWhea/prototype_sparc +++ b/usr/src/pkgdefs/SUNWhea/prototype_sparc @@ -48,6 +48,7 @@ # SUNWhea # f none usr/include/asm/flush.h 644 root bin +f none usr/include/libv12n.h 644 root bin f none usr/include/rpc/ib.h 644 root bin f none usr/include/sys/cmpregs.h 644 root bin f none usr/include/sys/dkmpio.h 644 root bin diff --git a/usr/src/uts/sun4v/sys/ldoms.h b/usr/src/uts/sun4v/sys/ldoms.h index 09c28f828a..fe074c76e7 100644 --- a/usr/src/uts/sun4v/sys/ldoms.h +++ b/usr/src/uts/sun4v/sys/ldoms.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,7 +31,7 @@ extern "C" { #endif -#include <sys/param.h> /* for MAXHOSTNAMELEN */ +#include <sys/param.h> /* * Global LDoms definitions. @@ -53,7 +53,7 @@ extern "C" { #define LDOMS_MAX_DOMAINS 512 /* maximum number of characters in the logical domain name */ -#define LDOMS_MAX_NAME_LEN MAXHOSTNAMELEN +#define LDOMS_MAX_NAME_LEN MAXNAMELEN /* * Global flags that indicate what domaining features are |
