diff options
| author | Mike Christensen <Michael.Christensen@Sun.COM> | 2008-09-25 17:36:37 -0700 |
|---|---|---|
| committer | Mike Christensen <Michael.Christensen@Sun.COM> | 2008-09-25 17:36:37 -0700 |
| commit | 30588217a56ff2c9137248fb2e5065c4f0101459 (patch) | |
| tree | 08b89b75fb363ad2fb24e241c8c3c64fdce586e1 /usr/src/lib/libds | |
| parent | 88294e09b5c27cbb12b6735e2fb247a86b76666d (diff) | |
| download | illumos-joyent-30588217a56ff2c9137248fb2e5065c4f0101459.tar.gz | |
PSARC 2008/568 Logical Domain's Domain Services
6689118 LDoms Domain Services (DS) extensions for user program API
Diffstat (limited to 'usr/src/lib/libds')
| -rw-r--r-- | usr/src/lib/libds/Makefile | 58 | ||||
| -rw-r--r-- | usr/src/lib/libds/Makefile.com | 64 | ||||
| -rw-r--r-- | usr/src/lib/libds/common/libds.c | 710 | ||||
| -rw-r--r-- | usr/src/lib/libds/common/libds.h | 95 | ||||
| -rw-r--r-- | usr/src/lib/libds/common/llib-lds | 29 | ||||
| -rw-r--r-- | usr/src/lib/libds/common/mapfile-vers | 44 | ||||
| -rw-r--r-- | usr/src/lib/libds/sparc/Makefile | 29 | ||||
| -rw-r--r-- | usr/src/lib/libds/sparcv9/Makefile | 30 |
8 files changed, 1059 insertions, 0 deletions
diff --git a/usr/src/lib/libds/Makefile b/usr/src/lib/libds/Makefile new file mode 100644 index 0000000000..059b9076c4 --- /dev/null +++ b/usr/src/lib/libds/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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +include ../Makefile.lib + +HDRS = libds.h +HDRDIR = common + +ROOTHDRDIR = $(ROOT)/usr/platform/sun4v/include/sys + +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/libds/Makefile.com b/usr/src/lib/libds/Makefile.com new file mode 100644 index 0000000000..9168e65ed2 --- /dev/null +++ b/usr/src/lib/libds/Makefile.com @@ -0,0 +1,64 @@ +# +# 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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +LIBRARY = libds.a +VERS = .1 + +LIBSRCS = libds.c +OBJECTS = $(LIBSRCS:%.c=%.o) + +include ../../Makefile.lib + +LIBS = $(DYNLIB) $(LINTLIB) + +SRCDIR = ../common +SRCS = $(LIBSRCS:%.c=$(SRCDIR)/%.c) + +CPPFLAGS += -I. -I$(SRC)/uts/sun4v +CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS) +CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) + +LDLIBS += -lsysevent -lnvpair -lc + +LINTFLAGS = -msux +LINTFLAGS64 = -msux -Xarch=$(MACH64:sparcv9=v9) + +$(LINTLIB) := SRCS = $(LINTSRC:%=$(SRCDIR)/%) +$(LINTLIB) := LINTFLAGS = -nsvx -I$(ROOT)/usr/platform/sun4v/include +$(LINTLIB) := LINTFLAGS64 = -nsvx -Xarch=$(MACH64:sparcv9=v9) \ + -I$(ROOT)/usr/platform/sun4v/include + +.KEEP_STATE: + +all: $(LIBS) + +lint: $(LINTLIB) lintcheck + +pics/%.o: $(SRCDIR)/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + +include ../../Makefile.targ diff --git a/usr/src/lib/libds/common/libds.c b/usr/src/lib/libds/common/libds.c new file mode 100644 index 0000000000..bacdd14f5a --- /dev/null +++ b/usr/src/lib/libds/common/libds.c @@ -0,0 +1,710 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <strings.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/sysevent.h> +#include <libsysevent.h> +#include <sys/vlds.h> +#include "libds.h" + +#define PTRTOUINT64(ptr) ((uint64_t)((uintptr_t)(ptr))) +static char vlds_device[] = + "/devices/virtual-devices@100/channel-devices@200/" + "virtual-domain-service@0:vlds"; + +typedef struct dslibentry { + ds_hdl_t dsl_hdl; + uint32_t dsl_flags; + char *dsl_service; + ds_ops_t dsl_ops; +} dslibentry_t; + +#define MIN_DSLIB_ENTRIES 64 +static dslibentry_t *dslibtab; +static int ndslib; + +/* + * Lock to protect the dslibtab table. We only need to protect this + * table for those functions which actually look at or modify the table: + * service registration (ds_svc_reg/ds_clnt_reg), service unregistration + * (ds_hdl_unreg) or during callbacks (ds_recv) + */ +static mutex_t dslib_lock; + +static int ds_fd = -1; + +static char *ds_sid_name = "vlds"; + +static evchan_t *ds_evchan; + +/* + * Static functions internal to dslib. + */ +static dslibentry_t *ds_hdl_to_dslibentry(ds_hdl_t hdl); +static dslibentry_t *ds_lookup_dslibentry(char *service, boolean_t is_client); +static dslibentry_t *ds_register_dslibentry(ds_hdl_t hdl, char *service, + boolean_t is_client); +static void ds_free_dslibentry(dslibentry_t *dsp, int force_unreg); +static int ds_recv(sysevent_t *sep, void *arg); +static void ds_string_arg(vlds_string_t *dsp, char *str); +static int ds_register(ds_capability_t *cap, ds_ops_t *ops, uint_t flags); + +static dslibentry_t * +ds_hdl_to_dslibentry(ds_hdl_t hdl) +{ + int i; + dslibentry_t *dsp; + + for (i = 0, dsp = dslibtab; i < ndslib; i++, dsp++) { + if (hdl == dsp->dsl_hdl) + return (dsp); + } + return (NULL); +} + +static dslibentry_t * +ds_new_dslibentry(void) +{ + int newndslib; + dslibentry_t *dsp; + + if ((dsp = ds_hdl_to_dslibentry(NULL)) != NULL) + return (dsp); + + /* double the size */ + newndslib = ndslib << 1; + if ((dslibtab = realloc(dslibtab, newndslib * sizeof (dslibentry_t))) + == NULL) + return (NULL); + dsp = &dslibtab[ndslib]; + (void) memset(dsp, 0, (newndslib - ndslib) * sizeof (dslibentry_t)); + ndslib = newndslib; + return (dsp); +} + +static dslibentry_t * +ds_lookup_dslibentry(char *service, boolean_t is_client) +{ + int i; + dslibentry_t *dsp; + uint_t is_client_flag = is_client ? VLDS_REG_CLIENT : 0; + + for (i = 0, dsp = dslibtab; i < ndslib; i++, dsp++) { + if (dsp->dsl_hdl != NULL && + strcmp(dsp->dsl_service, service) == 0 && + (dsp->dsl_flags & VLDS_REG_CLIENT) == is_client_flag) { + return (dsp); + } + } + return (NULL); +} + +static dslibentry_t * +ds_register_dslibentry(ds_hdl_t hdl, char *service, boolean_t is_client) +{ + dslibentry_t *dsp, *orig_dsp; + uint_t nhdls; + + if ((dsp = ds_hdl_to_dslibentry(hdl)) != NULL) + return (dsp); + + if ((orig_dsp = ds_lookup_dslibentry(service, is_client)) == NULL) { + return (NULL); + } + + /* + * Find out if we have 1 or 2 or more handles. Having one implies + * that we can reuse the current one handle for this service. + * Having two or more implies we need to allocate a new handle. + */ + if (ds_hdl_lookup(service, is_client, NULL, 2, &nhdls) != 0) + return (NULL); + + if (nhdls == 1) { + /* reuse the original structure entry */ + dsp = orig_dsp; + } else if (nhdls == 2) { + /* allocate a new structure entry */ + if ((dsp = ds_new_dslibentry()) == NULL) + return (NULL); + *dsp = *orig_dsp; + dsp->dsl_service = strdup(orig_dsp->dsl_service); + } else { + /* can't happen... */ + return (NULL); + } + dsp->dsl_hdl = hdl; + return (dsp); +} + +/* + * Want to leave an entry in the dslib table even though all the + * handles may have been unregistered for it. + */ +static void +ds_free_dslibentry(dslibentry_t *dsp, int force_unreg) +{ + uint_t nhdls; + + /* + * Find out if we have 1 or 2 or more handles. Having one implies + * that we want to leave the entry alone unless this is a ds_unreg_hdl + * (force_unreg is true). + */ + if (ds_hdl_lookup(dsp->dsl_service, + (dsp->dsl_flags & VLDS_REG_CLIENT) != 0, NULL, 2, &nhdls) != 0) { + /* should never happen */ + return; + } + + if ((nhdls == 1 && force_unreg) || nhdls == 2) { + dsp->dsl_hdl = NULL; + if (dsp->dsl_service) { + free(dsp->dsl_service); + } + (void) memset(dsp, 0, sizeof (dslibentry_t)); + } +} + +/*ARGSUSED*/ +static int +ds_recv(sysevent_t *sep, void *arg) +{ + nvlist_t *nvl; + uint64_t hdl; + ds_ver_t ver; + ds_domain_hdl_t dhdl; + uchar_t *bufp; + boolean_t is_client; + uint_t buflen; + char *subclass; + char *servicep; + dslibentry_t *dsp; + ds_cb_arg_t cb_arg; + + subclass = sysevent_get_subclass_name(sep); + if (sysevent_get_attr_list(sep, &nvl) != 0) { + return (0); + } + + if (nvlist_lookup_uint64(nvl, VLDS_HDL, &hdl) == 0) { + if (strcmp(subclass, ESC_VLDS_REGISTER) == 0) { + void (*reg_cb)(ds_hdl_t, ds_cb_arg_t, ds_ver_t *, + ds_domain_hdl_t) = NULL; + + if (nvlist_lookup_string(nvl, VLDS_SERVICE_ID, + &servicep) == 0 && + nvlist_lookup_boolean_value(nvl, VLDS_ISCLIENT, + &is_client) == 0) { + (void) mutex_lock(&dslib_lock); + if ((dsp = ds_register_dslibentry(hdl, + servicep, is_client)) != NULL) { + reg_cb = dsp->dsl_ops.ds_reg_cb; + cb_arg = dsp->dsl_ops.cb_arg; + } + (void) mutex_unlock(&dslib_lock); + if (reg_cb != NULL && + nvlist_lookup_uint64(nvl, VLDS_DOMAIN_HDL, + &dhdl) == 0 && + nvlist_lookup_uint16(nvl, VLDS_VER_MAJOR, + &ver.major) == 0 && + nvlist_lookup_uint16(nvl, VLDS_VER_MINOR, + &ver.minor) == 0) { + (reg_cb)((ds_hdl_t)hdl, cb_arg, &ver, + dhdl); + } + } + } else if (strcmp(subclass, ESC_VLDS_UNREGISTER) == 0) { + void (*unreg_cb)(ds_hdl_t, ds_cb_arg_t) = NULL; + + (void) mutex_lock(&dslib_lock); + if ((dsp = ds_hdl_to_dslibentry(hdl)) != NULL) { + unreg_cb = dsp->dsl_ops.ds_unreg_cb; + cb_arg = dsp->dsl_ops.cb_arg; + ds_free_dslibentry(dsp, 0); + } + (void) mutex_unlock(&dslib_lock); + if (unreg_cb != NULL) { + (unreg_cb)((ds_hdl_t)hdl, cb_arg); + } + } else if (strcmp(subclass, ESC_VLDS_DATA) == 0) { + void (*data_cb)(ds_hdl_t, ds_cb_arg_t, void *, + size_t) = NULL; + + (void) mutex_lock(&dslib_lock); + if ((dsp = ds_hdl_to_dslibentry(hdl)) != NULL) { + data_cb = dsp->dsl_ops.ds_data_cb; + cb_arg = dsp->dsl_ops.cb_arg; + } + (void) mutex_unlock(&dslib_lock); + if (data_cb != NULL && + nvlist_lookup_byte_array(nvl, VLDS_DATA, &bufp, + &buflen) == 0) { + (data_cb)((ds_hdl_t)hdl, cb_arg, bufp, buflen); + } + } + } + nvlist_free(nvl); + return (0); +} + +static void +ds_string_arg(vlds_string_t *dsp, char *str) +{ + if (str == NULL) { + dsp->vlds_strp = NULL; + dsp->vlds_strlen = 0; + } else { + dsp->vlds_strp = PTRTOUINT64(str); + dsp->vlds_strlen = strlen(str) + 1; + } +} + +static int +ds_init_sysev(void) +{ + char evchan_name[MAX_CHNAME_LEN]; + + (void) sprintf(evchan_name, VLDS_SYSEV_CHAN_FMT, (int)getpid()); + if (sysevent_evc_bind(evchan_name, &ds_evchan, 0) != 0) { + return (errno); + } + if (sysevent_evc_subscribe(ds_evchan, ds_sid_name, EC_VLDS, + ds_recv, NULL, 0) != 0) { + sysevent_evc_unbind(ds_evchan); + ds_evchan = NULL; + return (errno); + } + return (0); +} + +int +ds_init(void) +{ + if (ds_fd >= 0) + return (0); + + if ((ds_fd = open(vlds_device, 0)) < 0) + return (errno); + + if (dslibtab == NULL) { + if ((dslibtab = malloc(sizeof (dslibentry_t) * ndslib)) == NULL) + return (errno = ENOMEM); + ndslib = MIN_DSLIB_ENTRIES; + (void) memset(dslibtab, 0, sizeof (dslibentry_t) * ndslib); + } + + (void) mutex_init(&dslib_lock, USYNC_THREAD, NULL); + return (0); +} + +static int +ds_register(ds_capability_t *cap, ds_ops_t *ops, uint_t flags) +{ + dslibentry_t *dsp; + vlds_svc_reg_arg_t vlds_arg; + vlds_cap_t vlds_cap; + vlds_ver_t vlds_vers[VLDS_MAX_VERS]; + uint64_t hdl_arg; + ds_hdl_t hdl; + uint_t nhdls; + int i; + + if (cap == NULL || ops == NULL || cap->svc_id == NULL || + cap->vers == NULL || (flags & (~VLDS_REG_CLIENT)) != 0) { + return (errno = EINVAL); + } + + if (cap->nvers > VLDS_MAX_VERS) { + return (errno = EINVAL); + } + + if (ds_fd < 0 && (errno = ds_init()) != 0) { + return (errno); + } + + if (ds_hdl_lookup(cap->svc_id, (flags & VLDS_REG_CLIENT), NULL, 1, + &nhdls) == 0 && nhdls == 1) { + return (errno = EALREADY); + } + + (void) mutex_lock(&dslib_lock); + if ((dsp = ds_new_dslibentry()) == NULL) { + (void) mutex_unlock(&dslib_lock); + return (errno = ENOMEM); + } + + /* Setup device driver capability structure. */ + + /* service string */ + ds_string_arg(&vlds_cap.vlds_service, cap->svc_id); + + /* version array */ + for (i = 0; i < cap->nvers; i++) { + vlds_vers[i].vlds_major = cap->vers[i].major; + vlds_vers[i].vlds_minor = cap->vers[i].minor; + } + vlds_cap.vlds_versp = PTRTOUINT64(vlds_vers); + vlds_cap.vlds_nver = cap->nvers; + + /* + * Format args for VLDS_SVC_REG ioctl. + */ + + vlds_arg.vlds_capp = PTRTOUINT64(&vlds_cap); + + /* op flags */ + if (ops->ds_reg_cb != NULL) + flags |= VLDS_REGCB_VALID; + if (ops->ds_unreg_cb != NULL) + flags |= VLDS_UNREGCB_VALID; + if (ops->ds_data_cb != NULL) + flags |= VLDS_DATACB_VALID; + vlds_arg.vlds_reg_flags = flags; + + /* returned handle */ + vlds_arg.vlds_hdlp = PTRTOUINT64(&hdl_arg); + + if (ioctl(ds_fd, VLDS_SVC_REG, &vlds_arg) < 0) { + (void) mutex_unlock(&dslib_lock); + return (errno); + } + + /* + * Setup user callback sysevent channel. + */ + if ((flags & VLDS_ANYCB_VALID) != 0 && ds_evchan == NULL && + ds_init_sysev() != 0) { + (void) mutex_unlock(&dslib_lock); + (void) ioctl(ds_fd, VLDS_UNREG_HDL, &vlds_arg); + return (errno); + } + + hdl = hdl_arg; + + /* + * Set entry values in dslibtab. + */ + dsp->dsl_hdl = hdl; + dsp->dsl_flags = flags; + dsp->dsl_service = strdup(cap->svc_id); + dsp->dsl_ops = *ops; + (void) mutex_unlock(&dslib_lock); + return (0); +} + +/* + * Registers a service provider. Kicks off the handshake with other + * domain(s) to announce servce. Callback events are as described above. + */ +int +ds_svc_reg(ds_capability_t *cap, ds_ops_t *ops) +{ + return (ds_register(cap, ops, 0)); +} + +/* + * Registers interest in a service from a specific domain. When that + * service is registered, the register callback is invoked. When that + * service is unregistered, the unregister callback is invoked. When + * data is received, the receive data callback is invoked. + */ +int +ds_clnt_reg(ds_capability_t *cap, ds_ops_t *ops) +{ + return (ds_register(cap, ops, VLDS_REG_CLIENT)); +} + +/* + * Given a service name and type, returns the existing handle(s), if + * one or more exist. This could be used to poll for the connection being + * registered or unregistered, rather than using the register/unregister + * callbacks. + */ +int +ds_hdl_lookup(char *service, boolean_t is_client, ds_hdl_t *hdlsp, + uint_t maxhdls, uint_t *nhdlsp) +{ + vlds_hdl_lookup_arg_t vlds_arg; + uint64_t nhdls_arg; + + errno = 0; + if (ds_fd < 0) { + return (errno = EBADF); + } + + if (service == NULL) { + return (errno = EINVAL); + } + + ds_string_arg(&vlds_arg.vlds_service, service); + vlds_arg.vlds_isclient = is_client ? VLDS_REG_CLIENT : 0; + vlds_arg.vlds_hdlsp = PTRTOUINT64(hdlsp); + vlds_arg.vlds_maxhdls = maxhdls; + vlds_arg.vlds_nhdlsp = PTRTOUINT64(&nhdls_arg); + + if (ioctl(ds_fd, VLDS_HDL_LOOKUP, &vlds_arg) < 0) { + return (errno); + } + + *nhdlsp = nhdls_arg; + return (0); +} + +/* + * Given a handle, return its associated domain. + */ +int +ds_domain_lookup(ds_hdl_t hdl, ds_domain_hdl_t *dhdlp) +{ + vlds_dmn_lookup_arg_t vlds_arg; + uint64_t dhdl_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + vlds_arg.vlds_hdl = hdl; + vlds_arg.vlds_dhdlp = PTRTOUINT64(&dhdl_arg); + + if (ioctl(ds_fd, VLDS_DMN_LOOKUP, &vlds_arg) < 0) { + return (errno); + } + + if (dhdlp) { + *dhdlp = dhdl_arg; + } + + return (0); +} + +/* + * Unregisters either a service or an interest in that service + * indicated by the supplied handle. + */ +int +ds_unreg_hdl(ds_hdl_t hdl) +{ + dslibentry_t *dsp; + vlds_unreg_hdl_arg_t vlds_arg; + + (void) mutex_lock(&dslib_lock); + if ((dsp = ds_hdl_to_dslibentry(hdl)) != NULL) { + ds_free_dslibentry(dsp, 1); + } + (void) mutex_unlock(&dslib_lock); + + if (ds_fd >= 0) { + vlds_arg.vlds_hdl = hdl; + (void) ioctl(ds_fd, VLDS_UNREG_HDL, &vlds_arg); + } + + return (0); +} + +/* + * Send data to the appropriate service provider or client + * indicated by the provided handle. The sender will block + * until the message has been sent. There is no guarantee + * that multiple calls to ds_send_msg by the same thread + * will result in the data showing up at the receiver in + * the same order as sent. If multiple messages are required, + * it will be up to the sender and receiver to implement a + * protocol. + */ +int +ds_send_msg(ds_hdl_t hdl, void *buf, size_t buflen) +{ + vlds_send_msg_arg_t vlds_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + vlds_arg.vlds_hdl = hdl; + vlds_arg.vlds_bufp = PTRTOUINT64(buf); + vlds_arg.vlds_buflen = buflen; + + if (ioctl(ds_fd, VLDS_SEND_MSG, &vlds_arg) < 0) { + return (errno); + } + + return (0); +} + +/* + * Receive data from the appropriate service provider or client + * indicated by the provided handle. The sender will block + * until a message has been received. + */ +int +ds_recv_msg(ds_hdl_t hdl, void *buf, size_t buflen, size_t *msglen) +{ + vlds_recv_msg_arg_t vlds_arg; + uint64_t msglen_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + vlds_arg.vlds_hdl = hdl; + vlds_arg.vlds_bufp = PTRTOUINT64(buf); + vlds_arg.vlds_buflen = buflen; + vlds_arg.vlds_msglenp = PTRTOUINT64(&msglen_arg); + + if (ioctl(ds_fd, VLDS_RECV_MSG, &vlds_arg) < 0) { + if (errno == EFBIG && msglen) { + *msglen = msglen_arg; + } + return (errno); + } + + if (msglen) { + *msglen = msglen_arg; + } + + return (0); +} + +int +ds_isready(ds_hdl_t hdl, boolean_t *is_ready) +{ + vlds_hdl_isready_arg_t vlds_arg; + uint64_t is_ready_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + vlds_arg.vlds_hdl = hdl; + vlds_arg.vlds_isreadyp = PTRTOUINT64(&is_ready_arg); + + if (ioctl(ds_fd, VLDS_HDL_ISREADY, &vlds_arg) < 0) { + return (errno); + } + + *is_ready = (is_ready_arg != 0); + return (0); +} + +/* + * Given a domain name, return its associated domain handle. + */ +int +ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp) +{ + vlds_dom_nam2hdl_arg_t vlds_arg; + uint64_t dhdl_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + ds_string_arg(&vlds_arg.vlds_domain_name, domain_name); + vlds_arg.vlds_dhdlp = PTRTOUINT64(&dhdl_arg); + + if (ioctl(ds_fd, VLDS_DOM_NAM2HDL, &vlds_arg) < 0) { + return (errno); + } + + if (dhdlp) { + *dhdlp = dhdl_arg; + } + + return (0); +} + +/* + * Given a domain handle, return its associated domain name. + */ +int +ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char *domain_name, uint_t maxnamlen) +{ + vlds_dom_hdl2nam_arg_t vlds_arg; + + if (ds_fd < 0) { + return (errno = EBADF); + } + + vlds_arg.vlds_dhdl = dhdl; + vlds_arg.vlds_domain_name.vlds_strp = PTRTOUINT64(domain_name); + vlds_arg.vlds_domain_name.vlds_strlen = maxnamlen; + + if (ioctl(ds_fd, VLDS_DOM_HDL2NAM, &vlds_arg) < 0) { + return (errno); + } + + return (0); +} + +void +ds_unreg_svc(char *service, boolean_t is_client) +{ + ds_hdl_t hdl; + uint_t nhdls; + + while (ds_hdl_lookup(service, is_client, &hdl, 1, &nhdls) == 0 && + nhdls == 1) { + (void) ds_unreg_hdl(hdl); + } +} + +void +ds_fini(void) +{ + int i; + dslibentry_t *dsp; + + if (ds_fd >= 0) { + (void) close(ds_fd); + ds_fd = -1; + } + if (ds_evchan) { + (void) sysevent_evc_unsubscribe(ds_evchan, ds_sid_name); + (void) sysevent_evc_unbind(ds_evchan); + ds_evchan = NULL; + } + if (ndslib > 0) { + (void) mutex_lock(&dslib_lock); + for (i = 0, dsp = dslibtab; i < ndslib; i++, dsp++) { + if (dsp->dsl_hdl == NULL) + continue; + if (dsp->dsl_service) { + free(dsp->dsl_service); + } + } + free(dslibtab); + ndslib = 0; + dslibtab = NULL; + (void) mutex_unlock(&dslib_lock); + (void) mutex_destroy(&dslib_lock); + } +} diff --git a/usr/src/lib/libds/common/libds.h b/usr/src/lib/libds/common/libds.h new file mode 100644 index 0000000000..149e53c91a --- /dev/null +++ b/usr/src/lib/libds/common/libds.h @@ -0,0 +1,95 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDS_H +#define _LIBDS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> + +/* + * LDOMs User Domain Services library Interfaces + */ + +typedef uint64_t ds_hdl_t; /* service handle */ +typedef uint64_t ds_domain_hdl_t; /* domain handle */ +typedef void *ds_cb_arg_t; /* client callback arg */ + +#define DS_INVALID_HDL (0) /* a ds handle cannot be zero */ + +/* + * LDOMs User Domain Services versioning + */ +typedef struct ds_ver { + uint16_t major; + uint16_t minor; +} ds_ver_t; + +/* + * LDOMs User Domain Services capability + */ +typedef struct ds_capability { + char *svc_id; /* service identifier */ + ds_ver_t *vers; /* list of supported versions */ + uint_t nvers; /* number of supported versions */ +} ds_capability_t; + +/* + * LDOMs User Domain Services event callbacks + */ +typedef struct ds_ops { + void (*ds_reg_cb)(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver, + ds_domain_hdl_t dhdl); + void (*ds_unreg_cb)(ds_hdl_t hdl, ds_cb_arg_t arg); + void (*ds_data_cb)(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, + size_t buflen); + ds_cb_arg_t cb_arg; +} ds_ops_t; + +extern int ds_init(void); +extern int ds_svc_reg(ds_capability_t *cap, ds_ops_t *ops); +extern int ds_clnt_reg(ds_capability_t *cap, ds_ops_t *ops); +extern int ds_hdl_lookup(char *service, boolean_t is_client, ds_hdl_t *hdlsp, + uint_t maxhdls, uint_t *nhdlsp); +extern int ds_domain_lookup(ds_hdl_t hdl, ds_domain_hdl_t *dhdlp); +extern int ds_unreg_hdl(ds_hdl_t hdl); +extern int ds_send_msg(ds_hdl_t hdl, void *buf, size_t buflen); +extern int ds_recv_msg(ds_hdl_t hdl, void *buf, size_t buflen, + size_t *msglen); +extern int ds_isready(ds_hdl_t hdl, boolean_t *is_ready); +extern int ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp); +extern int ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char *domain_name, + uint_t maxnamlen); +extern void ds_unreg_svc(char *service, boolean_t is_client); +extern void ds_fini(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDS_H */ diff --git a/usr/src/lib/libds/common/llib-lds b/usr/src/lib/libds/common/llib-lds new file mode 100644 index 0000000000..83867420d8 --- /dev/null +++ b/usr/src/lib/libds/common/llib-lds @@ -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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include "libds.h" diff --git a/usr/src/lib/libds/common/mapfile-vers b/usr/src/lib/libds/common/mapfile-vers new file mode 100644 index 0000000000..889d1c47f0 --- /dev/null +++ b/usr/src/lib/libds/common/mapfile-vers @@ -0,0 +1,44 @@ +# +# 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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +SUNWprivate { + global: + ds_init; + ds_svc_reg; + ds_clnt_reg; + ds_hdl_lookup; + ds_domain_lookup; + ds_unreg_hdl; + ds_send_msg; + ds_recv_msg; + ds_isready; + ds_dom_name_to_hdl; + ds_dom_hdl_to_name; + ds_unreg_svc; + ds_fini; + local: + *; +}; diff --git a/usr/src/lib/libds/sparc/Makefile b/usr/src/lib/libds/sparc/Makefile new file mode 100644 index 0000000000..ea09428ea0 --- /dev/null +++ b/usr/src/lib/libds/sparc/Makefile @@ -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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libds/sparcv9/Makefile b/usr/src/lib/libds/sparcv9/Makefile new file mode 100644 index 0000000000..40e4cef06c --- /dev/null +++ b/usr/src/lib/libds/sparcv9/Makefile @@ -0,0 +1,30 @@ +# +# 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 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) |
