82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * CDDL HEADER START
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * The contents of this file are subject to the terms of the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Common Development and Distribution License (the "License").
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * You may not use this file except in compliance with the License.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * or http://www.opensolaris.org/os/licensing.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * See the License for the specific language governing permissions
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * and limitations under the License.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * When distributing Covered Code, include this CDDL HEADER in each
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * If applicable, add the following below this CDDL HEADER, with the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * fields enclosed by brackets "[]" replaced with your own identifying
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * information: Portions Copyright [yyyy] [name of copyright owner]
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * CDDL HEADER END
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
1a024a4828552f36f41749085bad547c64a0f0a6Mike Christensen * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <dlfcn.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <errno.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <fcntl.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <stdio.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <stdlib.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <strings.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <synch.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <thread.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <unistd.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <utility.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/mdesc.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/mdesc_impl.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/debug.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/stat.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/types.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include <sys/utsname.h>
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include "ldma.h"
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include "libds.h"
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#include "libv12n.h"
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * sun4 support for libv12n.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Non-sun4v support is minimal. The v12n_capabilities() function will
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * only return 0 (not supported, not enabled, no implementation).
82629e3015252bf18319ba3815c773df23e21436Mike Christensen *
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * For sun4v the support for v12n_capabilities(), v12n_domain_roles(),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * v12n_domain_name() and v12n_domain_uuid() are supported by scanning the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * MD from /dev/mdesc for specific properties. For v12n_ctrl_domain() and
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * v12n_chassis_serialno(), the ldoms agent daemon (ldmad) on the control
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * domain supplies the required information via the "agent-system" domain
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * service.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* libds statics */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void *v12n_ds_dlhdl = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int (*v12n_ds_send_msg)(ds_hdl_t, void *, size_t) = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int (*v12n_ds_clnt_reg)(ds_capability_t *, ds_ops_t *);
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int (*v12n_ds_unreg_svc)(char *, boolean_t);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Defines to support the 'agent-system' domain service.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define LDMA_SYSTEM_NVERS \
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (sizeof (v12n_ldma_system_vers) / sizeof (ds_ver_t))
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic ds_ver_t v12n_ldma_system_vers[] = { { 1, 0} };
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic ds_capability_t v12n_ldma_cap = {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen LDMA_NAME_SYSTEM, /* svc_id */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_system_vers, /* vers */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen LDMA_SYSTEM_NVERS /* nvers */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen};
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void v12n_ldma_register_handler(ds_hdl_t hdl, ds_cb_arg_t arg,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ds_ver_t *ver, ds_domain_hdl_t dhdl);
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void v12n_ldma_data_handler(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen size_t buflen);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic ds_ops_t v12n_ldma_ops = {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_register_handler, /* ds_reg_cb */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen NULL, /* ds_unreg_cb */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_data_handler, /* ds_data_cb */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen NULL /* ds_cb_arg */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen};
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* v12n_ldma_cv_state values */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_CVINVALID -1 /* invalid value for cv_state */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_REGWAITING 0 /* waiting for ctrl domain reg */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_REGRECEIVED 1 /* received ctrl domain reg */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_MSGWAITING 2 /* waiting for message response */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_MSGRECEIVED 3 /* received message response */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDMA_MSGERROR 4 /* received a bad message */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* 'agent-system' data used in async registration/data message handlers */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic ds_hdl_t v12n_ldma_ctrl_hdl = DS_INVALID_HDL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int v12n_ldma_msgtype;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic char *v12n_ldma_msgstr;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic mutex_t v12n_ldma_lock = DEFAULTMUTEX;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic cond_t v12n_ldma_cv = DEFAULTCV;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int v12n_ldma_cv_state = V12N_LDMA_CVINVALID;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic mutex_t v12n_ldma_cv_lock = DEFAULTMUTEX;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* 'agent-system' timeout values in seconds */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int v12n_ldma_timeout = 15;
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int v12n_ldma_sleeptime = 1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define V12N_LDOMS_SUPPORTED (V12N_CAP_SUPPORTED | V12N_CAP_ENABLED | \
82629e3015252bf18319ba3815c773df23e21436Mike Christensen V12N_CAP_IMPL_LDOMS)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen#define MD_DEVICE "/dev/mdesc"
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * libv12n routines to support /dev/mdesc.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Wrapper for MD free: need unused size argument.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* ARGSUSED */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_md_free(void *buf, size_t n)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(buf);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Wrapper for MD init: read MD and invoke md_init_intern.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic md_t *
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_md_init()
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_t *mdp;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *buf = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_header_t mdh;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int md_size;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int fd;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Open the Machine Description (MD)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen fd = open(MD_DEVICE, O_RDONLY);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (fd == -1) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (NULL);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (read(fd, &mdh, sizeof (md_header_t)) != sizeof (md_header_t))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto errdone;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_size = sizeof (md_header_t) + mdh.node_blk_sz + mdh.name_blk_sz +
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mdh.data_blk_sz;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((buf = malloc(md_size)) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto errdone;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) memcpy(buf, &mdh, sizeof (md_header_t));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (read(fd, buf + sizeof (md_header_t),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_size - sizeof (md_header_t)) != md_size - sizeof (md_header_t)) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto errdone;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mdp = md_init_intern((uint64_t *)((void *)buf), malloc, v12n_md_free);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) close(fd);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensenerrdone:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) close(fd);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(buf);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (NULL);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Wrapper for md_fini. Allow NULL md ptr and free MD buffer.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_md_fini(void *md)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_impl_t *mdp = (md_impl_t *)md;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (mdp) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(mdp->caddr);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) md_fini(md);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * See if LDoms domaining is enabled, returns 1 if enabled.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the value of the 'domaining-enabled' property under the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'platform' node. Value of 1 => domaining is enabled.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_domaining_enabled()
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mde_cookie_t *nodes, rootnode;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int nnodes;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen uint64_t prop_val = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_t *mdp;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((mdp = v12n_md_init()) == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nnodes = md_node_count(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nodes = malloc(nnodes * sizeof (mde_cookie_t));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (nodes == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_md_fini(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rootnode = md_root_node(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_find_name(mdp, "fwd"), nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (nnodes >= 1) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) md_get_prop_val(mdp, nodes[0], "domaining-enabled",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &prop_val);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_md_fini(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (prop_val == 1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensenint
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_capabilities()
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen struct utsname uinfo;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen struct stat st;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int cap;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check if this is an LDoms system. When using LDoms each
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * domain should have a /dev/mdesc device providing access to
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * the Machine Description (MD) of the domain. If this device
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * does not exist then this is not an LDoms system.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (uname(&uinfo) == -1 || strcmp(uinfo.machine, "sun4v")) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Not sun4v -> LDoms not supported
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cap = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if (stat(MD_DEVICE, &st) == 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * sun4v + /dev/mdesc exists -> Check if LDoms enabled
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * via the 'domaining-enabled' property.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cap = (V12N_CAP_SUPPORTED | V12N_CAP_IMPL_LDOMS |
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (v12n_domaining_enabled() ? V12N_CAP_ENABLED : 0));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if (errno == ENOENT) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * sun4v + /dev/mdesc does not exist -> LDoms supported
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * but not enabled.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cap = (V12N_CAP_SUPPORTED | V12N_CAP_IMPL_LDOMS);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (cap);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Routines to support v12n_domain_roles.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_scan_md_nodes(md_t *mdp, char *node_name, char *node_str_prop,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char **props)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mde_cookie_t *nodes, rootnode;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int nnodes, i, j;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *prop_str;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nnodes = md_node_count(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nodes = malloc(nnodes * sizeof (mde_cookie_t));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (nodes == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rootnode = md_root_node(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, node_name),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_find_name(mdp, "fwd"), nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (node_str_prop == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (nnodes > 0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen for (i = 0; i < nnodes; i++) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (md_get_prop_str(mdp, nodes[i], node_str_prop, &prop_str))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen continue;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen for (j = 0; props[j] != NULL; j++) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (strcmp(prop_str, props[j]) == 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check if MD has a hypervisor access point, returns 1 if true.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check the MD for a 'virtual-device-port' node whose 'vldc-svc-name' is
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'hvctl'.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_check_hv_access(md_t *mdp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen static char *hvctl_str[] = {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "hvctl",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen NULL
82629e3015252bf18319ba3815c773df23e21436Mike Christensen };
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (v12n_scan_md_nodes(mdp, "virtual-device-port", "vldc-svc-name",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen hvctl_str));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check if MD has a virtual device service (vcc, vsw, vds), returns 1 if true.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Need to check all the MD 'virtual-device' nodes for a 'device-type' property
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * of 'vcc', 'vsw' or 'vds'.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_check_virtual_service(md_t *mdp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen static char *vdevs[] = {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "vcc",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "vsw",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "vds",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen NULL
82629e3015252bf18319ba3815c773df23e21436Mike Christensen };
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (v12n_scan_md_nodes(mdp, "virtual-device", "device-type",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen vdevs));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check if MD has an physical I/O device node, returns 1 if true.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_check_io_service(md_t *mdp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (v12n_scan_md_nodes(mdp, "iodevice", NULL, NULL));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check if a MD node is root PCI device, returns 1 if true.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Need to check all the MD 'iodevice' nodes for a 'device-type' property
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * of 'pciex'.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_check_root(md_t *mdp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen static char *pciex[] = {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "pciex",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen NULL
82629e3015252bf18319ba3815c773df23e21436Mike Christensen };
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (v12n_scan_md_nodes(mdp, "iodevice", "device-type", pciex));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the domain roles for the domain.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenint
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_domain_roles()
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_t *mdp;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int roles = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ENOTSUP;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (-1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((mdp = v12n_md_init()) == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = EACCES;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (-1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_check_hv_access(mdp))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen roles |= V12N_ROLE_CONTROL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_check_virtual_service(mdp))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen roles |= V12N_ROLE_SERVICE;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_check_io_service(mdp))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen roles |= V12N_ROLE_IO;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_check_root(mdp))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen roles |= V12N_ROLE_ROOT;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_md_fini(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (roles);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get domain name from MD's virtual domain service node, returns 1 on success.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * The domain name is a string property 'vlds-domain-name' under the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'virtual-device' device node whose name is 'virtual-domain-service'.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_get_md_domain_name(md_t *mdp, char **vds_dnamep)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mde_cookie_t *vdev_nodes, rootnode;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int list_size, nvdevs, num_nodes, i, rv;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *vldc_name;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen num_nodes = md_node_count(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen list_size = num_nodes * sizeof (mde_cookie_t);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen vdev_nodes = malloc(list_size);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (vdev_nodes == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rootnode = md_root_node(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen nvdevs = md_scan_dag(mdp, rootnode, md_find_name(mdp, "virtual-device"),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_find_name(mdp, "fwd"), vdev_nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen for (i = 0; i < nvdevs; i++) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (md_get_prop_str(mdp, vdev_nodes[i], "name", &vldc_name))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen continue;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (strcmp(vldc_name, "virtual-domain-service") == 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = (md_get_prop_str(mdp, vdev_nodes[i],
82629e3015252bf18319ba3815c773df23e21436Mike Christensen "vlds-domain-name", vds_dnamep) == 0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(vdev_nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * String copyout utility.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic size_t
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_string_copyout(char *sout, char *sfrom, size_t count)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen size_t ret = strlen(sfrom) + 1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (sout != NULL && count > 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen count = MIN(ret, count);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) memcpy(sout, sfrom, count);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ret);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the domain name of this domain.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensensize_t
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_domain_name(char *buf, size_t count)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_t *mdp = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *ldmname;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int rv = -1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ENOTSUP;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if ((mdp = v12n_md_init()) == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = EACCES;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if (!v12n_get_md_domain_name(mdp, &ldmname)) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ESRCH;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = v12n_string_copyout(buf, ldmname, count);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_md_fini(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get UUID string from MD, returns 1 on success.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * The UUID is a string property 'uuid' under the 'platform' node of the MD.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_get_md_uuid_str(md_t *mdp, char **uuid_strp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen mde_cookie_t *plat_nodes, rootnode;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int list_size, npnodes, num_nodes, rv;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen num_nodes = md_node_count(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen list_size = num_nodes * sizeof (mde_cookie_t);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen plat_nodes = malloc(list_size);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (plat_nodes == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rootnode = md_root_node(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen npnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"),
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_find_name(mdp, "fwd"), plat_nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (npnodes >= 1)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = !md_get_prop_str(mdp, plat_nodes[0], "uuid", uuid_strp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen else
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(plat_nodes);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the domain UUID.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenint
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_domain_uuid(uuid_t uuid)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen md_t *mdp = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *uuid_str;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int rv = -1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ENOTSUP;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if ((mdp = v12n_md_init()) == NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = EACCES;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if (!v12n_get_md_uuid_str(mdp, &uuid_str)) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ESRCH;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = uuid_parse(uuid_str, uuid);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_md_fini(mdp);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Send 'agent-sytem' request message.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_ldma_send_request()
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldma_message_header_t ldmamsg;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ds_send_msg == NULL || v12n_ldma_ctrl_hdl == DS_INVALID_HDL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldmamsg.msg_num = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldmamsg.msg_type = v12n_ldma_msgtype;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldmamsg.msg_info = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (v12n_ds_send_msg(v12n_ldma_ctrl_hdl, (char *)&ldmamsg,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen sizeof (ldmamsg)));
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'agent-system' registration handler.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * If we get a registration from the control domain (domain 0), then send
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * the requested message. Otherwise, ignore the registration.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* ARGSUSED */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_ldma_register_handler(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ds_domain_hdl_t dhdl)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /* got registration from control domain */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (dhdl == 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_lock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ldma_cv_state == V12N_LDMA_REGWAITING) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_ctrl_hdl = hdl;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_cv_state = V12N_LDMA_REGRECEIVED;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) cond_signal(&v12n_ldma_cv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'agent-system' data handler.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/* ARGSUSED */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic void
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_ldma_data_handler(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen size_t buflen)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *data;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldma_message_header_t *ldmp;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int n;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Ignore any message not from the control domain.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ldma_ctrl_hdl != hdl)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Ignore any unexpected message.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (buflen < LDMA_MESSAGE_HEADER_SIZE)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Ignore message with unexpected msgnum.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldmp = (ldma_message_header_t *)buf;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (ldmp->msg_num != 0)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen switch (ldmp->msg_type) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen case LDMA_MSG_RESULT:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (ldmp->msg_info == 0 ||
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ldmp->msg_info > LDMA_MESSAGE_DLEN(buflen)) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen data = LDMA_HDR2DATA(buf);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /* ensure that data ends with a '\0' */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen data[ldmp->msg_info - 1] = '\0';
82629e3015252bf18319ba3815c773df23e21436Mike Christensen switch (v12n_ldma_msgtype) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen case LDMA_MSGSYS_GET_SYSINFO:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Control domain nodename is second string in the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * message. Make sure there is enough data in the msg
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * to have a second string.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen n = strlen(data);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (LDMA_MESSAGE_DLEN(buflen) <= n + 3) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen data += n + 1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ldma_msgstr = strdup(data)) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen else
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGRECEIVED;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen case LDMA_MSGSYS_GET_CHASSISNO:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ldma_msgstr = strdup(data)) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen else
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGRECEIVED;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen default:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /* v12n_ldma_msgtype must be valid */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen ASSERT(0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen case LDMA_MSG_ERROR:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen cv_state = V12N_LDMA_MSGERROR;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen default:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /* unexpected message, ignored */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_lock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_cv_state = cv_state;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) cond_signal(&v12n_ldma_cv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * libds doesn't exist on non-sun4v, dynamically load it and get the
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * function pointers to the needed lib functions.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_libds_init(void)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ds_dlhdl != NULL) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ds_clnt_reg == NULL || v12n_ds_send_msg == NULL ||
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ds_unreg_svc == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ds_dlhdl = dlopen("libds.so.1",
82629e3015252bf18319ba3815c773df23e21436Mike Christensen RTLD_NOW | RTLD_GLOBAL)) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ds_clnt_reg = (int (*)(ds_capability_t *, ds_ops_t *))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen dlsym(v12n_ds_dlhdl, "ds_clnt_reg")) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ds_send_msg = (int (*)(ds_hdl_t, void *, size_t))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen dlsym(v12n_ds_dlhdl, "ds_send_msg")) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((v12n_ds_unreg_svc = (int (*)(char *, boolean_t))
82629e3015252bf18319ba3815c773df23e21436Mike Christensen dlsym(v12n_ds_dlhdl, "ds_unreg_svc")) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (ENOENT);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (0);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Initiate and wait for an ldmad 'agent-system' domain service.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Dynamically load libds, register the client 'agent-system' service
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * and wait for a specified amount of time for the 'agent-system'
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * service on the control domain to respond to the request.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensenstatic int
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_get_ldma_system_msg(int msgtype, char **strp)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int tout;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int err = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen timestruc_t timeout;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Ensure that there's only one thread trying to do a
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * 'agent-system' client registration/message at a time.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_lock(&v12n_ldma_lock);
1a024a4828552f36f41749085bad547c64a0f0a6Mike Christensen if ((err = v12n_libds_init()) != 0) {
1a024a4828552f36f41749085bad547c64a0f0a6Mike Christensen (void) mutex_unlock(&v12n_ldma_lock);
1a024a4828552f36f41749085bad547c64a0f0a6Mike Christensen return (err);
1a024a4828552f36f41749085bad547c64a0f0a6Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_msgtype = msgtype;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_msgstr = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /* initialize v12n_ldma_cv_state variable before registering service */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_lock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_cv_state = V12N_LDMA_REGWAITING;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Other instances may be trying to load the "agent-system" service.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * If a collision happens (EBUSY error), wait and try again.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen for (tout = 0; tout < v12n_ldma_timeout; tout += v12n_ldma_sleeptime) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((err = v12n_ds_clnt_reg(&v12n_ldma_cap,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &v12n_ldma_ops)) == 0)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (err != EALREADY) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto done;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) sleep(v12n_ldma_sleeptime);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (tout >= v12n_ldma_timeout) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen err = EBUSY;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto done;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Wait for control domain registration.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen timeout.tv_sec = v12n_ldma_timeout;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen timeout.tv_nsec = 0;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_lock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen while (v12n_ldma_cv_state == V12N_LDMA_REGWAITING) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((err = cond_reltimedwait(&v12n_ldma_cv,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &v12n_ldma_cv_lock, &timeout)) != EINTR)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Check for timeout or an error.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ldma_cv_state != V12N_LDMA_REGRECEIVED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (err == 0)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen err = EPROTO;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto done;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Received a registration request, send the request message.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_cv_state = V12N_LDMA_MSGWAITING;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((err = v12n_ldma_send_request()) != 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto done;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen while (v12n_ldma_cv_state == V12N_LDMA_MSGWAITING) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if ((err = cond_reltimedwait(&v12n_ldma_cv,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &v12n_ldma_cv_lock, &timeout)) != EINTR)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen break;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ldma_cv_state != V12N_LDMA_MSGRECEIVED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (err == 0)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen err = EPROTO;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen goto done;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_cv_state = V12N_LDMA_CVINVALID;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_cv_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen /*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * If v12n_ldma_msgstr is set, a valid data response was seen.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_ldma_msgstr == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen err = ENODATA;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen else {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (*v12n_ldma_msgstr == '\0' ||
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (*strp = strdup(v12n_ldma_msgstr)) == NULL)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen err = ENODATA;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen free(v12n_ldma_msgstr);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_msgstr = NULL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensendone:
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ds_unreg_svc(LDMA_NAME_SYSTEM, B_TRUE);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_msgtype = -1;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen v12n_ldma_ctrl_hdl = DS_INVALID_HDL;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen (void) mutex_unlock(&v12n_ldma_lock);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (err);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the nodename of the control domain. Returns the equivalent
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * of 'uname -n' on the control domain.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * This is obtained via the 'agent-system' domain service provided
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * by ldmad.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensensize_t
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_ctrl_domain(char *buf, size_t count)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *str;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int err;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen size_t rv = (size_t)(-1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ENOTSUP;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if ((err = v12n_get_ldma_system_msg(LDMA_MSGSYS_GET_SYSINFO,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &str)) != 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = err;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = v12n_string_copyout(buf, str, count);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen/*
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * Get the Chassis serial number from the Control Domain.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * This is obtained via the 'agent-system' domain service provided
82629e3015252bf18319ba3815c773df23e21436Mike Christensen * by ldmad.
82629e3015252bf18319ba3815c773df23e21436Mike Christensen */
82629e3015252bf18319ba3815c773df23e21436Mike Christensensize_t
82629e3015252bf18319ba3815c773df23e21436Mike Christensenv12n_chassis_serialno(char *buf, size_t count)
82629e3015252bf18319ba3815c773df23e21436Mike Christensen{
82629e3015252bf18319ba3815c773df23e21436Mike Christensen char *str;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen int err;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen size_t rv = (size_t)(-1);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen
82629e3015252bf18319ba3815c773df23e21436Mike Christensen if (v12n_capabilities() != V12N_LDOMS_SUPPORTED) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = ENOTSUP;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else if ((err = v12n_get_ldma_system_msg(LDMA_MSGSYS_GET_CHASSISNO,
82629e3015252bf18319ba3815c773df23e21436Mike Christensen &str)) != 0) {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen errno = err;
82629e3015252bf18319ba3815c773df23e21436Mike Christensen } else {
82629e3015252bf18319ba3815c773df23e21436Mike Christensen rv = v12n_string_copyout(buf, str, count);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen }
82629e3015252bf18319ba3815c773df23e21436Mike Christensen return (rv);
82629e3015252bf18319ba3815c773df23e21436Mike Christensen}