31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * CDDL HEADER START
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * The contents of this file are subject to the terms of the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Common Development and Distribution License (the "License").
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * You may not use this file except in compliance with the License.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * or http://www.opensolaris.org/os/licensing.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * See the License for the specific language governing permissions
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * and limitations under the License.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * When distributing Covered Code, include this CDDL HEADER in each
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * If applicable, add the following below this CDDL HEADER, with the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * fields enclosed by brackets "[]" replaced with your own identifying
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * information: Portions Copyright [yyyy] [name of copyright owner]
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * CDDL HEADER END
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <stdlib.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <stdio.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <strings.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <sys/types.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <sys/stat.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <time.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <fcntl.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <unistd.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <errno.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <assert.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <umem.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <alloca.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <sys/processor.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <poll.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <pthread.h>
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen#include <signal.h>
c3b50bc594edb4e967f0156a09c6e64b845dd8earb#include <values.h>
c3b50bc594edb4e967f0156a09c6e64b845dd8earb#include <libscf.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen#include <ctype.h>
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include "ldmsvcs_utils.h"
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen#include "ldom_alloc.h"
e6590bdc0d540003c7df26f1d3b66db7cae9be2cVuong Nguyen#include "ldom_utils.h"
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#define ASSERT(cnd) \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ((void) ((cnd) || ((void) fprintf(stderr, \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn "assertion failure in %s:%d: %s\n", \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn __FILE__, __LINE__, #cnd), 0)))
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#define FDS_VLDC \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn "/devices/virtual-devices@100/channel-devices@200/" \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn "/virtual-channel-client@1:ldmfma"
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
c3b50bc594edb4e967f0156a09c6e64b845dd8earb/* allow timeouts in sec that are nearly forever but small enough for an int */
c3b50bc594edb4e967f0156a09c6e64b845dd8earb#define LDM_TIMEOUT_CEILING (MAXINT / 2)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#define MIN(x, y) ((x) < (y) ? (x) : (y))
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * functions in this file are for version 1.0 of FMA domain services
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic ds_ver_t ds_vers[] = {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn { 1, 0 }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn};
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#define DS_NUM_VER (sizeof (ds_vers) / sizeof (ds_ver_t))
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * information for each channel
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstruct ldmsvcs_info {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_mutex_t mt;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_cond_t cv;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_channel_t fds_chan;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_reg_svcs_t fmas_svcs;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int cv_twait;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn};
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * struct listdata_s and struct poller_s are used to maintain the state of
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * the poller thread. this thread is used to manage incoming messages and
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * pass those messages onto the correct requesting thread. see the "poller
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * functions" section for more details.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstruct listdata_s {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn enum {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn UNUSED,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn PENDING,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ARRIVED
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } status;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint64_t req_num;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int fd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t datalen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn};
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic struct poller_s {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_mutex_t mt;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_cond_t cv;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_t polling_tid;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen int notify_pipe[2];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int doreset;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int doexit;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int nclients;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct listdata_s **list;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int list_len;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int pending_count;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn} pollbase = {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn PTHREAD_MUTEX_INITIALIZER,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn PTHREAD_COND_INITIALIZER,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 0,
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen {-1, -1},
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 1,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 0,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 0,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn NULL,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 0,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn 0
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn};
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic struct ldmsvcs_info *channel_init(struct ldom_hdl *lhp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int channel_openreset(struct ldmsvcs_info *lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int read_msg(struct ldmsvcs_info *lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
c3b50bc594edb4e967f0156a09c6e64b845dd8earbstatic int
c3b50bc594edb4e967f0156a09c6e64b845dd8earbget_smf_int_val(char *prop_nm, int min, int max, int default_val)
c3b50bc594edb4e967f0156a09c6e64b845dd8earb{
c3b50bc594edb4e967f0156a09c6e64b845dd8earb scf_simple_prop_t *prop; /* SMF property */
c3b50bc594edb4e967f0156a09c6e64b845dd8earb int64_t *valp; /* prop value ptr */
c3b50bc594edb4e967f0156a09c6e64b845dd8earb int64_t val; /* prop value to return */
c3b50bc594edb4e967f0156a09c6e64b845dd8earb
c3b50bc594edb4e967f0156a09c6e64b845dd8earb val = default_val;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb if ((prop = scf_simple_prop_get(NULL, LDM_SVC_NM, LDM_PROP_GROUP_NM,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb prop_nm)) != NULL) {
c3b50bc594edb4e967f0156a09c6e64b845dd8earb if ((valp = scf_simple_prop_next_integer(prop)) != NULL) {
c3b50bc594edb4e967f0156a09c6e64b845dd8earb val = *valp;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb if (val < min)
c3b50bc594edb4e967f0156a09c6e64b845dd8earb val = min;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb else if (val > max)
c3b50bc594edb4e967f0156a09c6e64b845dd8earb val = max;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb }
c3b50bc594edb4e967f0156a09c6e64b845dd8earb scf_simple_prop_free(prop);
c3b50bc594edb4e967f0156a09c6e64b845dd8earb }
c3b50bc594edb4e967f0156a09c6e64b845dd8earb return ((int)val);
c3b50bc594edb4e967f0156a09c6e64b845dd8earb}
c3b50bc594edb4e967f0156a09c6e64b845dd8earb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnchannel_close(struct ldmsvcs_info *lsp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn if (lsp->fds_chan.state == CHANNEL_OPEN ||
c3b50bc594edb4e967f0156a09c6e64b845dd8earb lsp->fds_chan.state == CHANNEL_READY) {
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn (void) close(lsp->fds_chan.fd);
c3b50bc594edb4e967f0156a09c6e64b845dd8earb lsp->cv_twait = get_smf_int_val(LDM_INIT_TO_PROP_NM,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb 0, LDM_TIMEOUT_CEILING, LDM_INIT_WAIT_TIME);
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn lsp->fds_chan.state = CHANNEL_CLOSED;
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * read size bytes of data from a streaming fd into buf
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnread_stream(int fd, void *buf, size_t size)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd_t pollfd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ssize_t rv;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t data_left;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ptrdiff_t currentp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.events = POLLIN;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.revents = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.fd = fd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn currentp = (ptrdiff_t)buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn data_left = size;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * data may come in bits and pieces
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn do {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((rv = read(fd, (void *)currentp, data_left)) < 0) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen if (errno == EAGAIN && poll(&pollfd, 1, 3000) > 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn continue; /* retry */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn data_left -= rv;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn currentp += rv;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } while (data_left > 0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * poller functions
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * at init time, a thread is created for the purpose of monitoring incoming
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * messages and doing one of the following:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 1. doing the initial handshake and version negotiation
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 2. handing incoming data off to the requesting thread (which is an fmd
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * module or scheme thread)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_handle_data(int fd, size_t payloadsize)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint64_t *req_num;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *pr;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t prlen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn prlen = sizeof (ds_data_handle_t) + sizeof (uint64_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (payloadsize < prlen)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pr = alloca(prlen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (read_stream(fd, pr, prlen) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn req_num = (uint64_t *)((ptrdiff_t)pr + sizeof (ds_data_handle_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < pollbase.list_len; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.list[i]->req_num == *req_num) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.list[i]->status == PENDING);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->status = ARRIVED;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->fd = fd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->datalen = payloadsize - prlen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.pending_count--;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&pollbase.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * now wait for receiving thread to read in the data
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (i < pollbase.list_len) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn while (pollbase.list[i]->status == ARRIVED)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_wait(&pollbase.cv, &pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * note that this function is meant to handle only DS_DATA messages
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_recv_data(struct ldom_hdl *lhp, uint64_t req_num, int index,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void **resp, size_t *resplen)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct timespec twait;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int ier;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn twait.tv_sec = time(NULL) + lhp->lsinfo->cv_twait;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn twait.tv_nsec = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.list[index]->req_num == req_num);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn while (pollbase.list[index]->status == PENDING &&
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.doreset == 0 && ier == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = pthread_cond_timedwait(&pollbase.cv, &pollbase.mt,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &twait);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ier == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.doreset == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.list[index]->status == ARRIVED);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * need to add req_num to beginning of resp
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *resplen = pollbase.list[index]->datalen +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (uint64_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *resp = lhp->allocp(*resplen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *((uint64_t *)*resp) = req_num;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (read_stream(pollbase.list[index]->fd,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb (void *)((ptrdiff_t)*resp + sizeof (uint64_t)),
c3b50bc594edb4e967f0156a09c6e64b845dd8earb *resplen - sizeof (uint64_t)) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = ETIMEDOUT;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[index]->status = UNUSED;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[index]->req_num = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&pollbase.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (--(pollbase.pending_count) == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&pollbase.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(ier == 0 || ier == ETIMEDOUT);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (ier);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_add_client(void)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.nclients++;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_remove_client(void)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.nclients--;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.nclients >= 0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyenpoller_add_pending(uint64_t req_num)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int newlen, index, i, j;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.pending_count++;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (j = 0, index = -1; j < 2 && index == -1; j++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < pollbase.list_len; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.list[i]->status == UNUSED) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->status = PENDING;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->req_num = req_num;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->datalen = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn index = i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (index == -1) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct listdata_s **newlist, **oldlist;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * get to this point if list is not long enough.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * check for a runaway list. since requests are
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * synchronous (clients send a request and need to
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * wait for the result before returning) the size
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * of the list cannot be much more than the number
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * of clients.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.list_len < pollbase.nclients + 1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn newlen = pollbase.list_len + 5;
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen newlist = ldom_alloc(newlen *
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen sizeof (struct listdata_s *));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < pollbase.list_len; i++)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn newlist[i] = pollbase.list[i];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn oldlist = pollbase.list;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list = newlist;
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(oldlist, pollbase.list_len *
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen sizeof (struct listdata_s *));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = pollbase.list_len; i < newlen; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i] =
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_alloc(sizeof (struct listdata_s));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->status = UNUSED;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list_len = newlen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(index != -1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (index);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_delete_pending(uint64_t req_num, int index)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.list[index]->req_num == req_num);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[index]->status = UNUSED;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (--(pollbase.pending_count) == 0 && pollbase.doreset == 1)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&pollbase.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyenpoller_shutdown(boolean_t wait)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.doexit = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen if (wait == B_TRUE) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /*
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Write a byte to the pipe to notify the poller thread to exit.
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * Then wait for it to exit.
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) write(pollbase.notify_pipe[0], "1", 1);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen (void) pthread_join(pollbase.polling_tid, NULL);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * perform the polling of incoming messages. manage any resets (usually
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * due to one end of the connection being closed) as well as exit
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * conditions.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_loop(void *arg)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct ldmsvcs_info *lsp;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pollfd_t pollfd[2];
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen struct pollfd *pipe_fd = &pollfd[0];
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen struct pollfd *recv_fd = &pollfd[1];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int ier;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp = (struct ldmsvcs_info *)arg;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (;;) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.doexit) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.doreset) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn while (pollbase.pending_count > 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_wait(&pollbase.cv,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(pollbase.pending_count == 0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < pollbase.list_len; i++)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.list[i]->status = UNUSED;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.doreset = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((ier = channel_openreset(lsp)) == 1) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn continue;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (ier == 2) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * start exit preparations
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen poller_shutdown(B_FALSE);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn continue;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->fd = pollbase.notify_pipe[1]; /* notification pipe */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->events = POLLIN;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pipe_fd->revents = 0;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->fd = lsp->fds_chan.fd; /* FMA LDC */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->events = POLLIN;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen recv_fd->revents = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen if (poll(pollfd, 2, -1) <= 0) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /* fd got closed */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) pthread_mutex_lock(&pollbase.mt);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pollbase.doreset = 1;
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) pthread_mutex_unlock(&pollbase.mt);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen channel_close(lsp);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen } else if (pipe_fd->revents & POLLIN) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /* Receive a notification to exit */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen channel_close(lsp);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen pthread_exit((void *)NULL);
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen } else if (read_msg(lsp) != 0) {
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen /* fail to read a message from the LDOM manager */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollbase.doreset = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn channel_close(lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * create the polling thread
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnpoller_init(struct ldmsvcs_info *lsp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int rc = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pollbase.polling_tid == 0) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen pthread_attr_t *attr = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen * create a joinable polling thread for receiving messages
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen * The notify pipe is for stopping the thread
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
f044df33d9fe9e8e3ed7344a8b548b17f20709f2Vuong Nguyen (void) notify_setup(pollbase.notify_pipe);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen if (pthread_create(&pollbase.polling_tid, attr,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb poller_loop, lsp) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&pollbase.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen/*
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen * Cleanup the polling thread
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyenstatic void
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyenpoller_fini(void)
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen{
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen int i;
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen /* stop the poller thread */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen poller_shutdown(B_TRUE);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen (void) pthread_mutex_lock(&pollbase.mt);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen /* Free up the list of outstanding requests */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen if (pollbase.list != NULL) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen for (i = 0; i < pollbase.list_len; i++) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen if (pollbase.list[i]) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(pollbase.list[i],
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen sizeof (struct listdata_s));
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen }
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen }
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(pollbase.list, pollbase.list_len *
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen sizeof (struct listdata_s *));
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen pollbase.list = NULL;
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen pollbase.list_len = 0;
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen }
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen (void) pthread_mutex_unlock(&pollbase.mt);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * utilities for message handlers
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_send(struct ldmsvcs_info *lsp, void *msg, size_t msglen)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (write(lsp->fds_chan.fd, msg, msglen) != msglen) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn channel_close(lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (ETIMEDOUT);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Find the max and min version supported
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_min_max_versions(uint16_t *min_major, uint16_t *max_major)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *min_major = ds_vers[0].major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *max_major = *min_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 1; i < DS_NUM_VER; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ds_vers[i].major < *min_major)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *min_major = ds_vers[i].major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ds_vers[i].major > *max_major)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *max_major = ds_vers[i].major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * check whether the major and minor numbers requested by remote ds client
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * can be satisfied. if the requested major is supported, true is
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * returned, and the agreed minor is returned in new_minor. if the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * requested major is not supported, the routine returns false, and the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * closest major is returned in *new_major, upon which the ds client should
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * renegotiate. the closest major is the just lower that the requested
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * major number.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic boolean_t
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_negotiate_version(uint16_t req_major, uint16_t *new_majorp,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint16_t *new_minorp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint16_t major, lower_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint16_t min_major, max_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn boolean_t found_match = B_FALSE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_min_max_versions(&min_major, &max_major);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * if the minimum version supported is greater than the version
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * requested, return the lowest version supported
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (min_major > req_major) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *new_majorp = min_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (B_FALSE);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * if the largest version supported is lower than the version
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * requested, return the largest version supported
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (max_major < req_major) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *new_majorp = max_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (B_FALSE);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * now we know that the requested version lies between the min and
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * max versions supported. check if the requested major can be
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * found in supported versions.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lower_major = min_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < DS_NUM_VER; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn major = ds_vers[i].major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (major == req_major) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn found_match = B_TRUE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *new_minorp = ds_vers[i].minor;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *new_majorp = major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if ((major < req_major) && (major > lower_major))
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lower_major = major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * If no match is found, return the closest available number
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (!found_match)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *new_majorp = lower_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (found_match);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * return 0 if service is added; 1 if service is a duplicate
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_svc_add(struct ldmsvcs_info *lsp, ds_reg_req_t *req, int minor)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_t *svc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i, rc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < lsp->fmas_svcs.nsvcs; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (strcmp(lsp->fmas_svcs.tbl[i]->name, req->svc_id) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc = lsp->fmas_svcs.tbl[i];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (svc == NULL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0); /* we don't need this service */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->fmas_svcs.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * duplicate registration is OK --- we retain the previous entry
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * (which has not been unregistered anyway)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (svc->state == DS_SVC_ACTIVE) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc->state = DS_SVC_ACTIVE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc->hdl = req->svc_handle;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc->ver.major = req->major_vers;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc->ver.minor = minor;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&lsp->fmas_svcs.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->fmas_svcs.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_svc_reset(struct ldmsvcs_info *lsp, int index)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i, start, end;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (index >= 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn start = index;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn end = index + 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn start = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn end = lsp->fmas_svcs.nsvcs;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->fmas_svcs.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = start; i < end; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i]->hdl = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i]->state = DS_SVC_INVAL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i]->ver.major =
c3b50bc594edb4e967f0156a09c6e64b845dd8earb ds_vers[DS_NUM_VER - 1].major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i]->ver.minor =
c3b50bc594edb4e967f0156a09c6e64b845dd8earb ds_vers[DS_NUM_VER - 1].minor;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->fmas_svcs.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_svc_remove(struct ldmsvcs_info *lsp, ds_svc_hdl_t svc_handle)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < lsp->fmas_svcs.nsvcs; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lsp->fmas_svcs.tbl[i]->hdl == svc_handle) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_reset(lsp, i);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * message handlers
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnds_handle_msg_noop(struct ldmsvcs_info *lsp, void *buf, size_t len)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnds_handle_init_req(struct ldmsvcs_info *lsp, void *buf, size_t len)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_init_req_t *req;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint16_t new_major, new_minor;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t msglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn req = (ds_init_req_t *)buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /* sanity check the incoming message */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (len != sizeof (ds_init_req_t)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn channel_close(lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Check version info. ACK only if the major numbers exactly
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * match. The service entity can retry with a new minor
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * based on the response sent as part of the NACK.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (fds_negotiate_version(req->major_vers, &new_major, &new_minor)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_init_ack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_init_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_INIT_ACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_init_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->minor_vers = MIN(new_minor, req->minor_vers);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (fds_send(lsp, H, msglen) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(lsp->fds_chan.state == CHANNEL_OPEN);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state = CHANNEL_READY;
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn /*
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn * Now the channel is ready after the handshake completes.
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn * Reset the timeout to a smaller value for receiving messages
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn * from the domain services.
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn */
c3b50bc594edb4e967f0156a09c6e64b845dd8earb lsp->cv_twait = get_smf_int_val(LDM_RUNNING_TO_PROP_NM,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb 0, LDM_TIMEOUT_CEILING, LDM_RUNNING_WAIT_TIME);
a298b85fd4d5149fdcc1bae48f9baab83a0390c9vn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_init_nack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_init_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_INIT_NACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_init_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->major_vers = new_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) fds_send(lsp, H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * do not update state; remote end may attempt to initiate
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * connection with a different version
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnds_handle_reg_req(struct ldmsvcs_info *lsp, void *buf, size_t len)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_reg_req_t *req;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn char *msg;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint16_t new_major, new_minor;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t msglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int dup_svcreg = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn req = (ds_reg_req_t *)buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msg = (char *)req->svc_id;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Service must be NULL terminated
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (req->svc_id == NULL || strlen(req->svc_id) == 0 ||
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msg[strlen(req->svc_id)] != '\0') {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn channel_close(lsp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (fds_negotiate_version(req->major_vers, &new_major, &new_minor) &&
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (dup_svcreg = fds_svc_add(lsp, req,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb MIN(new_minor, req->minor_vers))) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Check version info. ACK only if the major numbers
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * exactly match. The service entity can retry with a new
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * minor based on the response sent as part of the NACK.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_reg_ack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_reg_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bzero(H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_REG_ACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_reg_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->svc_handle = req->svc_handle;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->minor_vers = MIN(new_minor, req->minor_vers);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) fds_send(lsp, H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_reg_nack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_reg_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bzero(H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_REG_NACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_reg_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->svc_handle = req->svc_handle;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->major_vers = new_major;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (dup_svcreg)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->result = DS_REG_DUP;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->result = DS_REG_VER_NACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) fds_send(lsp, H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnds_handle_unreg(struct ldmsvcs_info *lsp, void *buf, size_t len)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_unreg_req_t *req;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t msglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn req = (ds_unreg_req_t *)buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (fds_svc_remove(lsp, req->svc_handle) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_unreg_ack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_unreg_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_REG_ACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_unreg_ack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->svc_handle = req->svc_handle;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) fds_send(lsp, H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_unreg_nack_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msglen = sizeof (ds_hdr_t) + sizeof (ds_unreg_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = alloca(msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_REG_NACK;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_unreg_nack_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->svc_handle = req->svc_handle;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) fds_send(lsp, H, msglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Message handler lookup table (v1.0 only for now) Future
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * versions can add their own lookup table.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avntypedef void (*ds_msg_handler_t)(struct ldmsvcs_info *lsp,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *buf, size_t len);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic const ds_msg_handler_t ds_msg_handlers[] = {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_init_req, /* DS_INIT_REQ */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_INIT_ACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_INIT_NACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_reg_req, /* DS_REG_REQ */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_REG_ACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_REG_NACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_unreg, /* DS_UNREG */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_UNREG_ACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_UNREG_NACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop, /* DS_DATA */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_handle_msg_noop /* DS_NACK */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn};
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * message and service internal functions
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyenfds_svc_alloc(struct ldmsvcs_info *lsp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen static char *name[] = { LDM_DS_NAME_CPU, LDM_DS_NAME_MEM,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen LDM_DS_NAME_PRI, LDM_DS_NAME_IOD, NULL };
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_init(&lsp->fmas_svcs.mt, NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_init(&lsp->fmas_svcs.cv, NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (lsp->fmas_svcs.nsvcs = 0; name[lsp->fmas_svcs.nsvcs] != NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.nsvcs++)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen lsp->fmas_svcs.tbl = (fds_svc_t **)ldom_alloc(sizeof (fds_svc_t *) *
c3b50bc594edb4e967f0156a09c6e64b845dd8earb lsp->fmas_svcs.nsvcs);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < lsp->fmas_svcs.nsvcs; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i] =
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen (fds_svc_t *)ldom_alloc(sizeof (fds_svc_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bzero(lsp->fmas_svcs.tbl[i], sizeof (fds_svc_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fmas_svcs.tbl[i]->name = name[i];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic fds_svc_t *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_svc_lookup(struct ldmsvcs_info *lsp, char *name)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct timespec twait;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_t *svc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int i, ier;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pthread_mutex_lock(&lsp->fmas_svcs.mt) == EINVAL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL); /* uninitialized or destroyed mutex */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn for (i = 0; i < lsp->fmas_svcs.nsvcs; i++) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (strcmp(lsp->fmas_svcs.tbl[i]->name, name) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn svc = lsp->fmas_svcs.tbl[i];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn break;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(svc != NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (svc->state == DS_SVC_INACTIVE) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* service is not registered */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ier = ETIMEDOUT;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen } else {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ier = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen twait.tv_sec = time(NULL) + lsp->cv_twait;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen twait.tv_nsec = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen while (svc->state != DS_SVC_ACTIVE && ier == 0 &&
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen lsp->fds_chan.state != CHANNEL_UNUSABLE)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ier = pthread_cond_timedwait(&lsp->fmas_svcs.cv,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen &lsp->fmas_svcs.mt, &twait);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * By now, the ds service should have registered already.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * If it does not, ldmd probably does not support this service.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * Then mark the service state as inactive.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (ier == ETIMEDOUT) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen svc->state = DS_SVC_INACTIVE;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->fmas_svcs.mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ier == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (svc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic uint64_t
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnfds_svc_req_num(void)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static uint64_t req_num = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (req_num++);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * return 0 if successful, 1 if otherwise
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnread_msg(struct ldmsvcs_info *lsp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t header;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *msg_buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * read the header
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (read_stream(lsp->fds_chan.fd, &header, sizeof (ds_hdr_t)) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (header.msg_type >=
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn sizeof (ds_msg_handlers) / sizeof (ds_msg_handler_t))
c3b50bc594edb4e967f0156a09c6e64b845dd8earb return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * handle data as a special case
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (header.msg_type == 9)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (poller_handle_data(lsp->fds_chan.fd,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb header.payload_len));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * all other types of messages should be small
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(header.payload_len < 1024);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn msg_buf = alloca(header.payload_len);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * read the payload
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (read_stream(lsp->fds_chan.fd, msg_buf, header.payload_len) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (*ds_msg_handlers[header.msg_type])(lsp, msg_buf, header.payload_len);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * return values:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 0 - success
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 1 - problem with opening the channel
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 2 - channed not opened; request to exit has been detected
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnchannel_openreset(struct ldmsvcs_info *lsp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int ier;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = pthread_mutex_lock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ier == EINVAL || lsp->fds_chan.state == CHANNEL_EXIT ||
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state == CHANNEL_UNUSABLE) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (2);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lsp->fds_chan.state == CHANNEL_UNINITIALIZED ||
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state == CHANNEL_CLOSED) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&lsp->cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((lsp->fds_chan.fd = open(FDS_VLDC, O_RDWR)) < 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state = CHANNEL_UNUSABLE;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb lsp->cv_twait = get_smf_int_val(LDM_RUNNING_TO_PROP_NM,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb 0, LDM_TIMEOUT_CEILING, LDM_RUNNING_WAIT_TIME);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&lsp->fmas_svcs.cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (2);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn vldc_opt_op_t op;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn op.op_sel = VLDC_OP_SET;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn op.opt_sel = VLDC_OPT_MODE;
20ae46ebaff1237662e05edf9db61538aa85d448ha op.opt_val = LDC_MODE_RELIABLE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ioctl(lsp->fds_chan.fd, VLDC_IOCTL_OPT_OP,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &op) != 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) close(lsp->fds_chan.fd);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state = CHANNEL_OPEN;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lsp->fds_chan.state == CHANNEL_OPEN) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * reset various channel parameters
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.ver.major = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.ver.minor = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_reset(lsp, -1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic void
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnchannel_fini(void)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen int i;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct ldmsvcs_info *lsp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * End the poller thread
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen poller_fini();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((lsp = channel_init(NULL)) == NULL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp->fds_chan.state = CHANNEL_EXIT;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) close(lsp->fds_chan.fd);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen /* Free the ldom service structure */
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen for (i = 0; i < lsp->fmas_svcs.nsvcs; i++) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(lsp->fmas_svcs.tbl[i], sizeof (fds_svc_t));
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen }
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(lsp->fmas_svcs.tbl,
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen lsp->fmas_svcs.nsvcs * sizeof (fds_svc_t *));
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(lsp, sizeof (struct ldmsvcs_info));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic struct ldmsvcs_info *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnchannel_init(struct ldom_hdl *lhp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static struct ldmsvcs_info *root = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn static int busy_init = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct timespec twait;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int expired;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn while (busy_init == 1)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_wait(&cv, &mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (root != NULL || (lhp == NULL && root == NULL)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (root);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * get to this point if we need to open the channel
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn busy_init = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn root = (struct ldmsvcs_info *)
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_alloc(sizeof (struct ldmsvcs_info));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bzero(root, sizeof (struct ldmsvcs_info));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn root->fds_chan.state = CHANNEL_UNINITIALIZED;
c3b50bc594edb4e967f0156a09c6e64b845dd8earb root->cv_twait = get_smf_int_val(LDM_INIT_TO_PROP_NM,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb 0, LDM_TIMEOUT_CEILING, LDM_INIT_WAIT_TIME);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (pthread_mutex_init(&root->mt, NULL) != 0 ||
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pthread_cond_init(&root->cv, NULL) != 0) {
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen ldom_free(root, sizeof (struct ldmsvcs_info));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen fds_svc_alloc(root);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_reset(root, -1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) poller_init(root);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn expired = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn twait.tv_sec = time(NULL) + 10;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn twait.tv_nsec = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&root->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * wait for channel to become uninitialized. this should be quick.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn while (root->fds_chan.state == CHANNEL_UNINITIALIZED && expired == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn expired = pthread_cond_timedwait(&root->cv, &root->mt, &twait);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (root->fds_chan.state == CHANNEL_UNUSABLE)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn expired = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&root->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn busy_init = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_cond_broadcast(&cv);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) atexit(channel_fini);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (expired == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (root);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnsendrecv(struct ldom_hdl *lhp, uint64_t req_num,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *msg, size_t msglen, ds_svc_hdl_t *svc_hdl, char *svcname,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void **resp, size_t *resplen)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct ldmsvcs_info *lsp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fds_svc_t *svc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int maxretries, index, i, ier;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lsp = lhp->lsinfo;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn i = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn maxretries = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn do {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * if any of the calls in this loop fail, retry some number
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * of times before giving up.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((svc = fds_svc_lookup(lsp, svcname)) == NULL) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lsp->fds_chan.state != CHANNEL_READY)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = ETIMEDOUT; /* channel not ready */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = ENOTSUP; /* service not ready */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&lsp->mt);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn continue;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ier = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *svc_hdl = svc->hdl;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
3dc13b01e6ccde35cc4e663e261cdcbed0070e48Vuong Nguyen index = poller_add_pending(req_num);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((ier = fds_send(lsp, msg, msglen)) != 0 ||
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (ier = poller_recv_data(lhp, req_num, index, resp,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb resplen)) != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn poller_delete_pending(req_num, index);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } while (i++ < maxretries && ier != 0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(ier == 0 || ier == ETIMEDOUT || ier == ENOTSUP);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (ier);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * input:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * msg_type - requested operation: FMA_CPU_REQ_STATUS or FMA_CPU_REQ_OFFLINE
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * cpuid - physical cpu id
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * normal return values:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * P_OFFLINE - cpu is offline
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * P_ONLINE - cpu is online
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * abnormal return values:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ETIMEDOUT - LDOM manager is not responding
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ENOTSUP - LDOM service for cpu offlining/status is not available
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ENOMSG - got an unexpected response from the LDOM cpu service
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avncpu_request(struct ldom_hdl *lhp, uint32_t msg_type, uint32_t cpuid)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_data_handle_t *D;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fma_cpu_service_req_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *svcname = LDM_DS_NAME_CPU;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fma_cpu_resp_t *respmsg;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *resp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t resplen, reqmsglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int rc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lhp->lsinfo == NULL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (ENOMSG);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn reqmsglen = sizeof (ds_hdr_t) + sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_cpu_service_req_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = lhp->allocp(reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn D = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)D + sizeof (ds_data_handle_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_DATA;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_cpu_service_req_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->req_num = fds_svc_req_num();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->msg_type = msg_type;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->cpu_id = cpuid;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((rc = sendrecv(lhp, R->req_num, H, reqmsglen,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &D->svc_handle, svcname, &resp, &resplen)) != 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(resplen == sizeof (fma_cpu_resp_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn respmsg = (fma_cpu_resp_t *)resp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = ENOMSG;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->result == FMA_CPU_RESP_OK) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->status == FMA_CPU_STAT_ONLINE)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = P_ONLINE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else if (respmsg->status == FMA_CPU_STAT_OFFLINE)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = P_OFFLINE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (msg_type == FMA_CPU_REQ_OFFLINE &&
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn respmsg->status == FMA_CPU_STAT_OFFLINE)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = P_OFFLINE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(resp, resplen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * input:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * msg_type - requested operation: FMA_MEM_REQ_STATUS or FMA_MEM_REQ_RETIRE
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * pa - starting address of memory page
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * pgsize - memory page size in bytes
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * normal return values for msg_type == FMA_MEM_REQ_STATUS:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 0 - page is retired
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EAGAIN - page is scheduled for retirement
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EIO - page not scheduled for retirement
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EINVAL - error
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * normal return values for msg_type == FMA_MEM_REQ_RETIRE:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * 0 - success in retiring page
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EIO - page is already retired
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EAGAIN - page is scheduled for retirement
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * EINVAL - error
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * abnormal return values (regardless of msg_type)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ETIMEDOUT - LDOM manager is not responding
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ENOTSUP - LDOM service for cpu offlining/status is not available
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ENOMSG - got an unexpected response from the LDOM cpu service
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnmem_request(struct ldom_hdl *lhp, uint32_t msg_type, uint64_t pa,
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn uint64_t pgsize)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_data_handle_t *D;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fma_mem_service_req_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *svcname = LDM_DS_NAME_MEM;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fma_mem_resp_t *respmsg;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *resp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t resplen, reqmsglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int rc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lhp->lsinfo == NULL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (ENOMSG);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn reqmsglen = sizeof (ds_hdr_t) + sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_mem_service_req_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = lhp->allocp(reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bzero(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn D = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)D + sizeof (ds_data_handle_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_DATA;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_mem_service_req_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->req_num = fds_svc_req_num();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->msg_type = msg_type;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->real_addr = pa;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->length = pgsize;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((rc = sendrecv(lhp, R->req_num, H, reqmsglen,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &D->svc_handle, svcname, &resp, &resplen)) != 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ASSERT(resplen == sizeof (fma_mem_resp_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn respmsg = (fma_mem_resp_t *)resp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = ENOMSG;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (msg_type == FMA_MEM_REQ_STATUS) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->result == FMA_MEM_RESP_OK) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->status == FMA_MEM_STAT_RETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = 0; /* page is retired */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else if (respmsg->status == FMA_MEM_STAT_NOTRETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = EIO; /* page is not scheduled */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (respmsg->result == FMA_MEM_RESP_FAILURE) {
1557e65f9d0c6fde875d807c12fc03ea20f50280vn if (respmsg->status == FMA_MEM_STAT_NOTRETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = EAGAIN; /* page is scheduled */
1557e65f9d0c6fde875d807c12fc03ea20f50280vn else if (respmsg->status == FMA_MEM_STAT_ILLEGAL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = EINVAL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (msg_type == FMA_MEM_REQ_RETIRE) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->result == FMA_MEM_RESP_OK) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->status == FMA_MEM_STAT_RETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = 0; /* is successfully retired */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (respmsg->result == FMA_MEM_RESP_FAILURE) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (respmsg->status == FMA_MEM_STAT_RETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = EIO; /* is already retired */
1557e65f9d0c6fde875d807c12fc03ea20f50280vn else if (respmsg->status == FMA_MEM_STAT_NOTRETIRED)
1557e65f9d0c6fde875d807c12fc03ea20f50280vn rc = EAGAIN; /* is scheduled to retire */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else if (respmsg->status == FMA_MEM_STAT_ILLEGAL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn rc = EINVAL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye } else if (msg_type == FMA_MEM_REQ_RESURRECT) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (respmsg->result == FMA_MEM_RESP_OK) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (respmsg->status == FMA_MEM_STAT_NOTRETIRED)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = 0; /* is successfully unretired */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye } if (respmsg->result == FMA_MEM_RESP_FAILURE) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (respmsg->status == FMA_MEM_STAT_RETIRED)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = EAGAIN; /* page couldn't be locked */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (respmsg->status == FMA_MEM_STAT_NOTRETIRED)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = EIO; /* page isn't retired already */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (respmsg->status == FMA_MEM_STAT_ILLEGAL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = EINVAL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(resp, resplen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (rc);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * APIs
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnint
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_check_channel(void)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct stat buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (stat(FDS_VLDC, &buf) == 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0); /* vldc exists */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else if (errno == ENOENT || errno == ENOTDIR)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (1); /* vldc does not exist */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (-1); /* miscellaneous error */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnvoid
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_init(struct ldom_hdl *lhp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ldmsvcs_check_channel() != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->lsinfo = channel_init(lhp);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn poller_add_client();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnvoid
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_fini(struct ldom_hdl *lhp)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ldmsvcs_check_channel() != 0)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn poller_remove_client();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*ARGSUSED*/
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnssize_t
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_get_core_md(struct ldom_hdl *lhp, uint64_t **buf)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_hdr_t *H;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ds_data_handle_t *D;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fma_req_pri_t *R;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *svcname = LDM_DS_NAME_PRI;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn void *resp;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn size_t resplen, reqmsglen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn ssize_t buflen;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn int rc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (lhp->lsinfo == NULL)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (-1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn reqmsglen = sizeof (ds_hdr_t) + sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_req_pri_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H = lhp->allocp(reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn D = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R = (void *)((ptrdiff_t)D + sizeof (ds_data_handle_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->msg_type = DS_DATA;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn H->payload_len = sizeof (ds_data_handle_t) +
c3b50bc594edb4e967f0156a09c6e64b845dd8earb sizeof (fma_req_pri_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn R->req_num = fds_svc_req_num();
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((rc = sendrecv(lhp, R->req_num, H, reqmsglen,
c3b50bc594edb4e967f0156a09c6e64b845dd8earb &D->svc_handle, svcname, &resp, &resplen)) != 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn errno = rc;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (-1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(H, reqmsglen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * resp should contain the req_num immediately followed by the PRI
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * (the latter may or may not be present). unfortunately, the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * current compiler flags cause a warning for the following
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * definition
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * typedef struct {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * uint64_t req_num;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * uint8_t pri[];
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * } fma_pri_resp_t;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * so we do not use the struct here.
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (resplen <= sizeof (uint64_t)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(resp, resplen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (resplen == sizeof (uint64_t))
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (0);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn else
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (-1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn buflen = resplen - sizeof (uint64_t);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *buf = lhp->allocp(buflen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn bcopy((void *)((ptrdiff_t)resp + sizeof (uint64_t)), *buf, buflen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn lhp->freep(resp, resplen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (buflen);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * see cpu_request() for a description of return values
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnint
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_cpu_req_status(struct ldom_hdl *lhp, uint32_t cpuid)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (cpu_request(lhp, FMA_CPU_REQ_STATUS, cpuid));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnint
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_cpu_req_offline(struct ldom_hdl *lhp, uint32_t cpuid)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (cpu_request(lhp, FMA_CPU_REQ_OFFLINE, cpuid));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
5f149bca52352f45598e5563debe72ce04bd7a21cyint
5f149bca52352f45598e5563debe72ce04bd7a21cyldmsvcs_cpu_req_online(struct ldom_hdl *lhp, uint32_t cpuid)
5f149bca52352f45598e5563debe72ce04bd7a21cy{
5f149bca52352f45598e5563debe72ce04bd7a21cy return (cpu_request(lhp, FMA_CPU_REQ_ONLINE, cpuid));
5f149bca52352f45598e5563debe72ce04bd7a21cy}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * see mem_request() for a description of return values
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnint
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_mem_req_status(struct ldom_hdl *lhp, uint64_t pa)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (mem_request(lhp, FMA_MEM_REQ_STATUS, pa, getpagesize()));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnint
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnldmsvcs_mem_req_retire(struct ldom_hdl *lhp, uint64_t pa)
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn{
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (mem_request(lhp, FMA_MEM_REQ_RETIRE, pa, getpagesize()));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn}
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
5f149bca52352f45598e5563debe72ce04bd7a21cyint
5f149bca52352f45598e5563debe72ce04bd7a21cyldmsvcs_mem_req_unretire(struct ldom_hdl *lhp, uint64_t pa)
5f149bca52352f45598e5563debe72ce04bd7a21cy{
5f149bca52352f45598e5563debe72ce04bd7a21cy return (mem_request(lhp, FMA_MEM_REQ_RESURRECT, pa, getpagesize()));
5f149bca52352f45598e5563debe72ce04bd7a21cy}
5f149bca52352f45598e5563debe72ce04bd7a21cy
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenint
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyenldmsvcs_io_req_id(struct ldom_hdl *lhp, uint64_t addr, uint_t type,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen uint64_t *virt_addr, char *name, int name_len, uint64_t *did)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen{
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ds_hdr_t *H;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen ds_data_handle_t *D;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen fma_io_req_t *R;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen char *svcname = LDM_DS_NAME_IOD;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen void *resp;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen fma_io_resp_t *iop;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen size_t resplen, reqmsglen;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int offset;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen int rc;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (lhp->lsinfo == NULL)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen reqmsglen = sizeof (ds_hdr_t) + sizeof (ds_data_handle_t) +
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen sizeof (fma_io_req_t);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen H = lhp->allocp(reqmsglen);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen D = (void *)((ptrdiff_t)H + sizeof (ds_hdr_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen R = (void *)((ptrdiff_t)D + sizeof (ds_data_handle_t));
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen H->msg_type = DS_DATA;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen H->payload_len = sizeof (ds_data_handle_t) + sizeof (fma_io_req_t);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen R->req_num = fds_svc_req_num();
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen R->msg_type = type;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen R->rsrc_address = addr;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rc = ENOMSG;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if ((rc = sendrecv(lhp, R->req_num, H, reqmsglen,
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen &D->svc_handle, svcname, &resp, &resplen)) != 0) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen lhp->freep(H, reqmsglen);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (rc);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen lhp->freep(H, reqmsglen);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /*
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * resp should contain the req_num, status, virtual addr, domain id
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen * and the domain name. The domain name may or may not be present.
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen offset = sizeof (fma_io_resp_t);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (resplen < offset) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen lhp->freep(resp, resplen);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (-1);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen iop = (fma_io_resp_t *)resp;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen switch (iop->result) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen case FMA_IO_RESP_OK:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen /* success */
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rc = 0;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *virt_addr = iop->virt_rsrc_address;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *did = iop->domain_id;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (name == NULL || name_len <= 0)
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen *name = '\0';
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen if (resplen > offset) {
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen (void) strncpy(name, (char *)((ptrdiff_t)resp + offset),
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen name_len);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen default:
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen rc = -1;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen break;
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen }
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen lhp->freep(resp, resplen);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen return (rc);
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen}
25351652d920ae27c5a56c199da581033ce763f6Vuong Nguyen
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn/* end file */