diff options
author | Alexandre Chartre <Alexandre.Chartre@Sun.COM> | 2009-09-09 16:49:57 -0700 |
---|---|---|
committer | Alexandre Chartre <Alexandre.Chartre@Sun.COM> | 2009-09-09 16:49:57 -0700 |
commit | 49bfb42b00abac0958a1308f4233e366fd083366 (patch) | |
tree | 0de0400b1b0b1b2b6fc2d23632b73a951d4769ad | |
parent | 5f964b32847bbf776eb679b1688c38a4c7c31877 (diff) | |
download | illumos-joyent-49bfb42b00abac0958a1308f4233e366fd083366.tar.gz |
FWARC 2009/426 Logical Domains Agents
PSARC 2009/459 Logical Domains Agents on Solaris
6813200 Logical Domains Agents
6669994 Add a domain service to support OS identification - solaris
-rw-r--r-- | usr/src/Makefile.lint | 1 | ||||
-rw-r--r-- | usr/src/cmd/Makefile | 1 | ||||
-rw-r--r-- | usr/src/cmd/Makefile.check | 1 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/Makefile | 67 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldma.h | 167 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldma_device.c | 287 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldma_log.c | 154 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldma_system.c | 128 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldmad.c | 558 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldoms-agents | 80 | ||||
-rw-r--r-- | usr/src/cmd/ldmad/ldoms-agents.xml | 85 | ||||
-rw-r--r-- | usr/src/cmd/svc/profile/platform_sun4v.xml | 37 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWldomr.v/prototype_sparc | 2 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWldomu.v/prototype_sparc | 3 | ||||
-rw-r--r-- | usr/src/tools/scripts/bfu.sh | 5 |
15 files changed, 1557 insertions, 19 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index b2872fbe54..480dd36483 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -484,6 +484,7 @@ sparc_SUBDIRS= \ cmd/drd \ cmd/fps \ cmd/fruadm \ + cmd/ldmad \ cmd/prtdscp \ cmd/prtfru \ cmd/sckmd \ diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index f7684de607..dffdf532db 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -498,6 +498,7 @@ sparc_SUBDIRS= \ drd \ fps \ fruadm \ + ldmad \ oplhpd \ prtdscp \ prtfru \ diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index b6c3b8a7cc..de191712d2 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -49,6 +49,7 @@ MANIFEST_TOPDIRS= \ kbd \ keyserv \ ldapcachemgr \ + ldmad \ lms \ mms \ dlmgmtd \ diff --git a/usr/src/cmd/ldmad/Makefile b/usr/src/cmd/ldmad/Makefile new file mode 100644 index 0000000000..1db449789c --- /dev/null +++ b/usr/src/cmd/ldmad/Makefile @@ -0,0 +1,67 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= ldmad +MANIFEST= ldoms-agents.xml +SVCMETHOD= ldoms-agents + +include ../Makefile.cmd + +SRCS= ldmad.c \ + ldma_log.c \ + ldma_device.c \ + ldma_system.c + + +OBJS= $(SRCS:%.c=%.o) + +ROOTCMDDIR= $(ROOTLIB)/ldoms +ROOTMANIFESTDIR= $(ROOTSVCPLATFORMSUN4V) +$(ROOTMANIFEST) := FILEMODE= 444 + +LDLIBS += -lds -ldladm +INCS += -I$(ROOT)/usr/platform/sun4v/include/sys +CPPFLAGS += $(INCS) +C99MODE = $(C99_ENABLE) + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS) + $(POST_PROCESS) + +install: all .WAIT $(ROOTCMD) $(ROOTMANIFEST) $(ROOTSVCMETHOD) + +check: $(CHKMANIFEST) + +lint: lint_SRCS + +clean: + $(RM) $(PROG) $(OBJS) $(LINT_FILES) + +include ../Makefile.targ diff --git a/usr/src/cmd/ldmad/ldma.h b/usr/src/cmd/ldmad/ldma.h new file mode 100644 index 0000000000..92abc954ee --- /dev/null +++ b/usr/src/cmd/ldmad/ldma.h @@ -0,0 +1,167 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LDMA_H +#define _LDMA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libds.h> +#include <sys/sysmacros.h> +#include <sys/types.h> + +/* + * The following definitions are part of the LDoms Agent specification. + */ + +/* reply message types */ +#define LDMA_MSG_RESULT 0x8000 /* result message */ +#define LDMA_MSG_ERROR 0x8001 /* error message */ + +/* error codes for error messages */ +#define LDMA_MSGERR_FAIL 0x0000 /* request has failed */ +#define LDMA_MSGERR_INVALID 0x8001 /* request is invalid */ +#define LDMA_MSGERR_NOTSUP 0x8002 /* request is not supported */ +#define LDMA_MSGERR_DENY 0x8003 /* request is denied */ + +/* + * LDoms Device Agent + */ +#define LDMA_NAME_DEVICE "agent-device" + +#define LDMA_MSGDEV_VALIDATE_PATH 0x01 /* validate path */ +#define LDMA_MSGDEV_VALIDATE_NIC 0x02 /* validate network interface */ + +#define LDMA_DEVPATH_EXIST 0x01 /* path is accessible */ +#define LDMA_DEVPATH_OPENRW 0x02 /* path can be opened rw */ +#define LDMA_DEVPATH_OPENRO 0x04 /* path can be opened ro */ + +#define LDMA_DEVPATH_TYPE_UNKNOWN 0x00 /* path points to unknown */ +#define LDMA_DEVPATH_TYPE_FILE 0x01 /* path points to a file */ +#define LDMA_DEVPATH_TYPE_DEVICE 0x02 /* path points to a device */ + +#define LDMA_DEVNIC_EXIST 0x01 /* nic is accessible */ + +/* + * LDoms System Agent + */ +#define LDMA_NAME_SYSTEM "agent-system" + +#define LDMA_MSGSYS_GET_SYSINFO 0x01 /* get system info request */ + +/* + * Size of the header of an agent message. This is the minimal size that + * a message can have. + */ +#define LDMA_MESSAGE_HEADER_SIZE (sizeof (ldma_message_header_t)) + +/* + * Macro to compute the size of a message with a msg_data of size dlen. + * The size of the msg_data field must be a multiple of 8-bytes so dlen + * is roundup to an 8-bytes multiple. + */ +#define LDMA_MESSAGE_SIZE(dlen) (LDMA_MESSAGE_HEADER_SIZE + P2ROUNDUP(dlen, 8)) + +/* + * Macro to compute the size of the msg_data field from the size of the message. + */ +#define LDMA_MESSAGE_DLEN(msgsize) ((msgsize) - LDMA_MESSAGE_HEADER_SIZE) + +/* + * Handy macros for using the message and header structures. + */ +#define LDMA_HDR2MSG(hdr) ((ldma_message_t *)(hdr)) +#define LDMA_HDR2DATA(hdr) (LDMA_HDR2MSG(hdr)->msg_data) +#define LDMA_MSG2HDR(msg) ((ldma_message_header_t *)(msg)) + +/* agent message header structure */ +typedef struct ldma_message_header { + uint64_t msg_num; /* message number */ + uint32_t msg_type; /* message type */ + uint32_t msg_info; /* message info */ +} ldma_message_header_t; + +/* agent message structure */ +typedef struct ldma_message { + ldma_message_header_t msg_hdr; /* message header */ + char msg_data[1]; /* message data */ +} ldma_message_t; + +/* + * Additional structures and definition for the implementation. + */ +typedef enum ldma_request_status_t { + LDMA_REQ_COMPLETED, /* request was completed */ + LDMA_REQ_FAILED, /* request has failed */ + LDMA_REQ_INVALID, /* request is invalid */ + LDMA_REQ_NOTSUP, /* request is not supported */ + LDMA_REQ_DENIED /* request was denied */ +} ldma_request_status_t; + +typedef ldma_request_status_t (ldm_msg_func_t)(ds_ver_t *, + ldma_message_header_t *, size_t, ldma_message_header_t **, size_t *); + +typedef struct ldma_msg_handler { + uint32_t msg_type; /* message type */ + ldm_msg_func_t *msg_handler; /* message handler */ +} ldma_msg_handler_t; + +typedef struct ldma_agent_info { + char *name; /* agent name */ + ds_ver_t *vers; /* supported versions */ + int nvers; /* number of versions */ + ldma_msg_handler_t *handlers; /* message handlers */ + int nhandlers; /* number of handlers */ +} ldma_agent_info_t; + +/* + * Helper functions for the daemon and agents. + */ + +/* function to allocate a result message */ +ldma_message_header_t *ldma_alloc_result_msg(ldma_message_header_t *, size_t); + +/* functions to log messages */ +void ldma_err(char *module, char *fmt, ...); +void ldma_info(char *module, char *fmt, ...); +void ldma_dbg(char *module, char *fmt, ...); + +/* + * Macros to log messages. Each module/file using these macros should define + * LDMA_MODULE as the name under which messages are logged. For a given agent, + * LDMA_MODULE should be set to the name of the agent. + */ +#define LDMA_ERR(...) ldma_err(LDMA_MODULE, __VA_ARGS__) +#define LDMA_INFO(...) ldma_info(LDMA_MODULE, __VA_ARGS__) +#define LDMA_DBG(...) ldma_dbg(LDMA_MODULE, __VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif /* _LDMA_H */ diff --git a/usr/src/cmd/ldmad/ldma_device.c b/usr/src/cmd/ldmad/ldma_device.c new file mode 100644 index 0000000000..94e4831262 --- /dev/null +++ b/usr/src/cmd/ldmad/ldma_device.c @@ -0,0 +1,287 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Logical Domains Device Agent + */ + +#include <errno.h> +#include <fcntl.h> +#include <libdladm.h> +#include <libdllink.h> +#include <libds.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "ldma.h" + +#define LDMA_MODULE LDMA_NAME_DEVICE + +#define LDMA_NVERSIONS (sizeof (ldma_versions) / sizeof (ds_ver_t)) +#define LDMA_NHANDLERS (sizeof (ldma_handlers) / sizeof (ldma_msg_handler_t)) + +static ldm_msg_func_t ldma_dev_validate_path; +static ldm_msg_func_t ldma_dev_validate_nic; + +static ds_ver_t ldma_versions[] = { { 1, 0 } }; + +static ldma_msg_handler_t ldma_handlers[] = { + { LDMA_MSGDEV_VALIDATE_PATH, ldma_dev_validate_path }, + { LDMA_MSGDEV_VALIDATE_NIC, ldma_dev_validate_nic } +}; + +ldma_agent_info_t ldma_device_info = { + LDMA_NAME_DEVICE, + ldma_versions, LDMA_NVERSIONS, + ldma_handlers, LDMA_NHANDLERS +}; + +/*ARGSUSED*/ +static ldma_request_status_t +ldma_dev_validate_path(ds_ver_t *ver, ldma_message_header_t *request, + size_t request_dlen, ldma_message_header_t **replyp, size_t *reply_dlenp) +{ + ldma_message_header_t *reply = NULL; + ldma_request_status_t status; + struct stat st; + char *path = NULL; + uint32_t *path_type, reply_dlen; + uint32_t plen; + int fd; + + plen = request->msg_info; + if (plen == 0 || plen > MAXPATHLEN || plen > request_dlen) { + status = LDMA_REQ_INVALID; + goto done; + } + + path = malloc(plen + 1); + if (path == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + (void) strncpy(path, LDMA_HDR2DATA(request), plen); + path[plen] = '\0'; + + LDMA_DBG("VALIDATE_PATH(%s)", path); + + reply_dlen = sizeof (uint32_t); + reply = ldma_alloc_result_msg(request, reply_dlen); + if (reply == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + /* LINTED E_BAD_PTR_CAST_ALIGN */ + path_type = (uint32_t *)(LDMA_HDR2DATA(reply)); + + reply->msg_info = 0x0; + + /* check if path exists */ + if (stat(path, &st) != 0) { + + LDMA_DBG("VALIDATE_PATH(%s): stat failed with error %d", + path, errno); + + switch (errno) { + + case EACCES: + case ELOOP: + case ENOENT: + case ENOLINK: + case ENOTDIR: + /* path is inaccessible, the request is completed */ + status = LDMA_REQ_COMPLETED; + break; + + case ENAMETOOLONG: + status = LDMA_REQ_INVALID; + break; + + default: + /* request has failed */ + status = LDMA_REQ_FAILED; + break; + } + + goto done; + } + + status = LDMA_REQ_COMPLETED; + + reply->msg_info |= LDMA_DEVPATH_EXIST; + + LDMA_DBG("VALIDATE_PATH(%s): file mode = 0x%x", path, st.st_mode); + + switch (st.st_mode & S_IFMT) { + + case S_IFREG: + *path_type = LDMA_DEVPATH_TYPE_FILE; + break; + + case S_IFCHR: + case S_IFBLK: + *path_type = LDMA_DEVPATH_TYPE_DEVICE; + break; + + default: + /* we don't advertise other types (fifo, directory...) */ + *path_type = 0; + } + + /* check if path can be opened read/write */ + if ((fd = open(path, O_RDWR)) != -1) { + reply->msg_info |= LDMA_DEVPATH_OPENRW | LDMA_DEVPATH_OPENRO; + (void) close(fd); + } else { + LDMA_DBG("VALIDATE_PATH(%s): open RDWR failed with error %d", + path, errno); + + /* check if path can be opened read only */ + if ((fd = open(path, O_RDONLY)) != -1) { + reply->msg_info |= LDMA_DEVPATH_OPENRO; + (void) close(fd); + } else { + LDMA_DBG("VALIDATE_PATH(%s): open RDONLY failed " + "with error %d", path, errno); + } + } + +done: + if (status != LDMA_REQ_COMPLETED) { + /* + * We don't provide a reply message if the request has not + * been completed. The LDoms agent daemon will send an + * appropriate reply based on the return code of this function. + */ + free(reply); + reply = NULL; + reply_dlen = 0; + + LDMA_DBG("VALIDATE_PATH(%s): return error %d", + (path)? path : "<none>", status); + } else { + LDMA_DBG("VALIDATE_PATH(%s): return status=0x%x type=0x%x", + path, reply->msg_info, *path_type); + } + + free(path); + *replyp = reply; + *reply_dlenp = reply_dlen; + + return (status); +} + +/* + * We check that the device is a network interface (NIC) using libdladm. + */ +/*ARGSUSED*/ +static ldma_request_status_t +ldma_dev_validate_nic(ds_ver_t *ver, ldma_message_header_t *request, + size_t request_dlen, ldma_message_header_t **replyp, size_t *reply_dlenp) +{ + dladm_handle_t dlhandle; + datalink_id_t linkid; + uint32_t flag, media; + datalink_class_t class; + ldma_message_header_t *reply = NULL; + ldma_request_status_t status; + char *nic = NULL; + uint32_t nlen, reply_dlen; + + nlen = request->msg_info; + if (nlen == 0 || nlen > MAXPATHLEN || nlen > request_dlen) { + status = LDMA_REQ_INVALID; + goto done; + } + + nic = malloc(nlen + 1); + if (nic == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + (void) strncpy(nic, LDMA_HDR2DATA(request), nlen); + nic[nlen] = '\0'; + + LDMA_DBG("VALIDATE_NIC(%s)", nic); + + reply_dlen = 0; + reply = ldma_alloc_result_msg(request, reply_dlen); + if (reply == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + reply->msg_info = 0x0; + + if (dladm_open(&dlhandle) != DLADM_STATUS_OK) { + status = LDMA_REQ_FAILED; + goto done; + } + + if (dladm_name2info(dlhandle, nic, &linkid, &flag, &class, + &media) != DLADM_STATUS_OK) { + LDMA_DBG("VALIDATE_NIC(%s): name2info failed", nic); + } else { + LDMA_DBG("VALIDATE_NIC(%s): media=0x%x", nic, media); + reply->msg_info = LDMA_DEVNIC_EXIST; + } + + dladm_close(dlhandle); + + status = LDMA_REQ_COMPLETED; + +done: + if (status != LDMA_REQ_COMPLETED) { + /* + * We don't provide a reply message if the request has not + * been completed. The LDoms agent daemon will send an + * appropriate reply based on the return code of this function. + */ + free(reply); + reply = NULL; + reply_dlen = 0; + + LDMA_DBG("VALIDATE_NIC(%s): return error %d", + (nic)? nic : "<none>", status); + } else { + LDMA_DBG("VALIDATE_NIC(%s): return status=0x%x", + nic, reply->msg_info); + } + + free(nic); + *replyp = reply; + *reply_dlenp = reply_dlen; + + return (status); +} diff --git a/usr/src/cmd/ldmad/ldma_log.c b/usr/src/cmd/ldmad/ldma_log.c new file mode 100644 index 0000000000..ca5e423207 --- /dev/null +++ b/usr/src/cmd/ldmad/ldma_log.c @@ -0,0 +1,154 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Logging support for the LDoms Agent daemon + */ + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <syslog.h> +#include <sys/types.h> + +#define LDMA_MAX_MSG_LEN 512 +#define LDMA_MAX_TIME_LEN 32 + +extern boolean_t ldma_debug; +extern boolean_t ldma_daemon; + +static char *log_prio_str[] = { + "EMERG", /* LOG_EMERG */ + "ALERT", /* LOG_ALERT */ + "CRIT", /* LOG_CRIT */ + "ERROR", /* LOG_ERR */ + "WARNING", /* LOG_WARNING */ + "NOTICE", /* LOG_NOTICE */ + "INFO", /* LOG_INFO */ + "DEBUG" /* LOG_DEBUG */ +}; + +/* + * Generate a timestamp string in the provided buffer. + * If any errors are encountered, the function returns + * with the buffer containing an empty string. + */ +static void +ldma_timestamp(char *buf, size_t buflen) +{ + struct tm ltime; + struct timeval now; + + if ((buf == NULL) || (buflen == 0)) + return; + + buf[0] = '\0'; + + if (gettimeofday(&now, NULL) != 0) { + (void) fprintf(stderr, "gettimeofday failed: %s\n", + strerror(errno)); + return; + } + + if (localtime_r(&now.tv_sec, <ime) == NULL) { + (void) fprintf(stderr, "localtime_r failed: %s\n", + strerror(errno)); + return; + } + + if (strftime(buf, buflen, "%b %e %T ", <ime) == 0) { + (void) fprintf(stderr, "strftime failed: buffer[%d] too " + "small\n", buflen); + /* + * On failure, the contents of the buffer + * are indeterminate. Restore it to a known + * state before returning. + */ + buf[0] = '\0'; + } +} + +static void +ldma_log_msg(int prio, char *module, char *fmt, va_list vap) +{ + char msgbuf[LDMA_MAX_MSG_LEN]; + char timebuf[LDMA_MAX_TIME_LEN] = ""; + + /* generate a timestamp for the SMF log */ + ldma_timestamp(timebuf, sizeof (timebuf)); + + /* LINTED E_SEC_PRINTF_VAR_FMT */ + (void) vsnprintf(msgbuf, LDMA_MAX_MSG_LEN, fmt, vap); + + /* + * Print the message to stderr. In daemon mode, it + * will be sent to the SMF log. In standalone mode, + * it will be sent to the controlling terminal. + */ + (void) fprintf(stderr, "%s%s.%s: %s\n", timebuf, module, + log_prio_str[prio], msgbuf); + + if (ldma_daemon && prio != LOG_DEBUG) { + /* LINTED E_SEC_PRINTF_VAR_FMT */ + syslog(prio, msgbuf); + } +} + +void +ldma_err(char *module, char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + ldma_log_msg(LOG_ERR, module, fmt, vap); + va_end(vap); +} + +void +ldma_info(char *module, char *fmt, ...) +{ + va_list vap; + + va_start(vap, fmt); + ldma_log_msg(LOG_INFO, module, fmt, vap); + va_end(vap); +} + +void +ldma_dbg(char *module, char *fmt, ...) +{ + va_list vap; + + if (!ldma_debug) { + /* not debugging */ + return; + } + + va_start(vap, fmt); + ldma_log_msg(LOG_DEBUG, module, fmt, vap); + va_end(vap); +} diff --git a/usr/src/cmd/ldmad/ldma_system.c b/usr/src/cmd/ldmad/ldma_system.c new file mode 100644 index 0000000000..1db750e650 --- /dev/null +++ b/usr/src/cmd/ldmad/ldma_system.c @@ -0,0 +1,128 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Logical Domains System Agent + */ + +#include <errno.h> +#include <libds.h> +#include <stdio.h> +#include <strings.h> +#include <sys/utsname.h> + +#include "ldma.h" + +#define LDMA_MODULE LDMA_NAME_SYSTEM + +#define LDMA_NVERSIONS (sizeof (ldma_versions) / sizeof (ds_ver_t)) +#define LDMA_NHANDLERS (sizeof (ldma_handlers) / sizeof (ldma_msg_handler_t)) + +static ldm_msg_func_t ldma_sys_get_sysinfo; + +static ds_ver_t ldma_versions[] = { { 1, 0 } }; + +static ldma_msg_handler_t ldma_handlers[] = { + { LDMA_MSGSYS_GET_SYSINFO, ldma_sys_get_sysinfo } +}; + +ldma_agent_info_t ldma_system_info = { + LDMA_NAME_SYSTEM, + ldma_versions, LDMA_NVERSIONS, + ldma_handlers, LDMA_NHANDLERS +}; + +/*ARGSUSED*/ +static ldma_request_status_t +ldma_sys_get_sysinfo(ds_ver_t *ver, ldma_message_header_t *request, + size_t request_dlen, ldma_message_header_t **replyp, size_t *reply_dlenp) +{ + ldma_message_header_t *reply; + struct utsname name; + size_t syslen, nodlen, rellen, maclen, verlen; + size_t rlen; + char *data; + int status; + + LDMA_DBG("GET_SYSINFO"); + + if (request->msg_info != 0 || request_dlen != 0) { + status = LDMA_REQ_INVALID; + goto done; + } + + if (uname(&name) == -1) { + LDMA_DBG("GET_SYSINFO: uname failed with error %d", errno); + status = LDMA_REQ_FAILED; + goto done; + } + + syslen = strlen(name.sysname) + 1; + nodlen = strlen(name.nodename) + 1; + rellen = strlen(name.release) + 1; + verlen = strlen(name.version) + 1; + maclen = strlen(name.machine) + 1; + + rlen = syslen + nodlen + rellen + verlen + maclen; + + reply = ldma_alloc_result_msg(request, rlen); + + if (reply == NULL) { + status = LDMA_REQ_FAILED; + goto done; + } + + reply->msg_info = rlen; + + data = LDMA_HDR2DATA(reply); + + (void) strcpy(data, name.sysname); + data += syslen; + + (void) strcpy(data, name.nodename); + data += nodlen; + + (void) strcpy(data, name.release); + data += rellen; + + (void) strcpy(data, name.version); + data += verlen; + + (void) strcpy(data, name.machine); + + LDMA_DBG("GET_SYSINFO: return info=%u, {%s, %s, %s, %s, %s}", rlen, + name.sysname, name.nodename, name.release, name.version, + name.machine); + + *replyp = reply; + *reply_dlenp = rlen; + + return (LDMA_REQ_COMPLETED); + +done: + LDMA_DBG("GET_SYSINFO: return error %d", status); + return (status); +} diff --git a/usr/src/cmd/ldmad/ldmad.c b/usr/src/cmd/ldmad/ldmad.c new file mode 100644 index 0000000000..2403cd2cd7 --- /dev/null +++ b/usr/src/cmd/ldmad/ldmad.c @@ -0,0 +1,558 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Logical Domains (LDoms) Agents Daemon + * + * The LDoms agents daemon (ldmad) runs on LDoms domains and provides + * information to the control domain. It is composed of a set of agents + * which can send and receive messages to and from the control domain. + * Each agent is registered as a domain service using the libds library, + * and is able to handle requests coming from the control domain. + * + * The control domain sends requests to an agent as messages on the + * corresponding domain service (identified by the agent name). All requests + * are received by the ldmad daemon which dispatches them to the appropriate + * handler function of the agent depending on the type of the message. + * + * After the request has been processed by the handler, the ldmad daemon sent + * a reply message back to the control domain. The reply is either a result + * message if the request was successfully completed, or an error message + * describing the failure. + */ + +#include <dirent.h> +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <link.h> +#include <libds.h> +#include <libgen.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <syslog.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include "ldma.h" + +#define LDMA_MODULE "ldm-agent-daemon" + +#define LDMA_CONTROL_DOMAIN_DHDL 0 /* id of the control domain */ +#define LDMA_DOMAIN_NAME_MAXLEN MAXNAMELEN + +typedef struct ldma_agent { + ldma_agent_info_t *info; /* agent information */ + ds_hdl_t conn_hdl; /* connexion handler */ + ds_ver_t conn_ver; /* connexion version */ +} ldma_agent_t; + +/* information about existing agents */ +extern ldma_agent_info_t ldma_device_info; +extern ldma_agent_info_t ldma_system_info; + +boolean_t ldma_debug = B_FALSE; +boolean_t ldma_daemon = B_FALSE; + +static ldma_agent_info_t *ldma_agent_infos[] = { + &ldma_device_info, + &ldma_system_info, + NULL +}; + +static char *cmdname; +static pid_t daemon_pid; + +/* + * Allocate a new message with the specified message number (msg_num), + * message type (msg_type) and message data length (msg_dlen). Return + * NULL if the allocation has failed. + */ +static ldma_message_header_t * +ldma_alloc_msg(uint64_t msg_num, uint32_t msg_type, size_t msg_dlen) +{ + ldma_message_header_t *msg; + size_t msg_len; + + msg_len = LDMA_MESSAGE_SIZE(msg_dlen); + msg = malloc(msg_len); + if (msg == NULL) + return (NULL); + + msg->msg_num = msg_num; + msg->msg_type = msg_type; + msg->msg_info = 0; + + return (msg); +} + +/* + * Allocate a result message (LDMA_MSG_REQ_RESULT) with the specified message + * data length (msg_dlen). If the request argument is not NULL then the message + * is created with the same message number as the request, otherwise the message + * number is set to 0. Return NULL if the allocation has failed. + */ +ldma_message_header_t * +ldma_alloc_result_msg(ldma_message_header_t *request, size_t msg_dlen) +{ + uint64_t msg_num; + + msg_num = (request == NULL)? 0 : request->msg_num; + + return (ldma_alloc_msg(msg_num, LDMA_MSG_RESULT, msg_dlen)); +} + +/* + * Agent register callback. This callback is invoked when a client is registered + * for using the service provided by an agent. An agent will only have one + * consumer which is coming from the control domain. + */ +static void +ldma_reg_cb(ds_hdl_t hdl, ds_cb_arg_t arg, ds_ver_t *ver, + ds_domain_hdl_t dhdl) +{ + ldma_agent_t *agent = (ldma_agent_t *)arg; + char dname[LDMA_DOMAIN_NAME_MAXLEN]; + + if (ds_dom_hdl_to_name(dhdl, dname, LDMA_DOMAIN_NAME_MAXLEN) != 0) { + (void) strcpy(dname, "<unknown>"); + } + + LDMA_DBG("%s: REGISTER hdl=%llx, dhdl=%llx (%s) ver=%hd.%hd", + agent->info->name, hdl, dhdl, dname, ver->major, ver->minor); + + /* + * Record client information if the connexion is from the control + * domain. The domain service framework only allows connexion of a + * domain with the control domain. However, if the agent is running + * on the control domain then it can see connexions coming from any + * domains. That's why we explicitly have to check if the connexion + * is effectively with the control domain. + */ + if (dhdl == LDMA_CONTROL_DOMAIN_DHDL) { + agent->conn_hdl = hdl; + agent->conn_ver.major = ver->major; + agent->conn_ver.minor = ver->minor; + } else { + LDMA_INFO("agent %s will ignore any request from distrusted " + "domain %s", agent->info->name, dname); + } +} + +/* + * Agent unregister callback. This callback is invoked when a client is + * unregistered and stops using the service provided by an agent. + */ +static void +ldma_unreg_cb(ds_hdl_t hdl, ds_cb_arg_t arg) +{ + ldma_agent_t *agent = (ldma_agent_t *)arg; + + LDMA_DBG("%s: UNREGISTER hdl=%llx", agent->info->name, hdl); + + if (agent->conn_hdl == hdl) { + agent->conn_hdl = 0; + agent->conn_ver.major = 0; + agent->conn_ver.minor = 0; + } else { + LDMA_INFO("agent %s has unregistered consumer from " + "distrusted domain", agent->info->name); + } +} + +/* + * Agent data callback. This callback is invoked when an agent receives a new + * message from a client. Any request from a client which is not the control + * domain is immediatly rejected. Otherwise the message is forwarded to the + * appropriate handler function provided by the agent, depending on the message + * type. + */ +static void +ldma_data_cb(ds_hdl_t hdl, ds_cb_arg_t arg, void *buf, size_t len) +{ + ldma_agent_t *agent = (ldma_agent_t *)arg; + ldma_msg_handler_t *handler; + ldma_message_header_t *request = buf; + ldma_message_header_t *reply = NULL; + ldma_request_status_t status; + size_t request_dlen, reply_len, reply_dlen = 0; + int i; + + /* check the message size */ + if (len < LDMA_MESSAGE_HEADER_SIZE) { + LDMA_INFO("agent %s has ignored message with an invalid " + "size of %d bytes", agent->info->name, len); + return; + } + + request_dlen = LDMA_MESSAGE_DLEN(len); + + LDMA_DBG("%s: DATA hdl=%llx, request num=%llu type=0x%x info=0x%x " + "dlen=%d", agent->info->name, hdl, request->msg_num, + request->msg_type, request->msg_info, request_dlen); + + /* reject any request which is not from the control domain */ + if (hdl != agent->conn_hdl) { + LDMA_DBG("%s: DATA hdl=%llx, rejecting request from a " + "distrusted domain", agent->info->name, hdl); + status = LDMA_REQ_DENIED; + goto do_reply; + } + + handler = NULL; + + for (i = 0; i < agent->info->nhandlers; i++) { + if (agent->info->handlers[i].msg_type == request->msg_type) { + handler = &agent->info->handlers[i]; + break; + } + } + + if (handler == NULL) { + /* this type of message is not defined by the agent */ + LDMA_DBG("%s: DATA hdl=%llx, unknown message type %x", + agent->info->name, hdl, request->msg_type); + status = LDMA_REQ_NOTSUP; + goto do_reply; + } + + if (handler->msg_handler == NULL) { + /* + * This type of message is defined by the agent but it + * has no handler. That means there is no processing to + * do, the message is just ignored, but the request is + * successfully completed. + */ + LDMA_DBG("%s: DATA hdl=%llx, no handler", + agent->info->name, hdl); + status = LDMA_REQ_COMPLETED; + goto do_reply; + } + + /* invoke the message handler of the agent */ + status = (*handler->msg_handler)(&agent->conn_ver, request, + request_dlen, &reply, &reply_dlen); + + LDMA_DBG("%s: DATA hdl=%llx, handler stat=%d reply=%p rlen=%d", + agent->info->name, hdl, status, (void *)reply, reply_dlen); + +do_reply: + /* + * If the handler has provided a reply message, we use it directly. + * Otherwise, we build a reply depending on the status of the request. + * In that case, we re-use the request buffer to build the reply + * message. + */ + if (reply == NULL) { + + reply = request; + reply_dlen = 0; + + if (status == LDMA_REQ_COMPLETED) { + /* + * The request was successful but no result message was + * provided so we send an empty result message. + */ + reply->msg_type = LDMA_MSG_RESULT; + reply->msg_info = 0; + + } else { + /* + * The request has failed but no error message was + * provided so we send an error message based on the + * request status. + */ + reply->msg_type = LDMA_MSG_ERROR; + reply->msg_info = + (status == LDMA_REQ_NOTSUP)? LDMA_MSGERR_NOTSUP : + (status == LDMA_REQ_INVALID)? LDMA_MSGERR_INVALID : + (status == LDMA_REQ_DENIED)? LDMA_MSGERR_DENY : + LDMA_MSGERR_FAIL; + } + } + + reply_len = LDMA_MESSAGE_SIZE(reply_dlen); + + LDMA_DBG("%s: DATA hdl=%llx, reply num=%llu type=0x%x info=0x%x " + "dlen=%d", agent->info->name, hdl, reply->msg_num, + reply->msg_type, reply->msg_info, reply_dlen); + + if (ds_send_msg(hdl, reply, reply_len) != 0) { + LDMA_ERR("agent %s has failed to send reply for request %llu", + agent->info->name, request->msg_num); + } + + if (reply != request) + free(reply); +} + +/* + * Register an agent. Return 0 if the agent was successfully registered. + */ +static int +ldma_register(ldma_agent_info_t *agent_info) +{ + ldma_agent_t *agent; + ds_capability_t ds_cap; + ds_ops_t ds_ops; + + agent = malloc(sizeof (ldma_agent_t)); + if (agent == NULL) + goto register_fail; + + agent->info = agent_info; + agent->conn_hdl = 0; + agent->conn_ver.major = 0; + agent->conn_ver.minor = 0; + + ds_cap.svc_id = agent_info->name; + ds_cap.vers = agent_info->vers; + ds_cap.nvers = agent_info->nvers; + + ds_ops.ds_reg_cb = ldma_reg_cb; + ds_ops.ds_unreg_cb = ldma_unreg_cb; + ds_ops.ds_data_cb = ldma_data_cb; + ds_ops.cb_arg = agent; + + if (ds_svc_reg(&ds_cap, &ds_ops) == 0) { + LDMA_INFO("agent %s registered", agent_info->name); + return (0); + } + +register_fail: + + LDMA_ERR("agent %s has failed to register", agent_info->name); + free(agent); + return (-1); +} + +/* + * Register all known agents. Return the number of agents successfully + * registered. + */ +static int +ldma_register_agents() +{ + int count = 0; + ldma_agent_info_t **agent_infop; + + for (agent_infop = ldma_agent_infos; + *agent_infop != NULL; agent_infop++) { + + if (ldma_register(*agent_infop) == 0) + count++; + } + + return (count); +} + +/*ARGSUSED*/ +static void +ldma_sigusr_handler(int sig, siginfo_t *sinfo, void *ucontext) +{ + if (daemon_pid <= 0 || sig != SIGUSR1 || sinfo->si_code != SI_USER || + sinfo->si_pid != daemon_pid) + return; + + /* + * The parent process has received a USR1 signal from the child. + * This means that the daemon has correctly started and the parent + * can exit. + */ + exit(0); +} + +static void +ldma_start(boolean_t standalone) +{ + int stat, rv; + struct sigaction action; + + if (!standalone) { + /* + * Some configuration of the daemon has to be done in the + * child, but we want the parent to report if the daemon + * has successfully started or not. So we setup a signal + * handler, and the child will notify the parent using the + * USR1 signal if the setup was successful. Otherwise the + * child will exit. + */ + action.sa_sigaction = ldma_sigusr_handler; + action.sa_flags = SA_SIGINFO; + + if (sigemptyset(&action.sa_mask) == -1) { + LDMA_ERR("sigemptyset error (%d)", errno); + exit(1); + } + + if (sigaction(SIGUSR1, &action, NULL) == -1) { + LDMA_ERR("sigaction() error (%d)", errno); + exit(1); + } + + if (sigrelse(SIGUSR1) == -1) { + LDMA_ERR("sigrelse() error (%d)", errno); + exit(1); + } + + if ((daemon_pid = fork()) == -1) { + LDMA_ERR("fork() error (%d)", errno); + exit(1); + } + + if (daemon_pid != 0) { + /* + * The parent process waits until the child exits (in + * case of an error) or sends a USR1 signal (if the + * daemon has correctly started). + */ + for (;;) { + rv = waitpid(daemon_pid, &stat, 0); + if ((rv == daemon_pid && WIFEXITED(stat)) || + (rv == -1 && errno != EINTR)) { + /* child has exited or error */ + exit(1); + } + } + } + + /* + * Initialize child process + */ + if (sighold(SIGUSR1) == -1) { + LDMA_ERR("sighold error (%d)", errno); + exit(1); + } + + if (sigignore(SIGUSR1) == -1) { + LDMA_ERR("sigignore error (%d)", errno); + exit(1); + } + + if (setsid() == -1) { + LDMA_ERR("setsid error (%d)", errno); + exit(1); + } + + if (chdir("/") == -1) { + LDMA_ERR("chdir error (%d)", errno); + exit(1); + } + (void) umask(0); + + /* + * Initialize file descriptors. Do not touch stderr + * which is initialized by SMF to point to the daemon + * specific log file. + */ + (void) close(STDIN_FILENO); + if (open("/dev/null", O_RDWR) == -1) { + LDMA_ERR("open /dev/null error (%d)", errno); + exit(1); + } + if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1) { + LDMA_ERR("dup2 error (%d)", errno); + exit(1); + } + closefrom(STDERR_FILENO + 1); + + /* initialize logging */ + openlog(cmdname, LOG_CONS | LOG_NDELAY, LOG_DAEMON); + + ldma_daemon = B_TRUE; + } + + /* + * Register the agents. It would be easier to do this before + * daemonizing so that any start error is directly reported. But + * this can not be done because agents are registered using libds + * and this will subscribe the daemon to some sysevents which is + * a process based subscription. Instead we notify the parent process + * either by exiting, or by sending a SIGUSR1 signal. + */ + if (ldma_register_agents() == 0) { + /* no agent registered */ + LDMA_ERR("Unable to register any agent", cmdname); + exit(1); + } + + if (!standalone) { + /* signal parent that startup was successful */ + if (kill(getppid(), SIGUSR1) == -1) + exit(1); + } +} + +static void +ldma_usage() +{ + (void) fprintf(stderr, "usage: %s\n", cmdname); +} + +int +main(int argc, char *argv[]) +{ + int opt; + boolean_t standalone = B_FALSE; + + cmdname = basename(argv[0]); + + /* disable getopt error messages */ + opterr = 0; + + while ((opt = getopt(argc, argv, "ds")) != EOF) { + + switch (opt) { + case 'd': + ldma_debug = B_TRUE; + break; + case 's': + standalone = B_TRUE; + break; + default: + ldma_usage(); + exit(1); + } + } + + ldma_start(standalone); + + /* + * Loop forever. Any incoming message will be received by libds and + * forwarded to the agent data callback (ldma_data_cb()) where it + * will be processed. + */ + for (;;) { + (void) pause(); + } + + /*NOTREACHED*/ + return (0); +} diff --git a/usr/src/cmd/ldmad/ldoms-agents b/usr/src/cmd/ldmad/ldoms-agents new file mode 100644 index 0000000000..58ef419dca --- /dev/null +++ b/usr/src/cmd/ldmad/ldoms-agents @@ -0,0 +1,80 @@ +#!/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /lib/svc/share/smf_include.sh + +SVCNAME='Logical Domains agents' +LDMAD='/usr/lib/ldoms/ldmad' +VLDS='/devices/virtual-devices@100/channel-devices@200/virtual-domain-service@0:vlds' +mach=`/sbin/uname -m` + +if [ "$mach" != "sun4v" ]; then + echo "The $SVCNAME service is not supported on this platform." + exit "$SMF_EXIT_ERR_FATAL" +fi + +if smf_is_nonglobalzone; then + echo "The $SVCNAME service has been disabled because " \ + "it is not supported in a local zone." + /usr/sbin/svcadm disable "$SMF_FMRI" + sleep 5 & + exit "$SMF_EXIT_OK" +fi + +# +# The Logical Domains agents service is enabled by default on sun4v platforms. +# However it can fail to start if the domain has a machine description in which +# the vlds node is not defined (because it has an old MD or firmware). So we +# check if a vlds device is effectively defined. If not then we disable the +# service for this session. We don't return an error so that the service does +# not go into the maintenance state and generate spurious error (especially if +# the system is not configured with LDoms). The service is not permanently +# disabled so that the service can come up if the domain is restarted with a +# compatible MD. +# +if [ ! -c "$VLDS" ]; then + echo "The $SVCNAME service has been disabled because the system" \ + "has no virtual domain service (vlds) device." + /usr/sbin/svcadm disable -t "$SMF_FMRI" + sleep 5 & + exit "$SMF_EXIT_OK" +fi + +if [ ! -x "$LDMAD" ]; then + echo "The $SVCNAME service requires the $LDMAD executable." + exit "$SMF_EXIT_ERR_CONFIG" +fi + +$LDMAD + +EXIT=$? + +if [ "$EXIT" != 0 ]; then + exit "$EXIT" +fi + +exit "$SMF_EXIT_OK" diff --git a/usr/src/cmd/ldmad/ldoms-agents.xml b/usr/src/cmd/ldmad/ldoms-agents.xml new file mode 100644 index 0000000000..d968745f19 --- /dev/null +++ b/usr/src/cmd/ldmad/ldoms-agents.xml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<!-- + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + Copyright 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + NOTE: This service manifest is not editable; its contents will + be overwritten by package or patch operations, including + operating system upgrade. Make customizations in a different file. +--> + +<service_bundle type='manifest' name='SUNWldomu:ldmad'> + +<service + name='ldoms/agents' + type='service' + version='1'> + + <create_default_instance enabled='false' /> + + <single_instance /> + + <dependency + name='filesystem-minimal' + grouping='require_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/system/filesystem/minimal' /> + </dependency> + + <dependency + name='syslog' + grouping='optional_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/system/system-log' /> + </dependency> + + <exec_method + type='method' + name='start' + exec='/lib/svc/method/ldoms-agents' + timeout_seconds='60' /> + + <exec_method + type='method' + name='stop' + exec=':kill' + timeout_seconds='30' /> + + <stability value='Unstable' /> + + <template> + <common_name> + <loctext xml:lang='C'> + Logical Domains agents service + </loctext> + </common_name> + <documentation> + <manpage title='ldmad' section='1M' + manpath='/usr/share/man' /> + </documentation> + </template> +</service> + +</service_bundle> diff --git a/usr/src/cmd/svc/profile/platform_sun4v.xml b/usr/src/cmd/svc/profile/platform_sun4v.xml index e52039ec13..521767b48d 100644 --- a/usr/src/cmd/svc/profile/platform_sun4v.xml +++ b/usr/src/cmd/svc/profile/platform_sun4v.xml @@ -1,29 +1,27 @@ <?xml version='1.0'?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> <!-- - Copyright 2006 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. + CDDL HEADER START - CDDL HEADER START + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. - The contents of this file are subject to the terms of the - Common Development and Distribution License (the "License"). - You may not use this file except in compliance with the License. + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] + CDDL HEADER END - CDDL HEADER END - - ident "%Z%%M% %I% %E% SMI" + Copyright 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. NOTE: This service profile is not editable; its contents will be overwritten by package or patch operations, including operating @@ -38,4 +36,7 @@ <service name='platform/sun4v/efdaemon' version='1' type='service'> <instance name='default' enabled='true'/> </service> + <service name='ldoms/agents' version='1' type='service'> + <instance name='default' enabled='true'/> + </service> </service_bundle> diff --git a/usr/src/pkgdefs/SUNWldomr.v/prototype_sparc b/usr/src/pkgdefs/SUNWldomr.v/prototype_sparc index 13e14c5e7a..4a2de64c35 100644 --- a/usr/src/pkgdefs/SUNWldomr.v/prototype_sparc +++ b/usr/src/pkgdefs/SUNWldomr.v/prototype_sparc @@ -50,6 +50,7 @@ d none lib 755 root bin d none lib/svc 0755 root bin d none lib/svc/method 0755 root bin +f none lib/svc/method/ldoms-agents 0555 root bin f none lib/svc/method/svc-drd 0555 root bin f none lib/svc/method/svc-vntsd 0555 root bin d none platform 755 root sys @@ -86,4 +87,5 @@ d none var/svc/manifest 755 root sys d none var/svc/manifest/platform 755 root sys d none var/svc/manifest/platform/sun4v 755 root sys f manifest var/svc/manifest/platform/sun4v/drd.xml 0444 root sys +f manifest var/svc/manifest/platform/sun4v/ldoms-agents.xml 0444 root sys f manifest var/svc/manifest/platform/sun4v/vntsd.xml 0444 root sys diff --git a/usr/src/pkgdefs/SUNWldomu.v/prototype_sparc b/usr/src/pkgdefs/SUNWldomu.v/prototype_sparc index 413badcb41..434b07454d 100644 --- a/usr/src/pkgdefs/SUNWldomu.v/prototype_sparc +++ b/usr/src/pkgdefs/SUNWldomu.v/prototype_sparc @@ -20,7 +20,7 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # @@ -51,6 +51,7 @@ d none usr 755 root sys d none usr/lib 755 root bin d none usr/lib/ldoms 755 root bin f none usr/lib/ldoms/drd 555 root bin +f none usr/lib/ldoms/ldmad 555 root bin f none usr/lib/ldoms/vntsd 555 root bin f none usr/lib/libpri.so.1 755 root bin f none usr/lib/libds.so.1 755 root bin diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index 7d1d0447fc..fe9f110a99 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -306,6 +306,7 @@ superfluous_nonglobal_zone_files=" lib/svc/method/devices-audio lib/svc/method/fc-fabric lib/svc/method/iscsi-initiator + lib/svc/method/ldoms-agents lib/svc/method/npivconfig lib/svc/method/sf880dr lib/svc/method/svc-cvcd @@ -1613,6 +1614,10 @@ smf_handle_new_services () { -f $rootprefix/etc/pooladm.conf ]]; then smf_enable svc:/system/pools:default fi + if [[ $zone = global && $karch = sun4v && + ! -f $rootprefix/var/svc/manifest/platforms/sun4v/ldoms-agents.xml ]]; then + smf_enable svc:/ldoms/agents:default + fi } smf_copy_manifest() { |