summaryrefslogtreecommitdiff
path: root/usr/src/cmd/pools
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/pools
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/pools')
-rw-r--r--usr/src/cmd/pools/Makefile49
-rw-r--r--usr/src/cmd/pools/Makefile.pools34
-rw-r--r--usr/src/cmd/pools/common/utils.c114
-rw-r--r--usr/src/cmd/pools/common/utils.h109
-rw-r--r--usr/src/cmd/pools/pooladm/Makefile64
-rw-r--r--usr/src/cmd/pools/pooladm/pooladm.c258
-rw-r--r--usr/src/cmd/pools/poolbind/Makefile64
-rw-r--r--usr/src/cmd/pools/poolbind/poolbind.c301
-rw-r--r--usr/src/cmd/pools/poolcfg/Makefile81
-rw-r--r--usr/src/cmd/pools/poolcfg/poolcfg.h79
-rw-r--r--usr/src/cmd/pools/poolcfg/poolcfg.l264
-rw-r--r--usr/src/cmd/pools/poolcfg/poolcfg.y1596
-rw-r--r--usr/src/cmd/pools/poold/Makefile144
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DRM.java86
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DecisionHistory.java623
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Expression.java653
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/LogDRM.java128
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Makefile60
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Monitor.java102
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Move.java221
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Objective.java1034
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Poold.java1155
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/ResourceMonitor.java255
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Solver.java96
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Statistic.java491
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/StatisticList.java737
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemMonitor.java366
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemSolver.java986
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/package.html51
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/exception/Makefile47
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/exception/SuccinctStackTraceFormatter.java142
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/exception/package.html52
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Kstat.java80
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatChainUpdateException.java53
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatCtl.java94
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatException.java36
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatReadException.java35
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatTypeNotSupportedException.java36
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Makefile52
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/package.html51
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityDomain.java350
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityGroup.java211
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/locality/Makefile49
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/locality/package.html51
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Facility.java261
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Makefile50
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Severity.java254
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SyslogHandler.java267
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SysloglikeFormatter.java172
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/logging/package.html51
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Component.java186
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Configuration.java689
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Element.java287
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/HRTime.java107
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Makefile59
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Pool.java227
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolInternal.java207
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolsException.java677
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Property.java88
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PropertyWalk.java53
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Resource.java251
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/UnsignedInt64.java114
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Value.java380
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/pools/package.html51
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/timer/Makefile48
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/timer/RecurringEventTimer.java38
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/timer/SimpleRecurringEventTimer.java80
-rw-r--r--usr/src/cmd/pools/poold/com/sun/solaris/service/timer/package.html51
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/Makefile63
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/Makefile.com53
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/i386/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/jkstat.c421
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/sparc/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/Makefile31
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/Makefile.targ36
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/amd64/Makefile43
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/i386/Makefile42
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/jkstat.spec101
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/sparc/Makefile41
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/sparcv9/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjkstat/spec/versions36
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/Makefile63
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/Makefile.com55
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/i386/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/jlgrp.c250
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/sparc/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/Makefile31
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/Makefile.targ36
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/amd64/Makefile43
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/i386/Makefile42
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/jlgrp.spec76
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/sparc/Makefile41
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/sparcv9/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjlgrp/spec/versions36
-rw-r--r--usr/src/cmd/pools/poold/libjpool/Makefile65
-rw-r--r--usr/src/cmd/pools/poold/libjpool/Makefile.com56
-rw-r--r--usr/src/cmd/pools/poold/libjpool/i386/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjpool/jpool.c1759
-rw-r--r--usr/src/cmd/pools/poold/libjpool/sparc/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/Makefile31
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/Makefile.targ36
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/amd64/Makefile43
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/i386/Makefile42
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/jpool.spec760
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/sparc/Makefile41
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/sparcv9/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjpool/spec/versions36
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/Makefile62
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/Makefile.com55
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/i386/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/jsyslog.c113
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/sparc/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/Makefile31
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/Makefile.targ36
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/amd64/Makefile43
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/i386/Makefile42
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/jsyslog.spec53
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/sparc/Makefile41
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/sparcv9/Makefile36
-rw-r--r--usr/src/cmd/pools/poold/libjsyslog/spec/versions36
-rw-r--r--usr/src/cmd/pools/poold/poold.c680
-rw-r--r--usr/src/cmd/pools/poold/poold.properties47
-rw-r--r--usr/src/cmd/pools/poolstat/Makefile65
-rw-r--r--usr/src/cmd/pools/poolstat/poolstat.c1009
-rw-r--r--usr/src/cmd/pools/poolstat/poolstat.h190
-rw-r--r--usr/src/cmd/pools/poolstat/poolstat_utils.c51
-rw-r--r--usr/src/cmd/pools/poolstat/poolstat_utils.h52
-rw-r--r--usr/src/cmd/pools/poolstat/sa_kstat.c346
-rw-r--r--usr/src/cmd/pools/poolstat/sa_libpool.c156
129 files changed, 24137 insertions, 0 deletions
diff --git a/usr/src/cmd/pools/Makefile b/usr/src/cmd/pools/Makefile
new file mode 100644
index 0000000000..a26d82631f
--- /dev/null
+++ b/usr/src/cmd/pools/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/Makefile
+#
+
+include ../Makefile.cmd
+
+SUBDIRS= pooladm poolbind poolcfg poolstat poold
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+_msg := TARGET = _msg
+
+.KEEP_STATE:
+
+all install lint clean clobber _msg: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/cmd/pools/Makefile.pools b/usr/src/cmd/pools/Makefile.pools
new file mode 100644
index 0000000000..9b8f96eb1e
--- /dev/null
+++ b/usr/src/cmd/pools/Makefile.pools
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 (c) 2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/Makefile.pools
+
+POOLSSRC = $(SRC)/cmd/pools
+POOLSCOMMONDIR = $(POOLSSRC)/common
+
+COMMON_OBJS = utils.o
+COMMON_SRCS = $(COMMON_OBJS:%.o=$(POOLSCOMMONDIR)/%.c)
diff --git a/usr/src/cmd/pools/common/utils.c b/usr/src/cmd/pools/common/utils.c
new file mode 100644
index 0000000000..7318688908
--- /dev/null
+++ b/usr/src/cmd/pools/common/utils.c
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libintl.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <pool.h>
+#include "utils.h"
+
+static const char PNAME_FMT[] = "%s: ";
+static const char ERRNO_FMT[] = ": %s\n";
+
+static const char *pname;
+
+/*LINTLIBRARY*/
+const char *
+get_errstr_err(int errnum, int syserr)
+{
+ const char *errstr;
+
+ if (errnum == POE_SYSTEM)
+ errstr = strerror(syserr);
+ else
+ errstr = pool_strerror(errnum);
+ return (errstr);
+}
+
+const char *
+get_errstr(void)
+{
+ return (get_errstr_err(pool_error(), errno));
+}
+
+/*PRINTFLIKE1*/
+void
+warn(const char *format, ...)
+{
+ int err = errno;
+ va_list alist;
+
+ if (pname != NULL)
+ (void) fprintf(stderr, PNAME_FMT, pname);
+
+ va_start(alist, format);
+ (void) vfprintf(stderr, format, alist);
+ va_end(alist);
+
+ if (strrchr(format, '\n') == NULL)
+ (void) fprintf(stderr, ERRNO_FMT, strerror(err));
+}
+
+/*PRINTFLIKE1*/
+void
+die(const char *format, ...)
+{
+ int err = errno;
+ va_list alist;
+
+ if (pname != NULL)
+ (void) fprintf(stderr, PNAME_FMT, pname);
+
+ va_start(alist, format);
+ (void) vfprintf(stderr, format, alist);
+ va_end(alist);
+
+ if (strrchr(format, '\n') == NULL)
+ (void) fprintf(stderr, ERRNO_FMT, strerror(err));
+
+ exit(E_ERROR);
+}
+
+const char *
+getpname(const char *arg0)
+{
+ const char *p = strrchr(arg0, '/');
+
+ if (p == NULL)
+ p = arg0;
+ else
+ p++;
+
+ pname = p;
+ return (p);
+}
diff --git a/usr/src/cmd/pools/common/utils.h b/usr/src/cmd/pools/common/utils.h
new file mode 100644
index 0000000000..929e6c8eaa
--- /dev/null
+++ b/usr/src/cmd/pools/common/utils.h
@@ -0,0 +1,109 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Error messages for pool commands */
+#define ERR_SET_TERM "cleanup installation failed: %s\n"
+#define ERR_CONF_LOAD "cannot load configuration from %s: %s\n"
+#define ERR_CMD_FILE_INIT "cannot initialise command sequence: %s\n"
+#define ERR_PROP_TO_LIST "cannot add property %s to property list\n"
+#define ERR_UNKNOWN_ENTITY "unrecognised entity %lld\n"
+#define ERR_ASSOC_TO_LIST "cannot add association %s to association " \
+ "list\n"
+#define ERR_GET_ELEMENT_DETAILS "cannot get the %s details for %s: %s\n"
+#define ERR_LOCATE_ELEMENT "cannot locate the %s, %s: %s\n"
+#define ERR_CREATE_ELEMENT "cannot create the %s, %s: %s\n"
+#define ERR_DESTROY_ELEMENT "cannot destroy the %s, %s: %s\n"
+#define ERR_ALLOC_ELEMENT "cannot allocate %s: %s\n"
+#define ERR_PUT_PROPERTY "put property %s failed: %s\n"
+#define ERR_REMOVE_PROPERTY "remove property %s failed: %s\n"
+#define ERR_GET_PROPERTY "get property %s failed: %s\n"
+#define ERR_UNKNOWN_RESOURCE "unrecognized resource type: %d\n"
+#define ERR_ASSOC_RESOURCE "cannot associate resource %s to pool: %s\n"
+#define ERR_VALIDATION_FAILED "configuration failed strict validation: %s\n"
+#define ERR_CONFIG_OPEN_FAILED "cannot open the configuration: %s\n"
+#define ERR_CONFIG_SAVE_FAILED "cannot save the configuration: %s\n"
+#define ERR_WRONG_SYSTEM_NAME "incorrect system name supplied: %s\n"
+#define ERR_CMD_LINE_ALLOC "cannot create command, not enough memory\n"
+#define ERR_PROP_ALLOC "cannot create property, not enough memory\n"
+#define ERR_ASSOC_ALLOC "cannot create association, not enough memory\n"
+
+#define ERR_DISABLE "cannot disable pools"
+#define ERR_ENABLE "cannot enable pools"
+#define ERR_NOMEM "not enough memory\n"
+#define ERR_PERMISSIONS "insufficient privileges\n"
+#define ERR_PRIVILEGE "cannot access %s privileges"
+#define ERR_OPEN_DYNAMIC "couldn't open pools state file: %s\n"
+#define ERR_OPEN_STATIC "couldn't open configuration at '%s': %s\n"
+#define ERR_VALIDATE_RUNTIME "configuration at '%s' cannot be instantiated "\
+ "on current system\n"
+#define ERR_COMMIT_DYNAMIC "couldn't commit configuration changes at '%s'"\
+ ": %s\n"
+#define ERR_REMOVE_DYNAMIC "couldn't remove dynamic configuration: %s\n"
+#define ERR_COMMIT_STATIC "couldn't commit configuration changes at '%s'"\
+ ": %s\n"
+#define ERR_EXPORT_DYNAMIC "couldn't export pools state file to '%s': %s\n"
+#define ERR_NO_POOLS "no pools defined\n"
+#define ERR_XFER_COMPONENT "cannot transfer %s %s to %s: %s\n"
+#define ERR_XFER_QUANTITY "cannot transfer %llu from %s to %s: %s\n"
+#define ERR_CMDPARSE_FAILED "command parsing failed, terminating...\n"
+
+#define CONFIGURATION "configuration"
+#define RESOURCE "resource"
+#define POOL "pool"
+#define PSET "pset"
+#define COMPONENT "component"
+#define CPU "cpu"
+#define SYSTEM_NAME "system.name"
+#define POOL_NAME "pool.name"
+#define PSET_NAME "pset.name"
+#define CPU_SYSID "cpu.sys_id"
+
+#define E_PO_SUCCESS 0 /* Exit status for success */
+#define E_ERROR 1 /* Exit status for error */
+#define E_USAGE 2 /* Exit status for usage error */
+
+extern const char *get_errstr(void);
+extern const char *get_errstr_err(int, int);
+extern void warn(const char *, ...);
+extern void die(const char *, ...);
+extern const char *getpname(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UTILS_H */
diff --git a/usr/src/cmd/pools/pooladm/Makefile b/usr/src/cmd/pools/pooladm/Makefile
new file mode 100644
index 0000000000..00fee62fd2
--- /dev/null
+++ b/usr/src/cmd/pools/pooladm/Makefile
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/pooladm/Makefile
+
+PROG = pooladm
+OBJS = pooladm.o
+SRCS = $(OBJS:%.o=%.c) $(COMMON_SRCS)
+POFILES = $(OBJS:.o=.po)
+
+include ../../Makefile.cmd
+include ../Makefile.pools
+
+CFLAGS += -I$(POOLSCOMMONDIR)
+LDLIBS += -lpool
+XGETFLAGS = -a
+CLOBBERFILES += $(POFILES)
+
+lint := LINTFLAGS += -I$(POOLSCOMMONDIR)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS) $(COMMON_OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(COMMON_OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o : $(POOLSCOMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+ $(RM) $(OBJS) $(COMMON_OBJS) $(POFILES)
+
+lint: lint_SRCS
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/pools/pooladm/pooladm.c b/usr/src/cmd/pools/pooladm/pooladm.c
new file mode 100644
index 0000000000..f2469ed189
--- /dev/null
+++ b/usr/src/cmd/pools/pooladm/pooladm.c
@@ -0,0 +1,258 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * pooladm - set, remove, or display active pool configurations.
+ */
+
+#include <sys/zone.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <libintl.h>
+#include <locale.h>
+#include <string.h>
+#include <priv.h>
+#include <errno.h>
+#include <zone.h>
+#include <pool.h>
+#include <unistd.h>
+#include "utils.h"
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+static int Cflag;
+static int Sflag;
+static int Dflag;
+static int Eflag;
+static int Nflag;
+static int Xflag;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ gettext("Usage:\tpooladm [-n] [-s] [-c] [filename]\n"));
+ (void) fprintf(stderr,
+ gettext("Usage:\tpooladm [-n] -x\n"));
+ (void) fprintf(stderr,
+ gettext("Usage:\tpooladm -d | -e\n"));
+ exit(E_USAGE);
+}
+
+static void
+config_print(pool_conf_t *conf)
+{
+ char *buf;
+ pool_value_t *pv;
+ const char *tgt;
+
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
+ != PO_SUCCESS)
+ die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
+
+ if ((pv = pool_value_alloc()) == NULL ||
+ pool_get_property(conf, pool_conf_to_elem(conf), "system.name",
+ pv) == POC_INVAL ||
+ pool_value_get_string(pv, &tgt) != PO_SUCCESS)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+
+ if ((buf = pool_conf_info(conf, PO_TRUE)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION),
+ tgt, get_errstr());
+ pool_value_free(pv);
+ (void) printf("%s", buf);
+ free(buf);
+ (void) pool_conf_close(conf);
+}
+
+static void
+config_destroy(pool_conf_t *conf)
+{
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR)
+ != PO_SUCCESS)
+ die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
+ if (pool_conf_remove(conf) != PO_SUCCESS)
+ die(gettext(ERR_REMOVE_DYNAMIC), get_errstr());
+}
+
+static void
+config_commit(pool_conf_t *conf, const char *static_conf_name)
+{
+ if (pool_conf_open(conf, static_conf_name, Nflag || !Sflag ?
+ PO_RDONLY : PO_RDWR) != PO_SUCCESS)
+ die(gettext(ERR_OPEN_STATIC), static_conf_name, get_errstr());
+
+ if (pool_conf_validate(conf, POV_RUNTIME) != PO_SUCCESS)
+ die(gettext(ERR_VALIDATE_RUNTIME), static_conf_name);
+ if (!Nflag) {
+ if (pool_conf_commit(conf, PO_TRUE) != PO_SUCCESS)
+ die(gettext(ERR_COMMIT_DYNAMIC), static_conf_name,
+ get_errstr());
+ /*
+ * Dump the updated state to the specified location
+ */
+ if (Sflag) {
+ if (pool_conf_commit(conf, PO_FALSE) != PO_SUCCESS)
+ die(gettext(ERR_COMMIT_STATIC),
+ static_conf_name, get_errstr());
+ }
+ }
+ (void) pool_conf_close(conf);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ pool_conf_t *conf = NULL;
+ const char *static_conf_loc;
+
+ (void) getpname(argv[0]);
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+
+ while ((c = getopt(argc, argv, "cdensx")) != EOF) {
+ switch (c) {
+ case 'c': /* Create (or modify) system configuration */
+ Cflag++;
+ break;
+ case 'd': /* Disable the pools facility */
+ Dflag++;
+ break;
+ case 'e': /* Enable the pools facility */
+ Eflag++;
+ break;
+ case 'n': /* Don't actually do anything */
+ Nflag++;
+ break;
+ case 's': /* Update the submitted configuration */
+ Sflag++;
+ break;
+ case 'x': /* Delete current system configuration */
+ Xflag++;
+ break;
+ case '?':
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ }
+
+ /*
+ * Not all flags can be used at the same time.
+ */
+ if ((Cflag || Sflag || Dflag || Eflag) && Xflag)
+ usage();
+
+ if ((Dflag || Eflag) && (Cflag || Sflag || Xflag))
+ usage();
+
+ if (Dflag && Eflag)
+ usage();
+
+ argc -= optind;
+ argv += optind;
+
+ if (! (Cflag || Sflag)) {
+ if (argc != 0)
+ usage();
+ } else {
+ if (argc == 0)
+ static_conf_loc = pool_static_location();
+ else if (argc == 1)
+ static_conf_loc = argv[0];
+ else
+ usage();
+ }
+
+ if (!Nflag && (Cflag + Dflag + Eflag + Xflag != 0) &&
+ !priv_ineffect(PRIV_SYS_RES_CONFIG))
+ die(gettext(ERR_PERMISSIONS));
+
+ if (Dflag) {
+ if (pool_set_status(POOL_DISABLED) != PO_SUCCESS)
+ die(gettext(ERR_DISABLE));
+ } else if (Eflag) {
+ if (pool_set_status(POOL_ENABLED) != PO_SUCCESS) {
+ if (errno == EEXIST)
+ die(gettext(ERR_ENABLE
+ ": System has active processor sets\n"));
+ else
+ die(gettext(ERR_ENABLE));
+ }
+ } else {
+ if ((conf = pool_conf_alloc()) == NULL)
+ die(gettext(ERR_NOMEM));
+
+ if (Cflag + Sflag + Xflag == 0) {
+ /*
+ * No flags means print current system configuration
+ */
+ config_print(conf);
+ } else if (!Nflag && Xflag) {
+ /*
+ * Destroy active pools configuration and
+ * remove the state file.
+ */
+ config_destroy(conf);
+ } else {
+ /*
+ * Commit a new configuration.
+ */
+ if (Cflag)
+ config_commit(conf, static_conf_loc);
+ else {
+ /*
+ * Dump the dynamic state to the
+ * specified location
+ */
+ if (!Nflag && Sflag) {
+ if (pool_conf_open(conf,
+ pool_dynamic_location(), PO_RDONLY)
+ != PO_SUCCESS)
+ die(gettext(ERR_OPEN_DYNAMIC),
+ get_errstr());
+ if (pool_conf_export(conf,
+ static_conf_loc, POX_NATIVE) !=
+ PO_SUCCESS)
+ die(gettext(ERR_EXPORT_DYNAMIC),
+ static_conf_loc, get_errstr());
+ (void) pool_conf_close(conf);
+ }
+ }
+ }
+ pool_conf_free(conf);
+ }
+ return (E_PO_SUCCESS);
+}
diff --git a/usr/src/cmd/pools/poolbind/Makefile b/usr/src/cmd/pools/poolbind/Makefile
new file mode 100644
index 0000000000..9c0cdbdb2e
--- /dev/null
+++ b/usr/src/cmd/pools/poolbind/Makefile
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poolbind/Makefile
+
+PROG = poolbind
+OBJS = poolbind.o
+SRCS = $(OBJS:%.o=%.c) $(COMMON_SRCS)
+POFILES = $(OBJS:.o=.po)
+
+include ../../Makefile.cmd
+include ../Makefile.pools
+
+CFLAGS += -I$(POOLSCOMMONDIR)
+LDLIBS += -lpool -lproject
+XGETFLAGS = -a
+CLOBBERFILES += $(POFILES)
+
+lint := LINTFLAGS += -I$(POOLSCOMMONDIR)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS) $(COMMON_OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(COMMON_OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o : $(POOLSCOMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+ $(RM) $(OBJS) $(COMMON_OBJS) $(POFILES)
+
+lint: lint_SRCS
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/pools/poolbind/poolbind.c b/usr/src/cmd/pools/poolbind/poolbind.c
new file mode 100644
index 0000000000..395a09bbdf
--- /dev/null
+++ b/usr/src/cmd/pools/poolbind/poolbind.c
@@ -0,0 +1,301 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * poolbind - bind processes, tasks, and projects to pools, and query process
+ * pool bindings
+ */
+
+#include <libgen.h>
+#include <pool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <locale.h>
+#include <libintl.h>
+
+#include <sys/procset.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <project.h>
+#include <zone.h>
+
+#include "utils.h"
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+#define eFLAG 0x1
+#define iFLAG 0x2
+#define pFLAG 0x4
+#define qFLAG 0x8
+#define QFLAG 0x10
+
+static const char OPTS[] = "Qei:p:q";
+static struct {
+ idtype_t idtype;
+ char *str;
+} idtypes[] = {
+ { P_PID, "pid" },
+ { P_TASKID, "taskid" },
+ { P_PROJID, "projid" },
+ { P_PROJID, "project" },
+ { P_ZONEID, "zoneid" },
+ { -1, NULL }
+};
+
+int error = E_PO_SUCCESS;
+
+void exec_cmd(char *, char *[]);
+void process_ids(char *, uint_t, idtype_t, char *, int, char *[]);
+
+void
+usage(void)
+{
+ (void) fprintf(stderr,
+ gettext("Usage:\n"
+ " poolbind -p pool_name -e command [arguments...]\n"
+ " poolbind -p pool_name "
+ "[-i pid | -i taskid | -i projid | -i zoneid] id ...\n"
+ " poolbind -q pid ...\n"
+ " poolbind -Q pid ... \n"));
+ exit(E_USAGE);
+}
+
+int
+print_resource_binding(const char *type, pid_t pid)
+{
+ char *resource_name;
+
+ if ((resource_name = pool_get_resource_binding(type, pid)) == NULL)
+ warn(gettext("getting '%s' binding for %d: %s\n"), type,
+ (int)pid, get_errstr());
+ else
+ (void) printf("%d\t%s\t%s\n", (int)pid, type, resource_name);
+ free(resource_name);
+ return (PO_SUCCESS);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ int i;
+ idtype_t idtype = P_PID;
+ char *idstr = "pid";
+ char *pool_name = NULL;
+ uint_t flags = 0;
+ int status;
+
+ (void) getpname(argv[0]);
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ while ((c = getopt(argc, argv, OPTS)) != EOF) {
+ switch (c) {
+ case 'Q':
+ if (flags & (qFLAG | iFLAG | pFLAG))
+ usage();
+ flags |= QFLAG;
+ break;
+ case 'e':
+ if (flags & (iFLAG | qFLAG | QFLAG))
+ usage();
+ flags |= eFLAG;
+ break;
+ case 'i':
+ for (i = 0; idtypes[i].str != NULL; i++) {
+ if (strcmp(optarg, idtypes[i].str) == 0) {
+ idtype = idtypes[i].idtype;
+ idstr = idtypes[i].str;
+ break;
+ }
+ }
+ if ((flags & (iFLAG | qFLAG | QFLAG)) ||
+ idtypes[i].str == NULL)
+ usage();
+ flags |= iFLAG;
+ break;
+ case 'p':
+ if (flags & (pFLAG | qFLAG | QFLAG))
+ usage();
+ flags |= pFLAG;
+ pool_name = optarg;
+ break;
+ case 'q':
+ if (flags & (pFLAG | iFLAG | QFLAG))
+ usage();
+ flags |= qFLAG;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (flags & eFLAG && pool_name == NULL)
+ usage();
+ if (argc < 1 || (flags & (pFLAG | qFLAG | QFLAG)) == 0)
+ usage();
+
+ /*
+ * Check to see that the pools facility is enabled
+ */
+ if (pool_get_status(&status) != PO_SUCCESS)
+ die((ERR_OPEN_DYNAMIC), get_errstr());
+ if (status == POOL_DISABLED)
+ die((ERR_OPEN_DYNAMIC), strerror(ENOTACTIVE));
+
+ if (flags & eFLAG)
+ exec_cmd(pool_name, argv);
+ /*NOTREACHED*/
+ else
+ process_ids(pool_name, flags, idtype, idstr, argc, argv);
+
+ return (error);
+}
+
+void
+exec_cmd(char *pool_name, char *argv[])
+{
+ if (pool_set_binding(pool_name, P_PID, getpid()) != PO_SUCCESS) {
+ warn(gettext("binding to pool '%s': %s\n"), pool_name,
+ get_errstr());
+ error = E_ERROR;
+ return;
+ }
+
+ if (execvp(basename(argv[0]), argv) == -1)
+ die(gettext("exec of %s failed"), argv[0]);
+ /*NOTREACHED*/
+}
+
+void
+process_ids(char *pool_name, uint_t flags, idtype_t idtype, char *idstr,
+ int argc, char *argv[])
+{
+ int i;
+ id_t id;
+
+ for (i = 0; i < argc; i++) {
+ char *endp;
+ char *poolname;
+
+ errno = 0;
+ id = (id_t)strtol(argv[i], &endp, 10);
+ if (errno != 0 ||
+ (endp && endp != argv[i] + strlen(argv[i])) ||
+ (idtype == P_ZONEID &&
+ getzonenamebyid(id, NULL, 0) == -1)) {
+ /*
+ * The string does not completely parse to
+ * an integer, or it represents an invalid
+ * zone id.
+ */
+
+ /*
+ * It must be a project or zone name.
+ */
+ if (idtype == P_ZONEID) {
+ if (zone_get_id(argv[i], &id) != 0) {
+ warn(gettext("invalid zone '%s'\n"),
+ argv[i]);
+ error = E_ERROR;
+ continue;
+ }
+ /* make sure the zone is booted */
+ if (id == -1) {
+ warn(gettext("zone '%s' is not "
+ "active\n"), argv[i]);
+ error = E_ERROR;
+ continue;
+ }
+ } else if (idtype == P_PROJID) {
+ if ((id = getprojidbyname(argv[i])) < 0) {
+ warn(gettext("failed to get project "
+ "id for project: '%s'"), argv[i]);
+ error = E_ERROR;
+ continue;
+ }
+ } else {
+ warn(gettext("invalid %s '%s'\n"),
+ idstr, argv[i]);
+ error = E_ERROR;
+ continue;
+ }
+ }
+
+ if (flags & pFLAG) {
+ if (pool_set_binding(pool_name, idtype, id) !=
+ PO_SUCCESS) {
+ warn(gettext("binding %s %ld to pool '%s': "
+ "%s\n"), idstr, id, pool_name,
+ get_errstr());
+ error = E_ERROR;
+ }
+ continue;
+ }
+
+ if (flags & qFLAG) {
+ if ((poolname = pool_get_binding(id)) == NULL) {
+ warn(gettext("couldn't determine binding for "
+ "pid %ld: %s\n"), id, get_errstr());
+ error = E_ERROR;
+ } else {
+ (void) printf("%ld\t%s\n", id, poolname);
+ free(poolname);
+ }
+ }
+ if (flags & QFLAG) {
+ uint_t j, count;
+ const char **resource_types;
+ (void) pool_resource_type_list(NULL, &count);
+
+ if ((resource_types = malloc(count *
+ sizeof (const char *))) == NULL) {
+ warn(gettext("couldn't allocate query memory "
+ "for pid %ld: %s\n"), id, get_errstr());
+ error = E_ERROR;
+ }
+ (void) pool_resource_type_list(resource_types, &count);
+
+ for (j = 0; j < count; j++)
+ (void) print_resource_binding(resource_types[j],
+ (pid_t)id);
+ free(resource_types);
+ }
+ }
+}
diff --git a/usr/src/cmd/pools/poolcfg/Makefile b/usr/src/cmd/pools/poolcfg/Makefile
new file mode 100644
index 0000000000..d7b35660b1
--- /dev/null
+++ b/usr/src/cmd/pools/poolcfg/Makefile
@@ -0,0 +1,81 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 (c) 2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poolbind/Makefile
+
+PROG = poolcfg
+OBJS = poolcfg_lex.o poolcfg_grammar.o
+SRCS = $(OBJS:%.o=%.c) $(COMMON_SRCS)
+POFILES = $(OBJS:.o=.po)
+POFILE = poolcfg.po
+
+include ../../Makefile.cmd
+include ../Makefile.pools
+
+LFLAGS = -t
+YFLAGS = -d
+CFLAGS += -I$(POOLSCOMMONDIR)
+LDLIBS += -lpool -ll
+XGETFLAGS = -a
+CLOBBERFILES += poolcfg_lex.c poolcfg_grammar.c poolcfg_grammar.h
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS) $(COMMON_OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(COMMON_OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o : $(POOLSCOMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+install: all $(ROOTUSRSBINPROG)
+
+poolcfg_lex.c: poolcfg.l poolcfg_grammar.h
+ $(LEX) $(LFLAGS) poolcfg.l > $@
+
+poolcfg_grammar.h poolcfg_grammar.c: poolcfg.y
+ $(YACC) $(YFLAGS) poolcfg.y
+ @$(MV) y.tab.h poolcfg_grammar.h
+ @$(MV) y.tab.c poolcfg_grammar.c
+
+poolcfg_lex.o poolcfg_grammar.o := CCVERBOSE =
+
+clean:
+ $(RM) $(OBJS) $(COMMON_OBJS) $(POFILES)
+
+$(POFILE): $(POFILES)
+ $(RM) $@; cat $(POFILES) > $@
+
+#
+# We don't do lint of lex- and yacc- generated source files
+#
+lint:
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/pools/poolcfg/poolcfg.h b/usr/src/cmd/pools/poolcfg/poolcfg.h
new file mode 100644
index 0000000000..75aeca7286
--- /dev/null
+++ b/usr/src/cmd/pools/poolcfg/poolcfg.h
@@ -0,0 +1,79 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _POOLCFG_H
+#define _POOLCFG_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ po_create,
+ po_remove
+} prop_op_t;
+
+typedef union {
+ uint64_t u;
+ int64_t i;
+ double d;
+ uchar_t b;
+ const char *s;
+} pv_u;
+
+typedef struct prop {
+ const char *prop_name;
+ pool_value_t *prop_value;
+ prop_op_t prop_op;
+ struct prop *prop_next;
+} prop_t;
+
+typedef struct assoc {
+ int assoc_type;
+ const char *assoc_name;
+ struct assoc *assoc_next;
+} assoc_t;
+
+typedef struct cmd {
+ void (*cmd)(struct cmd *);
+ const char *cmd_tgt1;
+ const char *cmd_tgt2;
+ uint64_t cmd_qty;
+ prop_t *cmd_prop_list;
+ assoc_t *cmd_assoc_list;
+} cmd_t;
+
+typedef void (*cmdfunc)(cmd_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _POOLCFG_H */
diff --git a/usr/src/cmd/pools/poolcfg/poolcfg.l b/usr/src/cmd/pools/poolcfg/poolcfg.l
new file mode 100644
index 0000000000..0837674c7e
--- /dev/null
+++ b/usr/src/cmd/pools/poolcfg/poolcfg.l
@@ -0,0 +1,264 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma error_messages(off, E_STATEMENT_NOT_REACHED)
+
+/*
+ * poolcfg.l
+ *
+ * Overview
+ * poolcfg.l implements a lexer for the poolcfg(1) utility.The lexer uses
+ * the token definitions generated by YACC in the file poolcfg_Grammar.h.
+ * To make token recognition simpler, the lexer uses a separate state for
+ * each of the different data types supported by poolcfg(1).
+ *
+ * States
+ * Lex provides the ability to minimise conflict between qualifying regexps
+ * by providing states. A regexp that is qualified by a state will only be
+ * used when the state is entered (using the BEGIN <state> command). (The
+ * exception to this rule, is that rules defined in the default state are
+ * available in all states.)
+ *
+ * poolcfg.l makes use of type states, one for each of the poolcfg(1)
+ * supported data types:
+ *
+ * ISTATE => int64_t
+ * USTATE => uint64_t
+ * BSTATE => uchar_t
+ * SSTATE => const char *
+ * DSTATE => double
+ *
+ * and a further state, CPUSTATE, to indicate the difference between matching
+ * a valid "name" (i.e. id) for a cpu and a valid name for other components of
+ * libpool.
+ *
+ * When a token indicating a variable declaration is matched, the corresponding
+ * state is saved in the state variable. Once the assignment ('=') token is
+ * matched, the stored state is entered and the additional state specific
+ * matching regular expressions become available. Once a state specific
+ * token is matched, the default state is restored.
+ *
+ */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <libintl.h>
+
+#include <pool.h>
+#include "utils.h"
+#include "poolcfg.h"
+#include "poolcfg_grammar.h"
+
+static int lex_lineno = 1; /* line-number for error reporting */
+static int state = INITIAL; /* state to be used */
+extern void yyerror(char *s);
+extern int dofile; /* are we processing a file? */
+%}
+
+%s ISTATE
+%s USTATE
+%s BSTATE
+%s SSTATE
+%s DSTATE
+%s CPUSTATE
+
+%%
+
+\n lex_lineno++;
+
+[ \t]+ ;
+
+#.* ;
+
+info { return PCC_INFO; }
+
+create { return PCC_CREATE; }
+
+destroy { return PCC_DESTROY; }
+
+modify { return PCC_MODIFY; }
+
+associate { return PCC_ASSOC; }
+
+transfer {
+ BEGIN USTATE;
+ return PCC_TRANSFER;
+ }
+
+discover { return PCC_DISC; }
+
+rename { return PCC_RENAME; }
+
+to { return PCK_TO; }
+
+from { return PCK_FROM; }
+
+int {
+ state=ISTATE;
+ return PCT_INT;
+ }
+
+uint {
+ state=USTATE;
+ return PCT_UINT;
+ }
+
+boolean {
+ state=BSTATE;
+ return PCT_BOOLEAN;
+ }
+
+string {
+ state=SSTATE;
+ return PCT_STRING;
+ }
+
+float {
+ state=DSTATE;
+ return PCT_FLOAT;
+ }
+
+cpu {
+ BEGIN CPUSTATE;
+ return PCE_CPU;
+ }
+
+pset { return PCE_PSET; }
+
+pool { return PCE_POOL; }
+
+system { return PCE_SYSTEM; }
+
+\( { return PCK_OPENLST; }
+
+\) { return PCK_CLOSELST; }
+
+= {
+ BEGIN state;
+ return PCK_ASSIGN;
+ }
+
+\; { return PCK_SEPLST; }
+
+~ { return PCK_UNDEF; }
+
+<ISTATE>-?[0-9]+ {
+ yylval.ival = strtoll(yytext, NULL, 0);
+ if (errno == EINVAL || errno == ERANGE) {
+ yyerror(gettext("Invalid value"));
+ exit(E_ERROR);
+ }
+ BEGIN INITIAL;
+ return PCV_VAL_INT;
+ }
+
+<USTATE>[0-9]+ {
+ yylval.uval = strtoull(yytext, NULL, 0);
+ if (errno == EINVAL || errno == ERANGE) {
+ yyerror(gettext("Invalid value"));
+ exit(E_ERROR);
+ }
+ BEGIN INITIAL;
+ return PCV_VAL_UINT;
+ }
+
+
+<BSTATE>true|false {
+ if (strcmp(yytext, "true") == 0)
+ yylval.bval = 1;
+ else
+ yylval.bval = 0;
+ BEGIN INITIAL;
+ return PCV_VAL_BOOLEAN;
+ }
+
+<SSTATE>\"[^\"\n]*[\"\n] {
+ if((yylval.sval = strdup(yytext+1)) == NULL) {
+ yyerror(gettext("Out of memory"));
+ exit(E_ERROR);
+ }
+ if (yylval.sval[yyleng-2] =='"')
+ yylval.sval[yyleng-2] = 0;
+ BEGIN INITIAL;
+ return PCV_VAL_STRING;
+ }
+
+<DSTATE>([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
+ yylval.dval = strtod(yytext, (char **)NULL);
+ if (errno == EINVAL || errno == ERANGE) {
+ yyerror(gettext("Invalid value"));
+ exit(E_ERROR);
+ }
+ BEGIN INITIAL;
+ return PCV_VAL_FLOAT;
+ }
+
+[A-Za-z][A-Za-z0-9,._-]* {
+ if ((yylval.sval = strdup(yytext)) == NULL) {
+ yyerror(gettext("Out of memory"));
+ exit(E_ERROR);
+ }
+ return PCV_SYMBOL;
+ }
+
+<CPUSTATE>[0-9]+ {
+ if ((yylval.sval = strdup(yytext)) == NULL) {
+ yyerror(gettext("Out of memory"));
+ exit(E_ERROR);
+ }
+ BEGIN INITIAL;
+ return PCV_SYMBOL;
+ }
+. {
+ yyerror(gettext("Illegal character"));
+ exit(E_ERROR);
+ }
+
+%%
+
+void
+yyerror(char *s)
+{
+ if (dofile == PO_TRUE) {
+ if (yytext[0] == '\0') {
+ (void) warn(gettext("line %d, %s, token expected\n"),
+ lex_lineno, s);
+ return;
+ }
+ (void) warn(gettext("line %d, %s at '%s'\n"), lex_lineno, s,
+ yytext);
+ } else {
+ if (yytext[0] == '\0') {
+ (void) warn(gettext("%s, token expected\n"), s);
+ return;
+ }
+ (void) warn(gettext("%s at '%s'\n"), s, yytext);
+ }
+}
+
diff --git a/usr/src/cmd/pools/poolcfg/poolcfg.y b/usr/src/cmd/pools/poolcfg/poolcfg.y
new file mode 100644
index 0000000000..3fdd526805
--- /dev/null
+++ b/usr/src/cmd/pools/poolcfg/poolcfg.y
@@ -0,0 +1,1596 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Overview of poolcfg(1)
+ *
+ * poolcfg(1) implements a small grammar for manipulating pools configurations.
+ * yacc(1) is used to generate the parser and poolcfg.l contains a simple lexer
+ * (generted by lex(1)) to perform lexical processsing of the input.
+ *
+ * Refer to the poolcfg(1) manpage for more details of the grammar.
+ *
+ * The parser is designed so that all operations implement the same interface.
+ * This allows the parser to simply build up the command (using the cmd
+ * variable) by storing arguments and a pointer to the desired function in the
+ * cmd. The command is executed when the commands production is matched.
+ *
+ * Properties and associations are stored in simple linked lists and processed
+ * in the order submitted by the user.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <locale.h>
+#include <libintl.h>
+#include <sys/utsname.h>
+
+#include <pool.h>
+#include "utils.h"
+#include "poolcfg.h"
+
+
+
+#define USAGE1 \
+"Usage:\n" \
+"%s -h\n" \
+"%s -c command [ -d | [ file ] ]\n" \
+"%s -f command-file [-d | [ file ] ]\n\n"
+
+#define USAGE2 \
+"command:\n" \
+" info [entity name]\n" \
+" display configuration (or specified portion) in readable form\n" \
+" create entity name [property-list]\n" \
+" make an entity of the specified type and name\n" \
+" destroy entity name\n" \
+" remove the specified entity\n" \
+" modify entity name [property-list]\n" \
+" change the listed properties on the named entity\n" \
+" associate pool name [resource-list]\n" \
+" connect one or more resources to a pool, or replace one or more\n" \
+" existing connections\n" \
+" transfer to resource name [component-list]\n" \
+" transfer one or more discreet components to a resource\n" \
+" transfer [quantity] from resource src to tgt\n" \
+" transfer a resource quantity from src to tgt\n" \
+" transfer [quantity] to resource tgt from src\n" \
+" transfer a resource quantity to tgt from src\n" \
+" discover\n" \
+" create a system entity, with one pool entity and resources to\n" \
+" match current system configuration\n" \
+" rename entity old_name to new_name\n" \
+" change the name of the entity on the system to its new name\n\n" \
+"property-list:\n" \
+" ( proptype name = value [ ; proptype name = value ]* )\n" \
+" where multiple definitions in the sentence for a given\n" \
+" proptype, name pair are ignored; the last one provided is used.\n" \
+" For property deletion, use \"~ proptype name\"\n\n" \
+"resource-list:\n" \
+" ( resource name [; resource name ] )\n" \
+" where multiple uses of a resource are ignored; the last provided\n" \
+" is the one used.\n" \
+" There is no deletion syntax for resource lists.\n" \
+"component-list:\n" \
+" ( cpu id [; cpu id ] )\n" \
+" where multiple uses of the same component cause the last provided\n" \
+" to be the one used.\n" \
+" There is no deletion syntax for component lists.\n" \
+"entity:\n" \
+" system | pool | pset | cpu\n" \
+" where cpu is only valid for transfer, info and modify commands.\n" \
+"resource:\n" \
+" pset\n\n" \
+"proptype:\n" \
+" boolean | int | uint | string | float\n\n"
+
+int dofile = PO_FALSE; /* poolcfg.l uses this for errors */
+int conf_edit_error = POE_OK; /* cached error for error reporting */
+int conf_edit_errno = 0; /* cached errno for error reporting */
+int conf_list_error = POE_OK; /* cached error for error reporting */
+int conf_list_errno = 0; /* cached errno for error reporting */
+static const char cmdname[] = "poolcfg";
+static const char cmd_options[] = "c:df:h";
+static void usage(int);
+static const char *max_suffix = ".max";
+static const char *min_suffix = ".min";
+
+static const char *conf_file = NULL; /* Location of target config */
+static cmd_t *cmd = NULL; /* Command being processed */
+static pool_conf_t *conf = NULL; /* Config to be processed */
+static int edited = PO_FALSE; /* Has the configuration been changed */
+
+/* yacc externals */
+extern FILE *yyin;
+extern int yydebug;
+extern void yyerror(char *s);
+
+/* Utility functions */
+static void arg_parse(const char *);
+static void file_parse(const char *);
+static cmd_t *alloc_cmd(void);
+static prop_t *alloc_prop(prop_op_t);
+static assoc_t *alloc_assoc(int, const char *);
+static void free_cmd(cmd_t *);
+static void check_conf_name(cmd_t *);
+static void prop_list_walk(cmd_t *, pool_elem_t *);
+static void assoc_list_walk(cmd_t *, pool_t *);
+static void transfer_list_walk(cmd_t *, pool_resource_t *);
+static void terminate(void);
+static pool_component_t *get_cpu(const char *);
+static void process_min_max(pool_resource_t *);
+
+/* Info Commands */
+static void parser_conf_info(cmd_t *);
+static void parser_pool_info(cmd_t *);
+static void parser_resource_info(cmd_t *, const char *);
+static void parser_pset_info(cmd_t *);
+static void parser_cpu_info(cmd_t *);
+
+/* Create Commands */
+static void parser_conf_create(cmd_t *);
+static void parser_pool_create(cmd_t *);
+static void parser_resource_create(cmd_t *, const char *);
+static void parser_pset_create(cmd_t *);
+
+/* Destroy Commands */
+static void parser_conf_destroy(cmd_t *);
+static void parser_pool_destroy(cmd_t *);
+static void parser_resource_destroy(cmd_t *, const char *);
+static void parser_pset_destroy(cmd_t *);
+
+/* Modify Commands */
+static void parser_conf_modify(cmd_t *);
+static void parser_pool_modify(cmd_t *);
+static void parser_resource_modify(cmd_t *, const char *);
+static void parser_pset_modify(cmd_t *);
+static void parser_cpu_modify(cmd_t *);
+
+/* Associate Commands */
+static void parser_pool_associate(cmd_t *);
+
+/* Assign Commands */
+static void parser_resource_xtransfer(cmd_t *);
+static void parser_resource_transfer(cmd_t *);
+
+/* Discover Commands */
+static void parser_conf_discover(cmd_t *);
+
+/* Rename Commands */
+static void parser_rename(cmd_t *, pool_elem_t *, const char *);
+static void parser_conf_rename(cmd_t *);
+static void parser_pool_rename(cmd_t *);
+static void parser_pset_rename(cmd_t *);
+
+
+%}
+
+%union {
+ double dval;
+ uint64_t uval;
+ int64_t ival;
+ char *sval;
+ uchar_t bval;
+ cmd_t *cmd;
+ prop_t *prop;
+ pv_u val;
+ assoc_t *assoc;
+}
+
+%start commands
+
+%token PCC_INFO PCC_CREATE PCC_DESTROY PCC_MODIFY PCC_ASSOC PCC_DISC PCC_RENAME
+%token PCC_TRANSFER
+%token PCK_FROM PCK_TO PCK_OPENLST PCK_CLOSELST PCK_SEPLST PCK_ASSIGN PCK_UNDEF
+PCK_COMMAND
+%token PCV_FILENAME PCV_SYMBOL PCV_VAL_INT PCV_VAL_UINT PCV_VAL_FLOAT
+PCV_VAL_STRING PCV_VAL_BOOLEAN
+%token PCT_INT PCT_UINT PCT_BOOLEAN PCT_FLOAT PCT_STRING
+%token PCE_SYSTEM PCE_POOL PCE_PSET PCE_CPU
+
+%type <ival> PCV_VAL_INT
+%type <uval> PCV_VAL_UINT
+%type <bval> PCV_VAL_BOOLEAN
+%type <dval> PCV_VAL_FLOAT
+%type <sval> PCV_VAL_STRING
+%type <sval> PCV_SYMBOL
+%type <sval> PCV_FILENAME
+
+%type <ival> PCC_INFO
+%type <ival> PCE_SYSTEM PCE_POOL PCE_PSET PCE_CPU
+%type <ival> entity proptype info_entity modify_entity
+%type <sval> name src tgt
+%type <cmd> command
+%type <cmd> list_command info_command edit_command create_command
+destroy_command modify_command associate_command discover_command
+rename_command transfer_command transfer_qty transfer_components
+%type <prop> prop_remove prop_assign prop_op prop_ops property_list
+%type <assoc> resource_assign resource_assigns resource_list
+%type <assoc> component_assign component_assigns component_list
+%type <val> value
+%type <ival> resource component
+
+%%
+
+commands: command
+ {
+ if ($1->cmd != NULL)
+ $1->cmd($1);
+ free_cmd($1);
+ }
+ | commands command
+ {
+ if ($2->cmd != NULL)
+ $2->cmd($2);
+ free_cmd($2);
+ }
+ | command error { YYERROR;};
+
+command: list_command
+ | edit_command
+ {
+ if (conf_edit_error != POE_OK) {
+ if ($1->cmd != parser_conf_create &&
+ $1->cmd != parser_conf_discover) {
+ die(gettext(ERR_CONF_LOAD), conf_file,
+ get_errstr_err(conf_edit_error,
+ conf_edit_errno));
+ }
+ }
+ edited = PO_TRUE;
+ };
+
+list_command: info_command
+ {
+ if (conf_list_error != POE_OK) {
+ if ($1->cmd != parser_conf_create &&
+ $1->cmd != parser_conf_discover) {
+ die(gettext(ERR_CONF_LOAD), conf_file,
+ get_errstr_err(conf_list_error,
+ conf_list_errno));
+ }
+ }
+ }
+ | discover_command {conf_list_error = conf_edit_error = POE_OK;};
+
+edit_command: create_command
+ | destroy_command
+ | modify_command
+ | associate_command
+ | transfer_command
+ | rename_command;
+
+info_command: PCC_INFO
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_conf_info;
+ }
+ | PCC_INFO info_entity name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ switch ($2) {
+ case PCE_SYSTEM:
+ $$->cmd = &parser_conf_info;
+ break;
+ case PCE_POOL:
+ $$->cmd = &parser_pool_info;
+ break;
+ case PCE_PSET:
+ $$->cmd = &parser_pset_info;
+ break;
+ case PCE_CPU:
+ $$->cmd = &parser_cpu_info;
+ break;
+ default:
+ warn(gettext(ERR_UNKNOWN_ENTITY), $2);
+ YYERROR;
+ }
+ $$->cmd_tgt1 = $3;
+ };
+
+create_command: PCC_CREATE entity name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ switch ($2) {
+ case PCE_SYSTEM:
+ $$->cmd = &parser_conf_create;
+ break;
+ case PCE_POOL:
+ $$->cmd = &parser_pool_create;
+ break;
+ case PCE_PSET:
+ $$->cmd = &parser_pset_create;
+ break;
+ default:
+ warn(gettext(ERR_UNKNOWN_ENTITY), $2);
+ YYERROR;
+ }
+ $$->cmd_tgt1 = $3;
+ }
+ | create_command property_list;
+
+destroy_command: PCC_DESTROY entity name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ switch ($2) {
+ case PCE_SYSTEM:
+ $$->cmd = &parser_conf_destroy;
+ break;
+ case PCE_POOL:
+ $$->cmd = &parser_pool_destroy;
+ break;
+ case PCE_PSET:
+ $$->cmd = &parser_pset_destroy;
+ break;
+ default:
+ warn(gettext(ERR_UNKNOWN_ENTITY), $2);
+ YYERROR;
+ }
+ $$->cmd_tgt1 = $3;
+ };
+
+modify_command: PCC_MODIFY modify_entity name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ switch ($2) {
+ case PCE_SYSTEM:
+ $$->cmd = &parser_conf_modify;
+ break;
+ case PCE_POOL:
+ $$->cmd = &parser_pool_modify;
+ break;
+ case PCE_PSET:
+ $$->cmd = &parser_pset_modify;
+ break;
+ case PCE_CPU:
+ $$->cmd = &parser_cpu_modify;
+ break;
+ default:
+ warn(gettext(ERR_UNKNOWN_ENTITY), $2);
+ YYERROR;
+ }
+ $$->cmd_tgt1 = $3;
+ }
+ | modify_command property_list;
+
+associate_command: PCC_ASSOC PCE_POOL name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_pool_associate;
+ cmd->cmd_tgt1 = $3;
+ }
+ | associate_command resource_list;
+
+transfer_command: transfer_qty
+ | transfer_components;
+
+transfer_components: PCC_TRANSFER PCK_TO PCE_PSET name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_resource_xtransfer;
+ cmd->cmd_tgt1 = $4;
+ }
+ | transfer_components component_list;
+
+transfer_qty: PCC_TRANSFER PCV_VAL_UINT PCK_FROM PCE_PSET src PCK_TO tgt
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_resource_transfer;
+ cmd->cmd_tgt1 = $5;
+ cmd->cmd_tgt2 = $7;
+ cmd->cmd_qty = $2;
+ }
+ | PCC_TRANSFER PCV_VAL_UINT PCK_TO PCE_PSET tgt PCK_FROM src
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_resource_transfer;
+ cmd->cmd_tgt1 = $7;
+ cmd->cmd_tgt2 = $5;
+ cmd->cmd_qty = $2;
+ };
+
+discover_command: PCC_DISC
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ $$->cmd = &parser_conf_discover;
+ };
+
+rename_command: PCC_RENAME entity name PCK_TO name
+ {
+ if (($$ = alloc_cmd()) == NULL)
+ YYERROR;
+ cmd = $$;
+ switch ($2) {
+ case PCE_SYSTEM:
+ $$->cmd = &parser_conf_rename;
+ break;
+ case PCE_POOL:
+ $$->cmd = &parser_pool_rename;
+ break;
+ case PCE_PSET:
+ $$->cmd = &parser_pset_rename;
+ break;
+ default:
+ warn(gettext(ERR_UNKNOWN_ENTITY), $2);
+ YYERROR;
+ }
+ $$->cmd_tgt1 = $3;
+ $$->cmd_tgt2 = $5;
+ };
+
+modify_entity: entity
+ | PCE_CPU {$$ = PCE_CPU;};
+
+info_entity: entity
+ | PCE_CPU {$$ = PCE_CPU;};
+
+entity: PCE_SYSTEM {$$ = PCE_SYSTEM;}
+ | PCE_POOL {$$ = PCE_POOL;}
+ | PCE_PSET {$$ = PCE_PSET;};
+
+name: PCV_SYMBOL;
+
+src: PCV_SYMBOL;
+
+tgt: PCV_SYMBOL;
+
+value: PCV_VAL_INT { $$.i = $1;}
+ | PCV_VAL_UINT { $$.u = $1;}
+ | PCV_VAL_FLOAT { $$.d = $1;}
+ | PCV_VAL_BOOLEAN { $$.b = $1;}
+ | PCV_VAL_STRING { $$.s = $1;};
+
+prop_remove: PCK_UNDEF proptype name
+ {
+ if (($$ = alloc_prop(po_remove)) == NULL)
+ YYERROR;
+ $$->prop_name = $3;
+ };
+
+prop_op: prop_assign
+ | prop_remove;
+
+prop_ops: prop_op
+ {
+ prop_t *prop = NULL;
+ prop_t *prev = NULL;
+
+ for (prop = cmd->cmd_prop_list; prop != NULL;
+ prop = prop->prop_next)
+ prev = prop; /* Find end of list */
+ if (prev != NULL)
+ prev->prop_next = $1;
+ else
+ cmd->cmd_prop_list = $1;
+ $$ = cmd->cmd_prop_list;
+ }
+ | prop_ops PCK_SEPLST prop_op
+ {
+ prop_t *prop = NULL;
+ prop_t *prev = NULL;
+
+ for (prop = cmd->cmd_prop_list; prop != NULL;
+ prop = prop->prop_next)
+ prev = prop; /* Find end of list */
+ if (prev != NULL)
+ prev->prop_next = $3;
+ else
+ cmd->cmd_prop_list = $3;
+ $$ = cmd->cmd_prop_list;
+
+ };
+
+prop_assign: proptype name PCK_ASSIGN value
+ {
+ if (($$ = alloc_prop(po_create)) == NULL)
+ YYERROR;
+ $$->prop_name = $2;
+ switch ($1) {
+ case PCT_INT:
+ pool_value_set_int64($$->prop_value, $4.i);
+ break;
+ case PCT_UINT:
+ pool_value_set_uint64($$->prop_value, $4.u);
+ break;
+ case PCT_BOOLEAN:
+ pool_value_set_bool($$->prop_value, $4.b);
+ break;
+ case PCT_FLOAT:
+ pool_value_set_double($$->prop_value, $4.d);
+ break;
+ case PCT_STRING:
+ pool_value_set_string($$->prop_value, $4.s);
+ break;
+ }
+ };
+
+property_list: PCK_OPENLST prop_ops PCK_CLOSELST
+ {
+ $$ = $2;
+ };
+
+resource_assigns: resource_assign
+ {
+ assoc_t *assoc = NULL;
+ assoc_t *prev = NULL;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next)
+ prev = assoc; /* Find end of list */
+ if (prev != NULL)
+ prev->assoc_next = $1;
+ else
+ cmd->cmd_assoc_list = $1;
+ $$ = cmd->cmd_assoc_list;
+ }
+
+ | resource_assigns PCK_SEPLST resource_assign
+ {
+ assoc_t *assoc = NULL;
+ assoc_t *prev = NULL;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next)
+ prev = assoc; /* Find end of list */
+ if (prev != NULL)
+ prev->assoc_next = $3;
+ $$ = $3;
+ };
+
+resource_assign: resource name
+ {
+ if (($$ = alloc_assoc($1, $2)) == NULL)
+ YYERROR;
+ };
+
+resource: PCE_PSET {$$ = PCE_PSET;};
+
+resource_list: PCK_OPENLST resource_assigns PCK_CLOSELST
+ {
+ $$ = $2;
+ };
+
+component_assigns: component_assign
+ {
+ assoc_t *assoc = NULL;
+ assoc_t *prev = NULL;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next)
+ prev = assoc; /* Find end of list */
+ if (prev != NULL)
+ prev->assoc_next = $1;
+ else
+ cmd->cmd_assoc_list = $1;
+ $$ = cmd->cmd_assoc_list;
+ }
+
+ | component_assigns PCK_SEPLST component_assign
+ {
+ assoc_t *assoc = NULL;
+ assoc_t *prev = NULL;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next)
+ prev = assoc; /* Find end of list */
+ if (prev != NULL)
+ prev->assoc_next = $3;
+ $$ = $3;
+ };
+
+component_list: PCK_OPENLST component_assigns PCK_CLOSELST
+ {
+ $$ = $2;
+ };
+
+component_assign: component name
+ {
+ if (($$ = alloc_assoc($1, $2)) == NULL)
+ YYERROR;
+ };
+
+component: PCE_CPU {$$ = PCE_CPU;};
+
+proptype: PCT_INT {$$ = PCT_INT;}
+ | PCT_UINT {$$ = PCT_UINT;}
+ | PCT_BOOLEAN {$$ = PCT_BOOLEAN;}
+ | PCT_FLOAT {$$ = PCT_FLOAT;}
+ | PCT_STRING {$$ = PCT_STRING;};
+
+%%
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int opt;
+ int docmd = PO_FALSE;
+
+ (void) getpname(argv[0]);
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+ if (atexit(terminate) != 0) {
+ die(gettext(ERR_SET_TERM), get_errstr());
+ }
+
+ conf_file = pool_static_location();
+
+ yydebug = 0;
+ while ((opt = getopt(argc, argv, cmd_options)) != (int)EOF) {
+
+ switch (opt) {
+ case 'c': /* Process command line */
+ if (dofile == PO_TRUE)
+ usage(1);
+ arg_parse(optarg);
+ docmd = PO_TRUE;
+ break;
+ case 'd': /* Manipulate dynamic configuration */
+ conf_file = pool_dynamic_location();
+ break;
+ case 'f': /* Process command file */
+ if (docmd == PO_TRUE)
+ usage(1);
+ file_parse(optarg);
+ dofile = PO_TRUE;
+ break;
+ case 'h':
+ usage(2);
+ break;
+ case '?':
+ default:
+ usage(1);
+ break;
+ }
+ }
+ if (docmd == PO_FALSE && dofile == PO_FALSE)
+ usage(1);
+
+ if (optind == argc - 1) {
+ if (strcmp(conf_file, pool_dynamic_location()) == 0)
+ usage(1);
+ conf_file = argv[optind];
+ } else if (optind < argc - 1)
+ usage(1);
+
+ if ((conf = pool_conf_alloc()) == NULL) {
+ die(gettext(ERR_ALLOC_ELEMENT), gettext(CONFIGURATION),
+ get_errstr());
+ }
+ /*
+ * Opening a conf is complex, since we may be opening one of the
+ * following:
+ * - An existing configuration that we can modify
+ * - An existing configuration that we can't modify
+ * - A new configuration that we can modify
+ * - A new configuration that we can't modify
+ * The parser_conf_discover() function closes the file and reopens
+ * in PO_CREAT mode, so we only need be concerned here with the
+ * first two cases.
+ * Always try to open RDWR, if fail try RDONLY. Don't check
+ * if that fails, since we may be trying to discover a configuration
+ * in which case it's valid for both open attempts to fail. Later, when
+ * processing commands, if we don't have a valid configuration and
+ * we are trying to process a command which isn't a create or a discover
+ * we will fail the command as there is no valid configuration to
+ * work with.
+ */
+ if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) {
+ conf_edit_error = pool_error();
+ conf_edit_errno = errno;
+ if (pool_conf_open(conf, conf_file, PO_RDONLY) != 0) {
+ conf_list_error = pool_error();
+ conf_list_errno = errno;
+ }
+ }
+
+ if (yyparse() == 0) {
+ if (pool_conf_status(conf) >= POF_VALID) {
+ if (pool_conf_validate(conf, POV_STRICT) == PO_FAIL) {
+ die(gettext(ERR_VALIDATION_FAILED),
+ get_errstr());
+ }
+ /*
+ * If the user attempted to change the configuration,
+ * then we should try to save the changes.
+ */
+ if (edited == PO_TRUE) {
+ if (pool_conf_commit(conf, 0) == PO_FAIL) {
+ die(gettext(ERR_CONFIG_SAVE_FAILED),
+ get_errstr());
+ }
+ }
+ pool_conf_close(conf);
+ }
+ } else {
+ die(gettext(ERR_CMDPARSE_FAILED));
+ }
+
+ /*
+ * Cleanup is performed in terminate(), using atexit
+ */
+ return (0);
+}
+
+/*
+ * Info Commands
+ * Invoke the appropriate libpool info function and display the returned
+ * information.
+ */
+static void
+parser_conf_info(cmd_t *cmd)
+{
+ char *info_buf;
+ const char *tgt = cmd->cmd_tgt1;
+ pool_value_t *pv = NULL;
+ pool_elem_t *pe;
+
+ if ((pe = pool_conf_to_elem(conf)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+
+ if (tgt != NULL)
+ check_conf_name(cmd);
+ else {
+ if ((pv = pool_value_alloc()) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+ if (pool_get_property(conf, pe, "system.name", pv) ==
+ POC_INVAL ||
+ pool_value_get_string(pv, &tgt) != PO_SUCCESS)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+ }
+ if ((info_buf = pool_conf_info(conf, PO_TRUE)) == NULL) {
+ die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION),
+ tgt, get_errstr());
+ }
+ if (pv != NULL) {
+ pool_value_free(pv);
+ }
+ (void) printf("%s\n", info_buf);
+ free(info_buf);
+}
+
+static void
+parser_pool_info(cmd_t *cmd)
+{
+ pool_t *pool;
+ char *info_buf;
+
+ if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+
+ if ((info_buf = pool_info(conf, pool, PO_TRUE)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(POOL),
+ cmd->cmd_tgt1, get_errstr());
+ (void) printf("%s\n", info_buf);
+ free(info_buf);
+}
+
+static void
+parser_resource_info(cmd_t *cmd, const char *type)
+{
+ pool_resource_t *resource;
+ char *info_buf;
+
+ if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
+ cmd->cmd_tgt1, get_errstr());
+
+ if ((info_buf = pool_resource_info(conf, resource, PO_TRUE)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(RESOURCE),
+ cmd->cmd_tgt1, get_errstr());
+ (void) printf("%s\n", info_buf);
+ free(info_buf);
+}
+
+static void
+parser_pset_info(cmd_t *cmd)
+{
+ parser_resource_info(cmd, PSET);
+}
+
+static void
+parser_cpu_info(cmd_t *cmd)
+{
+ pool_component_t *comp;
+ char *info_buf;
+
+ if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
+ cmd->cmd_tgt1, get_errstr());
+ if ((info_buf = pool_component_info(conf, comp, PO_TRUE)) == NULL) {
+ die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CPU),
+ cmd->cmd_tgt1, get_errstr());
+ }
+ (void) printf("%s\n", info_buf);
+ free(info_buf);
+}
+
+/*
+ * Create Commands
+ * Invoke the appropriate libpool create function and perform any requested
+ * property operations.
+ */
+static void
+parser_conf_create(cmd_t *cmd)
+{
+ const char *tmp_name;
+ pool_elem_t *pe;
+
+ if (conf != NULL && pool_conf_status(conf) >= POF_VALID)
+ pool_conf_close(conf);
+ if (pool_conf_open(conf, conf_file, PO_CREAT) != 0) {
+ die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
+ cmd->cmd_tgt1, get_errstr());
+ }
+ tmp_name = cmd->cmd_tgt1;
+ cmd->cmd_tgt1 = cmd->cmd_tgt2;
+ cmd->cmd_tgt2 = tmp_name;
+ parser_conf_rename(cmd);
+ if ((pe = pool_conf_to_elem(conf)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+ prop_list_walk(cmd, pe);
+}
+
+static void
+parser_pool_create(cmd_t *cmd)
+{
+ pool_t *pool;
+
+ if ((pool = pool_create(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_CREATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+ prop_list_walk(cmd, pool_to_elem(conf, pool));
+}
+
+static void
+parser_resource_create(cmd_t *cmd, const char *type)
+{
+ pool_resource_t *resource;
+
+ if ((resource = pool_resource_create(conf, type, cmd->cmd_tgt1))
+ == NULL)
+ die(gettext(ERR_CREATE_ELEMENT), type, cmd->cmd_tgt1,
+ get_errstr());
+
+ process_min_max(resource);
+
+ prop_list_walk(cmd, pool_resource_to_elem(conf, resource));
+}
+
+static void
+parser_pset_create(cmd_t *cmd)
+{
+ parser_resource_create(cmd, PSET);
+}
+
+/*
+ * Rename Commands
+ * Rename the target by calling pool_put_property for the name property.
+ */
+static void
+parser_rename(cmd_t *cmd, pool_elem_t *pe, const char *name)
+{
+ pool_value_t *pv;
+
+ if ((pv = pool_value_alloc()) == NULL) {
+ die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE),
+ get_errstr());
+ }
+ pool_value_set_string(pv, cmd->cmd_tgt2);
+ if (pool_put_property(conf, pe, name, pv) != 0)
+ die(gettext(ERR_PUT_PROPERTY), name, get_errstr());
+ pool_value_free(pv);
+}
+
+static void
+parser_conf_rename(cmd_t *cmd)
+{
+ pool_elem_t *pe;
+
+ if ((pe = pool_conf_to_elem(conf)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+
+ if (cmd->cmd_tgt1 != NULL)
+ check_conf_name(cmd);
+
+ parser_rename(cmd, pe, SYSTEM_NAME);
+}
+
+static void
+parser_pool_rename(cmd_t *cmd)
+{
+ pool_t *pool;
+
+ if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+
+ parser_rename(cmd, pool_to_elem(conf, pool), POOL_NAME);
+}
+
+static void
+parser_pset_rename(cmd_t *cmd)
+{
+ pool_resource_t *resource;
+
+ if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET), cmd->cmd_tgt1,
+ get_errstr());
+
+ parser_rename(cmd, pool_resource_to_elem(conf, resource), PSET_NAME);
+}
+
+/*
+ * Destroy Commands
+ * Invoke the appropriate libpool destroy function to remove the target of the
+ * command from the configuration.
+ */
+static void
+parser_conf_destroy(cmd_t *cmd)
+{
+ if (cmd->cmd_tgt1 != NULL)
+ check_conf_name(cmd);
+
+ if (pool_conf_remove(conf) != 0)
+ die(gettext(ERR_DESTROY_ELEMENT), gettext(CONFIGURATION),
+ cmd->cmd_tgt1, get_errstr());
+}
+
+static void
+parser_pool_destroy(cmd_t *cmd)
+{
+ pool_t *pool;
+
+ if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+
+ if (pool_destroy(conf, pool) != 0)
+ die(gettext(ERR_DESTROY_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+}
+
+static void
+parser_resource_destroy(cmd_t *cmd, const char *type)
+{
+ pool_resource_t *resource;
+
+ if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), type, cmd->cmd_tgt1,
+ get_errstr());
+
+ if (pool_resource_destroy(conf, resource) != 0)
+ die(gettext(ERR_DESTROY_ELEMENT), type, cmd->cmd_tgt1,
+ get_errstr());
+}
+
+static void
+parser_pset_destroy(cmd_t *cmd)
+{
+ parser_resource_destroy(cmd, PSET);
+}
+
+/*
+ * Modify Commands
+ * Perform any requested property operations.
+ */
+static void
+parser_conf_modify(cmd_t *cmd)
+{
+ pool_elem_t *pe;
+
+ if ((pe = pool_conf_to_elem(conf)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+
+ if (cmd->cmd_tgt1 != NULL)
+ check_conf_name(cmd);
+
+ prop_list_walk(cmd, pe);
+}
+
+static void
+parser_pool_modify(cmd_t *cmd)
+{
+ pool_t *pool;
+
+ if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+ prop_list_walk(cmd, pool_to_elem(conf, pool));
+}
+
+static void
+parser_resource_modify(cmd_t *cmd, const char *type)
+{
+ pool_resource_t *resource;
+
+ if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
+ cmd->cmd_tgt1, get_errstr());
+
+ process_min_max(resource);
+
+ prop_list_walk(cmd, pool_resource_to_elem(conf, resource));
+}
+
+static void
+parser_pset_modify(cmd_t *cmd)
+{
+ parser_resource_modify(cmd, PSET);
+}
+
+static void
+parser_cpu_modify(cmd_t *cmd)
+{
+ pool_component_t *comp;
+
+ if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
+ cmd->cmd_tgt1, get_errstr());
+ prop_list_walk(cmd, pool_component_to_elem(conf, comp));
+}
+
+/*
+ * Discover Commands
+ * Invoke the libpool pool_conf_open function so that discovery will be
+ * performed.
+ */
+
+/*ARGSUSED*/
+static void
+parser_conf_discover(cmd_t *cmd)
+{
+ struct utsname utsname;
+
+ if (strcmp(conf_file, pool_dynamic_location()) == 0)
+ return;
+
+ if (uname(&utsname) < 0)
+ die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
+ "unknown", get_errstr());
+
+ if (conf != NULL && pool_conf_status(conf) >= POF_VALID)
+ pool_conf_close(conf);
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != 0) {
+ die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
+ utsname.nodename, get_errstr());
+ }
+ if (pool_conf_export(conf, conf_file, POX_NATIVE) != 0) {
+ die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
+ utsname.nodename, get_errstr());
+ }
+ (void) pool_conf_close(conf);
+ if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) {
+ die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
+ utsname.nodename, get_errstr());
+ }
+}
+
+/*
+ * Associate Commands
+ * Walk the list of specified associations so that the target pool will be
+ * associated with the required resources.
+ */
+
+static void
+parser_pool_associate(cmd_t *cmd)
+{
+ pool_t *pool;
+
+ if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
+ get_errstr());
+ assoc_list_walk(cmd, pool);
+}
+
+/*
+ * Assign Commands
+ * Walk the list of specified assignations so that the required
+ * components will be assigned to the target resource.
+ */
+
+static void
+parser_resource_xtransfer(cmd_t *cmd)
+{
+ pool_resource_t *resource;
+
+ if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
+ cmd->cmd_tgt1, get_errstr());
+ transfer_list_walk(cmd, resource);
+}
+
+/*
+ * Transfer Commands
+ * Transfer the specified quantity of resource between the src and the tgt.
+ */
+
+static void
+parser_resource_transfer(cmd_t *cmd)
+{
+ pool_resource_t *src;
+ pool_resource_t *tgt;
+
+ if ((src = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
+ cmd->cmd_tgt1, get_errstr());
+ if ((tgt = pool_get_resource(conf, PSET, cmd->cmd_tgt2)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
+ cmd->cmd_tgt2, get_errstr());
+ if (pool_resource_transfer(conf, src, tgt, cmd->cmd_qty) != PO_SUCCESS)
+ die(gettext(ERR_XFER_QUANTITY), cmd->cmd_qty,
+ cmd->cmd_tgt1, cmd->cmd_tgt2, get_errstr());
+}
+
+/*
+ * arg_parse() puts the parser into command parsing mode. Create a tmpfile
+ * and instruct the parser to read instructions from this location by setting
+ * yyin to the value returned by tmpfile. Write the command into the file.
+ * Then seek back to to the start of the file so that the parser can read
+ * the instructions.
+ */
+static void
+arg_parse(const char *command)
+{
+ if ((yyin = tmpfile()) == NULL)
+ die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
+ if (fwrite(command, strlen(command), 1, yyin) != 1)
+ die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
+ if (fseek(yyin, 0, SEEK_SET) != 0)
+ die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
+}
+
+/*
+ * file_parse() puts the parser into command file parsing mode. Firstly check
+ * to see if the user wishes to parse from standard input, if so do nothing.
+ * Attempt to open the specified file and instruct the parser to read
+ * instructions from this location by setting yyin to the value returned by
+ * fopen.
+ */
+static void
+file_parse(const char *file)
+{
+ if (strcmp(file, "-") == 0)
+ return;
+
+ if ((yyin = fopen(file, "r")) == NULL) {
+ die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
+ }
+}
+
+/*
+ * free_cmd() releases the resources associated with the supplied cmd parameter.
+ */
+static void
+free_cmd(cmd_t *cmd)
+{
+ prop_t *prop = cmd->cmd_prop_list;
+ assoc_t *assoc = cmd->cmd_assoc_list;
+
+ free((void *)cmd->cmd_tgt1);
+ free((void *)cmd->cmd_tgt2);
+ while (prop != NULL) {
+ prop_t *tmp = prop;
+ prop = prop->prop_next;
+ pool_value_free(tmp->prop_value);
+ free((void *)tmp->prop_name);
+ free(tmp);
+ }
+ while (assoc != NULL) {
+ assoc_t *tmp = assoc;
+ assoc = assoc->assoc_next;
+ free((void *)tmp->assoc_name);
+ free(tmp);
+ }
+ free(cmd);
+}
+
+/*
+ * alloc_cmd() allocates the required resources for a cmd_t. On failure, a
+ * warning is issued and NULL is returned.
+ */
+static cmd_t *
+alloc_cmd(void)
+{
+ cmd_t *cmd;
+
+ if ((cmd = malloc(sizeof (cmd_t))) == NULL) {
+ warn(gettext(ERR_CMD_LINE_ALLOC));
+ return (NULL);
+ }
+
+ (void) memset(cmd, 0, sizeof (cmd_t));
+
+ return (cmd);
+}
+
+/*
+ * alloc_prop() allocates the required resources for a prop_t. On failure, a
+ * warning is issued and NULL is returned. The prop_t is initialised with
+ * the prop_op_t parameter.
+ */
+static prop_t *
+alloc_prop(prop_op_t op)
+{
+ prop_t *prop;
+
+ if ((prop = malloc(sizeof (prop_t))) == NULL) {
+ warn(gettext(ERR_PROP_ALLOC));
+ return (NULL);
+ }
+
+ (void) memset(prop, 0, sizeof (prop_t));
+ if ((prop->prop_value = pool_value_alloc()) == NULL) {
+ warn(gettext(ERR_PROP_ALLOC));
+ free(prop);
+ return (NULL);
+ }
+ prop->prop_op = op;
+ return (prop);
+}
+
+/*
+ * alloc_assoc() allocates the required resources for an assoc_t. On failure, a
+ * warning is issued and NULL is returned. The assoc_t is initialised with
+ * the type and name of the association.
+ */
+static assoc_t *
+alloc_assoc(int type, const char *name)
+{
+ assoc_t *assoc;
+
+ if ((assoc = malloc(sizeof (assoc_t))) == NULL) {
+ warn(gettext(ERR_ASSOC_ALLOC));
+ return (NULL);
+ }
+ (void) memset(assoc, 0, sizeof (assoc_t));
+ assoc->assoc_type = type;
+ assoc->assoc_name = name;
+ return (assoc);
+}
+
+/*
+ * check_conf_name() ensures the the name of the system in the configuration
+ * which is being manipulated matches the name of the system in the command.
+ * If not, the command is terminated with an appropriate error message.
+ */
+static void
+check_conf_name(cmd_t *cmd)
+{
+ pool_value_t *pv;
+ const char *name;
+ pool_elem_t *pe;
+
+ if ((pe = pool_conf_to_elem(conf)) == NULL)
+ die(gettext(ERR_GET_ELEMENT_DETAILS),
+ gettext(CONFIGURATION), "unknown", get_errstr());
+
+
+ if ((pv = pool_value_alloc()) == NULL) {
+ die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE),
+ get_errstr());
+ }
+
+ if (pool_get_property(conf, pe, SYSTEM_NAME, pv)
+ == POC_INVAL)
+ die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME),
+ get_errstr());
+
+ if (pool_value_get_string(pv, &name) == PO_FAIL)
+ die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME),
+ get_errstr());
+
+ if (strcmp(cmd->cmd_tgt1, name) != 0) {
+ die(gettext(ERR_WRONG_SYSTEM_NAME), cmd->cmd_tgt1);
+ }
+ pool_value_free(pv);
+}
+
+/*
+ * usage() display brief or verbose help for the poolcfg(1) command.
+ */
+static void
+usage(int help)
+{
+ if (help >= 1)
+ (void) fprintf(stderr, gettext(USAGE1), cmdname, cmdname,
+ cmdname);
+ if (help >= 2)
+ (void) fprintf(stderr, gettext(USAGE2));
+ exit(E_USAGE);
+}
+
+/*
+ * prop_list_walk() walks the property manipulation requests and either puts
+ * or removes the property as appropriate.
+ */
+static void
+prop_list_walk(cmd_t *cmd, pool_elem_t *pe)
+{
+ prop_t *prop;
+
+ for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) {
+ switch (prop->prop_op) {
+ case po_create:
+ if (pool_put_property(conf, pe, prop->prop_name,
+ prop->prop_value) != 0)
+ die(gettext(ERR_PUT_PROPERTY),
+ prop->prop_name, get_errstr());
+ break;
+ case po_remove:
+ if (pool_rm_property(conf, pe, prop->prop_name) != 0)
+ die(gettext(ERR_REMOVE_PROPERTY),
+ prop->prop_name, get_errstr());
+ break;
+ }
+ }
+}
+
+/*
+ * assoc_list_walk() walks the resource association requests and attempts
+ * to associate the pool with the specified resource.
+ */
+static void
+assoc_list_walk(cmd_t *cmd, pool_t *pool)
+{
+ assoc_t *assoc;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next) {
+ pool_resource_t *resource;
+
+ switch (assoc->assoc_type) {
+ case PCE_PSET:
+ if ((resource = pool_get_resource(conf,
+ PSET, assoc->assoc_name)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET),
+ assoc->assoc_name, get_errstr());
+ break;
+ default:
+ die(gettext(ERR_UNKNOWN_RESOURCE),
+ assoc->assoc_type);
+ break;
+ }
+ if (pool_associate(conf, pool, resource) != 0)
+ die(gettext(ERR_ASSOC_RESOURCE), assoc->assoc_name,
+ get_errstr());
+ }
+}
+
+/*
+ * transfer_list_walk() walks the component assign requests and attempts
+ * to assign the component with the specified resource.
+ */
+static void
+transfer_list_walk(cmd_t *cmd, pool_resource_t *tgt)
+{
+ assoc_t *assoc;
+
+ for (assoc = cmd->cmd_assoc_list; assoc != NULL;
+ assoc = assoc->assoc_next) {
+ pool_component_t *comp;
+ pool_resource_t *src;
+ pool_component_t *xfer[2] = {NULL};
+
+ if ((comp = get_cpu(assoc->assoc_name)) == NULL)
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
+ assoc->assoc_name, get_errstr());
+ if ((src = pool_get_owning_resource(conf, comp)) == NULL)
+ die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT),
+ assoc->assoc_name, cmd->cmd_tgt1, get_errstr());
+ xfer[0] = comp;
+ if (pool_resource_xtransfer(conf, src, tgt, xfer) !=
+ PO_SUCCESS)
+ die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT),
+ assoc->assoc_name, cmd->cmd_tgt1, get_errstr());
+ }
+}
+
+/*
+ * terminate() is invoked when poolcfg exits. It cleans up
+ * configurations and closes the parser input stream.
+ */
+static void
+terminate(void)
+{
+ if (conf != NULL) {
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+ }
+ if (yyin != stdin)
+ (void) fclose(yyin);
+}
+
+/*
+ * get_cpu() takes the name of a CPU components and attempts to locate
+ * the element with that name. If the name is not formatted correctly
+ * (i.e. contains non-numeric characters) then the function terminates
+ * execution. If the components cannot be uniquely identified by the
+ * name, then NULL is returned.
+ */
+static pool_component_t *
+get_cpu(const char *name)
+{
+ pool_component_t **components;
+ uint_t nelem;
+ int64_t sysid;
+ pool_value_t *vals[3] = {NULL};
+ pool_component_t *ret;
+ const char *c;
+
+ if ((vals[0] = pool_value_alloc()) == NULL)
+ return (NULL);
+ if ((vals[1] = pool_value_alloc()) == NULL) {
+ pool_value_free(vals[0]);
+ return (NULL);
+ }
+ if (pool_value_set_string(vals[0], "cpu") != PO_SUCCESS ||
+ pool_value_set_name(vals[0], "type") != PO_SUCCESS) {
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ return (NULL);
+ }
+
+ for (c = name; *c != NULL; c++) {
+ if (!isdigit(*c)){
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
+ cmd->cmd_tgt1, gettext("CPU id should only contain "
+ "digits"));
+ }
+ }
+ sysid = strtoll(name, NULL, 0);
+ if (errno == ERANGE || errno == EINVAL) {
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ return (NULL);
+ }
+ pool_value_set_int64(vals[1], sysid);
+ if (pool_value_set_name(vals[1], CPU_SYSID) != PO_SUCCESS) {
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ return (NULL);
+ }
+ if ((components = pool_query_components(conf, &nelem, vals)) ==
+ NULL) {
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ return (NULL);
+ }
+ if (nelem != 1) {
+ free(components);
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ return (NULL);
+ }
+ pool_value_free(vals[0]);
+ pool_value_free(vals[1]);
+ ret = components[0];
+ free(components);
+ return (ret);
+}
+
+/*
+ * process_min_max() ensures that "min" and "max" properties are
+ * processed correctly by poolcfg. libpool enforces validity
+ * constraints on these properties and so it's important that changes
+ * to them are supplied to the library in the correct order.
+ */
+void
+process_min_max(pool_resource_t *resource)
+{
+ prop_t *minprop = NULL;
+ prop_t *maxprop = NULL;
+ prop_t *prop;
+
+ /*
+ * Before walking the list of properties, it has to be checked
+ * to ensure there are no clashes between min and max. If
+ * there are, then process these properties immediately.
+ */
+ for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) {
+ const char *pos;
+
+ if ((pos = strstr(prop->prop_name, min_suffix)) != NULL)
+ if (pos == prop->prop_name + strlen(prop->prop_name)
+ - 4)
+ minprop = prop;
+ if ((pos = strstr(prop->prop_name, max_suffix)) != NULL)
+ if (pos == prop->prop_name + strlen(prop->prop_name)
+ - 4)
+ maxprop = prop;
+ }
+ if (minprop && maxprop) {
+ pool_value_t *pv;
+ uint64_t smin, smax, dmax;
+ const char *type;
+ char *prop_name;
+ pool_elem_t *pe = pool_resource_to_elem(conf, resource);
+
+ if ((pv = pool_value_alloc()) == NULL)
+ die(gettext(ERR_NOMEM));
+
+ (void) pool_get_property(conf, pe, "type", pv);
+ (void) pool_value_get_string(pv, &type);
+
+ if ((prop_name = malloc(strlen(type) + strlen(max_suffix)
+ + 1)) == NULL)
+ die(gettext(ERR_NOMEM));
+
+ (void) sprintf(prop_name, "%s%s", type, max_suffix);
+ (void) pool_get_property(conf, pe, prop_name, pv);
+ (void) pool_value_get_uint64(pv, &dmax);
+
+ (void) pool_value_get_uint64(minprop->prop_value, &smin);
+
+ (void) pool_value_get_uint64(maxprop->prop_value, &smax);
+ if (smin < dmax) {
+ (void) pool_put_property(conf, pe,
+ minprop->prop_name, minprop->prop_value);
+ } else {
+ (void) pool_put_property(conf, pe,
+ maxprop->prop_name, maxprop->prop_value);
+ }
+ free((void *)prop_name);
+ pool_value_free(pv);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/Makefile b/usr/src/cmd/pools/poold/Makefile
new file mode 100644
index 0000000000..0dbe209449
--- /dev/null
+++ b/usr/src/cmd/pools/poold/Makefile
@@ -0,0 +1,144 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/Makefile
+
+
+PROG = poold
+OBJS = poold.o
+SRCS = $(OBJS:%.o=%.c)
+
+include $(SRC)/cmd/Makefile.cmd
+
+JAVA_SUBDIRS = com/sun/solaris/service/exception \
+ com/sun/solaris/service/kstat \
+ com/sun/solaris/service/locality \
+ com/sun/solaris/service/logging \
+ com/sun/solaris/service/pools \
+ com/sun/solaris/service/timer \
+ com/sun/solaris/domain/pools
+
+SUBDIRS = libjkstat \
+ libjlgrp \
+ libjpool \
+ libjsyslog
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+msg := TARGET = msg
+
+JARFILE = JPool.jar
+
+# JAVA_SUBDIRS and PACKAGEDOCS must be synchronized to ensure
+# javadoc documentation is generated for all packages.
+
+PACKAGEDOCS = com.sun.solaris.service.exception \
+ com.sun.solaris.service.kstat \
+ com.sun.solaris.service.locality \
+ com.sun.solaris.service.logging \
+ com.sun.solaris.service.pools \
+ com.sun.solaris.service.timer \
+ com.sun.solaris.domain.pools
+DOCDIR = doc
+ROOTUSRLIBDRP = $(ROOTLIB)/pool
+INCS = -I../common \
+ -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+LDLIBS += -lpool -L$(JAVA_ROOT)/jre/lib/$(MACH)/client -ljvm
+LDFLAGS += -R$(JAVA_ROOT)/jre/lib/$(MACH)/client
+LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2
+LINTLIBS += -L$(ROOTLIB) -lpool
+
+CPPFLAGS += $(INCS)
+ROOTCMDDIR = $(ROOT)/usr/lib/pool
+
+CLOBBERFILES += $(JARFILE)
+
+#
+# Definitions for message catalogue
+#
+POFILES = $(OBJS:.o=.po)
+
+#
+# Definitions for Java installs
+#
+
+JFILES = poold.properties $(JARFILE)
+ROOTJAVA = $(JFILES:%=$(ROOTUSRLIBDRP)/%)
+
+$(ROOTJAVA) := FILEMODE = 444
+$(ROOTJAVA) := OWNER = root
+$(ROOTJAVA) := GROUP = bin
+
+all: $(PROG) $(JAVA_SUBDIRS) $(JARFILE) \
+ .WAIT $(SUBDIRS)
+
+clean : $(JAVA_SUBDIRS) $(SUBDIRS)
+ -$(RM) $(OBJS) $(POFILES)
+
+lint: $(SUBDIRS)
+
+msg: $(POFILES)
+
+install: $(ROOTCMD) $(JAVA_SUBDIRS) $(JARFILE) \
+ .WAIT $(SUBDIRS) $(ROOTJAVA)
+
+$(JAVA_SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+ if [ "$(TARGET)" != "clean" ] && [ "$(TARGET)" != "clobber" ]; \
+ then \
+ if [ ! -f $(JARFILE) ]; \
+ then \
+ $(JAR) -cf $(JARFILE) $@/*class; \
+ else \
+ $(JAR) -uf $(JARFILE) $@/*class; \
+ fi \
+ fi
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+doc: all
+ $(JAVADOC) -private -classpath $(JARFILE): -sourcepath . \
+ -source 1.4 -d $(DOCDIR) $(PACKAGEDOCS)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+$(ROOTUSRLIBDRP)/%: %
+ $(INS.file)
+
+FRC:
+
+lint:
+ $(LINT.c) $(PROG).c $(LINTLIBS)
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DRM.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DRM.java
new file mode 100644
index 0000000000..15160174f1
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DRM.java
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.domain.pools;
+
+/**
+ * The <code>DRM</code> interface specifies the contract between
+ * poold and higher level partitioning agents.
+ *
+ * <code>Poold</code> is designed to operate indepedently or as a
+ * member of a hierarchy of co-operating resource managers. In order
+ * to promote interaction and minimise implementation dependencies,
+ * the use of a common protocol which may be implemented in multiple
+ * languages is advocated. The protocol is provisionally named the
+ * "Distributed Resource Management" (DRM) protocol.
+ *
+ * This interface specifies how an implementation of the protocol
+ * would be implemented in Java.
+ *
+ * @see LogDRM
+ */
+
+interface DRM {
+ /**
+ * Connect to a higher level partitioning agent.
+ *
+ * @param version The version of the protocol.
+ * @param url The location of the agent.
+ * @throws Exception If the connect fails.
+ */
+ public void connect(int version, String url) throws Exception;
+
+ /**
+ * Disconnect from a higher level partitioning agent.
+ *
+ * @throws Exception If the client is not connected.
+ */
+ public void disconnect() throws Exception;
+
+ /**
+ * Request resources via a higher level partitioning agent.
+ *
+ * @throws Exception If the request fails.
+ */
+ public void request() throws Exception;
+
+ /**
+ * Offer resources via a higher level partitioning agent.
+ *
+ * @throws Exception If the offer fails.
+ */
+ public void offer() throws Exception;
+
+ /**
+ * Cancel a previous offer or request.
+ *
+ * @throws Exception If the cancel fails.
+ */
+ public void cancel() throws Exception;
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DecisionHistory.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DecisionHistory.java
new file mode 100644
index 0000000000..f854231d9d
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/DecisionHistory.java
@@ -0,0 +1,623 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.io.*;
+import java.util.*;
+import java.text.SimpleDateFormat;
+
+import com.sun.solaris.service.logging.*;
+import com.sun.solaris.service.pools.*;
+
+/**
+ * This class maintains history about previous decisions. It can be
+ * used to ratify that a decision made on the basis of observed behavior
+ * over a limited time was historically shown to not degrade
+ * performance. The class maintains historical data in a history file.
+ * The format of this data is project-private and very likely to change
+ * as the implementation improves.
+ */
+public final class DecisionHistory implements Serializable {
+ /**
+ * The number of samples which a decision will be remembered.
+ */
+ public static final int DECISION_LIFETIME = 256;
+
+ /**
+ * Map of values of historical decisions.
+ */
+ private HashMap decisions = new HashMap();
+
+ /**
+ * Map of resources to be monitored for improvement in
+ * utilization to the corresponding decision. Maps Resources to
+ * their decision's key string.
+ */
+ private transient HashMap resourcesAwaitingImprovement = new HashMap();
+
+ /**
+ * List of decisions, in order of creation, to manage expiry.
+ */
+ private transient LinkedList decisionList = new LinkedList();
+
+ /**
+ * Constructor.
+ */
+ public DecisionHistory()
+ {
+ }
+
+ /**
+ * Record a decision that's been made regarding a processor.
+ * Such a decision is a (cpuid, from-pset-name, to-pset-name,
+ * (from-pset-composition), (to-pset-composition),
+ * original-utilization-class) tuple.
+ */
+ public void recordProcessorMove(ComponentMove move,
+ double startingUtilization, int sampleCount) throws PoolsException
+ {
+ Decision decision = Decision.forMove(move, startingUtilization);
+ decision.setStartingSampleCount(sampleCount);
+ Object o = decisions.put(decision.getKey(), decision);
+ Poold.OPT_LOG.log(Severity.DEBUG, "recorded decision (" +
+ decision + ")" + (o == null ? "" : " (displaced " + o +
+ ")"));
+
+ /*
+ * Remember the most-recently-made decision regarding a
+ * resource until the next utilization sample is taken,
+ * so the next solve() may then reocrd the improvement.
+ * If another decision is made regarding this resource,
+ * the previous ones are forgotten, and their
+ * improvement fields are left 0.
+ */
+ resourcesAwaitingImprovement.put(move.getTo(),
+ decision.getKey());
+ decisionList.add(decision);
+ }
+
+ private void recordImprovementWithUtilization(Resource resource,
+ double utilization)
+ {
+ String decisionKey = (String)resourcesAwaitingImprovement.get(
+ resource);
+
+ if (decisionKey != null) {
+ Decision decision = (Decision)decisions.get(
+ decisionKey);
+ if (decision != null) {
+ decision.setImprovementWithNewUtilization(
+ utilization);
+ Poold.OPT_LOG.log(Severity.DEBUG, resource +
+ " improvement measured for decision " +
+ decision.describe());
+ }
+ }
+ }
+
+ /**
+ * A Decision boils down to a tuple describing the resource
+ * configuration involved before and after a particular resource
+ * is moved. We use a textual representation to describe the
+ * decision, by value, to avoid holding references to any of the
+ * actual resources involved.
+ */
+ private static abstract class Decision implements Serializable {
+ /**
+ * Utilization of the resource before the move was made.
+ */
+ private double startingUtilization = 0.0;
+
+ /**
+ * Improvement in utilization (-1..1) after the move was
+ * made, if the determination is made.
+ */
+ private double improvement = 0.0;
+
+ /**
+ * Number of times this decision has been reexamined.
+ */
+ private int usage = 0;
+
+ /**
+ * Monitor's sample count when the decision was made,
+ * used to expire this decision after DECISION_LIFETIME
+ * samples.
+ */
+ private int startingSampleCount;
+
+ /**
+ * Decision's creation time.
+ */
+ private Date date;
+
+ /**
+ * Returns a String key for this Decision.
+ */
+ public abstract String getKey();
+
+ /**
+ * Returns a Decision corresponding to a given Move.
+ * @return a Decision corresponding to a given Move.
+ * @throws InvalidArgumentException if there is no
+ * Decision type corresponding to the move.
+ */
+ public static final Decision forMove(Move move,
+ double startingUtilization)
+ {
+ if (move instanceof ComponentMove)
+ return (new ComponentMoveDecision(
+ (ComponentMove)move, startingUtilization));
+ else
+ return (null);
+ }
+
+ private Decision()
+ {
+ date = new Date();
+ }
+
+ /**
+ * Invoked after construction, sets the utilization
+ * corresponding to the affected resource before the move
+ * was made.
+ */
+ public final void setStartingUtilization(
+ double startingUtilization)
+ {
+ this.startingUtilization = startingUtilization;
+ }
+
+ /**
+ * Invoked after construction, sets the sampleCount from
+ * the monitor, used to expire this decision after
+ * DECISION_LIFETIME samples.
+ */
+ public void setStartingSampleCount(int sampleCount)
+ {
+ this.startingSampleCount = sampleCount;
+ }
+
+ /**
+ * sampleCount accessor.
+ */
+ public int getStartingSampleCount()
+ {
+ return (startingSampleCount);
+ }
+
+ /**
+ * Stores the improvement, computed in a
+ * subclass-specific way.
+ */
+ abstract public void setImprovementWithNewUtilization(
+ double newUtilization);
+
+ /**
+ * Allow subclasses to record the improvement.
+ */
+ protected void setImprovement(double improvement)
+ {
+ this.improvement = improvement;
+ }
+
+ /**
+ * Returns the improvement in utilization measured by
+ * the monitor after the move is made.
+ */
+ public final double getImprovement()
+ {
+ return (improvement);
+ }
+
+ /**
+ * Returns the utilization corresponding to the affected
+ * resource before the move was made.
+ */
+ public final double getStartingUtilization()
+ {
+ return (startingUtilization);
+ }
+
+ public abstract int hashCode();
+ public abstract boolean equals(Object o);
+ public abstract String toString();
+
+ private static final long serialVersionUID = 0x7860687;
+
+ /**
+ * Number of times this decision has been reexamined.
+ */
+ public final int getUsage()
+ {
+ return (usage);
+ }
+
+ private final void incrementUsage()
+ {
+ usage++;
+ }
+
+ /**
+ * Returns the time this decision was created.
+ */
+ public final Date getDate()
+ {
+ return date;
+ }
+
+ /**
+ * Formatter for printing creation date.
+ */
+ private static SimpleDateFormat dateFormatter;
+
+ /**
+ * Format for printing creation date.
+ */
+ private final static String dateFormat = "MMM d kk:mm:ss";
+
+ /**
+ * Returns a more comprehensive textual representation
+ * of this devision than toString().
+ */
+ public final String describe()
+ {
+ if (dateFormatter == null)
+ dateFormatter = new SimpleDateFormat(
+ dateFormat);
+ return (toString() + " made at " +
+ dateFormatter.format(getDate()) +
+ " with improvement " + getImprovement() +
+ " used " + getUsage() + " times");
+ }
+ }
+
+ /**
+ * A Decision affecting the transfer of one CPU between
+ * processor sets.
+ */
+ private static final class ComponentMoveDecision extends Decision {
+ /**
+ * The CPU Id of the involved CPU.
+ */
+ private String cpuid;
+
+ /**
+ * The name of the donating processor set.
+ */
+ private String fromPsetName;
+
+ /**
+ * The name of the receiving processor set.
+ */
+ private String toPsetName;
+
+ /**
+ * The string representation of the list of CPU IDs
+ * composing the donating set.
+ */
+ private String fromPsetComposition;
+
+ /**
+ * The string representation of the list of CPU IDs
+ * composing the receiving set.
+ */
+ private String toPsetComposition;
+
+ /**
+ * The number of CPUs in the receiving set, after the
+ * move is made.
+ */
+ private int toPsetSize;
+
+ /**
+ * A Decision-subclass-specific utilization group.
+ */
+ private String utilizationClass;
+
+ /**
+ * Constructs a ComponentMoveDecision based on the
+ * ComponentMove.
+ * @throws IllegalArgumentException if the ComponentMove
+ * can't be interpreted.
+ */
+ public ComponentMoveDecision(ComponentMove move,
+ double startingUtilization) throws IllegalArgumentException
+ {
+ try {
+ cpuid = move.getComponents().toString();
+ fromPsetName = move.getFrom().toString();
+ toPsetName = move.getTo().toString();
+ fromPsetComposition = move.getFrom()
+ .getComponents(null).toString();
+ toPsetComposition = move.getTo()
+ .getComponents(null).toString();
+ toPsetSize = move.getTo().getComponents(null)
+ .size();
+ utilizationClass = computeUtilizationClass(
+ startingUtilization);
+ setStartingUtilization(startingUtilization);
+ } catch (PoolsException pe) {
+ throw(IllegalArgumentException)(
+ new IllegalArgumentException().initCause(
+ pe));
+ }
+ }
+
+ public String getKey()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(cpuid);
+ sb.append(", ");
+ sb.append(fromPsetName);
+ sb.append(", ");
+ sb.append(toPsetName);
+
+ return (sb.toString());
+ }
+
+ public void setImprovementWithNewUtilization(
+ double newUtilization)
+ {
+ double sizeRatio = (double)(toPsetSize - 1) /
+ toPsetSize;
+ double expectedUtilization = sizeRatio *
+ getStartingUtilization();
+
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "pset improvement calculation expected " +
+ expectedUtilization + ", got " + newUtilization);
+ setImprovement(newUtilization - expectedUtilization);
+ }
+
+ public int hashCode() {
+ return (((((cpuid.hashCode() ^
+ fromPsetName.hashCode()) ^ toPsetName.hashCode()) ^
+ fromPsetComposition.hashCode()) ^
+ toPsetComposition.hashCode()) ^
+ utilizationClass.hashCode());
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof ComponentMoveDecision))
+ return false;
+ else {
+ ComponentMoveDecision cmd =
+ (ComponentMoveDecision)o;
+ return (cpuid.equals(cmd.cpuid) &&
+ fromPsetName.equals(cmd.fromPsetName) &&
+ toPsetName.equals(cmd.toPsetName) &&
+ fromPsetComposition.equals(
+ cmd.fromPsetComposition) &&
+ toPsetComposition.equals(
+ cmd.toPsetComposition) &&
+ utilizationClass.equals(
+ cmd.utilizationClass));
+ }
+ }
+
+ /**
+ * Returns the group that this decision's utilization
+ * falls into. Presently, there is only one group, but
+ * ostensibly decisions will later be grouped (e.g.
+ * into control-zone-wide groups).
+ */
+ private String computeUtilizationClass(
+ double startingUtilization)
+ {
+ return "I";
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(cpuid.toString());
+ sb.append(", ");
+ sb.append(fromPsetName.toString());
+ sb.append(", ");
+ sb.append(toPsetName.toString());
+ sb.append(", ");
+ sb.append(fromPsetComposition.toString());
+ sb.append(", ");
+ sb.append(toPsetComposition.toString());
+ sb.append(", ");
+ sb.append(utilizationClass.toString());
+
+ return (sb.toString());
+ }
+
+ private static final long serialVersionUID = 0xf7860687;
+ }
+
+ /**
+ * Vetoes a Move only if there is a prior decision that showed a
+ * degradation in resource utilization.
+ */
+ public boolean veto(Move m, double utilization)
+ {
+ Decision current = Decision.forMove(m, utilization);
+ Decision past;
+
+ if (current != null) {
+ past = (Decision)decisions.get(current.getKey());
+ if (past != null)
+ past.incrementUsage();
+ if (past != null && past.getImprovement() < 0.0) {
+ Poold.OPT_LOG.log(Severity.DEBUG, m +
+ " vetoed by decision " + past.describe());
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static final long serialVersionUID = 0xf7860687;
+
+ /**
+ * Synchronize the decision history with the persistent version.
+ */
+ public static DecisionHistory loadFromFile(String path)
+ throws IOException, ClassNotFoundException
+ {
+ return (load(new FileInputStream(path)));
+ }
+
+ /**
+ * Synchronize the persistent decision history with the present
+ * history.
+ */
+ public void syncToFile(String path) throws IOException
+ {
+ FileOutputStream fos = new FileOutputStream(path);
+ sync(fos);
+ fos.close();
+ }
+
+ /**
+ * Synchronize the decision history with the persistent version,
+ * from the given stream.
+ */
+ public static DecisionHistory load(InputStream is)
+ throws IOException, ClassNotFoundException
+ {
+ ObjectInputStream ois = new ObjectInputStream(is);
+
+ DecisionHistory dh = (DecisionHistory)ois.readObject();
+ return (dh);
+ }
+
+ /**
+ * Serialize the persistent decision history to the given
+ * stream.
+ */
+ public void sync(OutputStream os) throws IOException
+ {
+ new ObjectOutputStream(os).writeObject(this);
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(decisions.keySet().size() + " decisions {");
+ Iterator it = decisions.keySet().iterator();
+ while (it.hasNext()) {
+ String dk = (String)it.next();
+ Decision d = (Decision)decisions.get(dk);
+
+ sb.append("\t(");
+ sb.append(d.describe());
+ sb.append(")\n");
+ }
+ sb.append("}");
+
+ return (sb.toString());
+ }
+
+ /**
+ * Measures the improvement in utilization of any resource for
+ * which a decision was recently made.
+ */
+ public void expireAndMeasureImprovements(Monitor mon)
+ {
+ /*
+ * Measure the improvement in resources involved in
+ * recent decisions.
+ */
+ if (mon.isValid()) {
+ for (Iterator it = resourcesAwaitingImprovement.
+ keySet().iterator(); it.hasNext(); ) {
+ Resource res = (Resource)it.next();
+ try {
+ double utilization = mon.
+ getUtilization(res);
+ recordImprovementWithUtilization(res,
+ utilization);
+ } catch (StaleMonitorException sme) {
+ /*
+ * We can't access the utilization, so
+ * remove the decision.
+ */
+ String decisionKey = (String)
+ resourcesAwaitingImprovement.
+ get(res);
+ if (decisionKey != null)
+ decisions.remove(decisionKey);
+ }
+ it.remove();
+ }
+ }
+
+ /*
+ * Expire decisions which have outlived
+ * DECISION_LIFETIME samples.
+ */
+ int cutoff = mon.getSampleCount() - DECISION_LIFETIME;
+ if (cutoff > 0) {
+ Decision decision;
+ ListIterator it = decisionList.listIterator(0);
+ while (it.hasNext()) {
+ decision = (Decision)it.next();
+ int sc = decision.getStartingSampleCount();
+ if (sc < cutoff) {
+ if (sc > 0) {
+ Poold.OPT_LOG.log(
+ Severity.DEBUG,
+ "expiring decision (" +
+ decision + ")");
+ it.remove();
+ decisions.remove(
+ decision.getKey());
+ }
+ } else
+ break;
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+
+ resourcesAwaitingImprovement = new HashMap();
+ decisionList = new LinkedList();
+ for (Iterator it = decisions.keySet().iterator();
+ it.hasNext(); ) {
+ String decisionKey = (String)it.next();
+ Decision decision = (Decision)decisions.get(
+ decisionKey);
+ decision.setStartingSampleCount(0);
+ decisionList.add(decision);
+ }
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Expression.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Expression.java
new file mode 100644
index 0000000000..022d975f9a
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Expression.java
@@ -0,0 +1,653 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.util.regex.*;
+
+/**
+ * This class provides the base implementation of an Expression. All
+ * types of Expression must inherit from this class.
+ *
+ * An objective is always specified in terms of an expression. The
+ * only recognized expressions are those known by this class. An
+ * expression is create using the valueOf() factory method, which is
+ * why Expressions must be known to this class.
+ */
+abstract class Expression
+{
+ /**
+ * Expression importance
+ */
+ private long imp = -1;
+
+ /**
+ * Expression name
+ */
+ private String name;
+
+ /**
+ * Sole constructor. (For invocation by subclass constructors)
+ */
+ protected Expression(long imp, String name)
+ {
+ this.imp = imp;
+ this.name = name;
+ }
+
+ /**
+ * Return the name of the expression.
+ */
+ String getName()
+ {
+ return (this.name);
+ }
+
+ /**
+ * Return the importance of the expression.
+ */
+ long getImportance()
+ {
+ return (imp);
+ }
+
+ /**
+ * Returns the supplied string as an expression.
+ *
+ * This utility function attempts to identify the supplied
+ * string as an expression. It tries in turn each of the known
+ * sub-classes until finally, if none can be recognized, an
+ * exception is thrown. This function is not immune to
+ * mistakenly mis-classifying an expression. It is the
+ * responsibility of the concrete Exrpession classes to ensure
+ * that syntactic integrity is maintained with respect to
+ * potential cases of mistaken identity.
+ *
+ * @param raw The candidate expression
+ * @throws IllegalArgumentException If no valid expression can
+ * be found
+ */
+ static Expression valueOf(String raw) throws IllegalArgumentException
+ {
+ Expression exp = null;
+ /*
+ * TODO It would be better if subclasses registered,
+ * but this hard coded list will do until such a time
+ */
+ if ((exp = KVOpExpression.valueOf(raw)) == null)
+ if ((exp = KVExpression.valueOf(raw)) == null)
+ exp = KExpression.valueOf(raw);
+ if (exp == null)
+ throw new IllegalArgumentException(
+ "unrecognized expression: " + raw);
+ return (exp);
+ }
+
+ /**
+ * Ensure that the supplied importance is a valid value.
+ *
+ * @param imps String representation of the importance.
+ *
+ * @throws IllegalArgumentException if the importance is not
+ * valid.
+ */
+ protected static long validateImportance(String imps)
+ throws IllegalArgumentException
+ {
+ long imp;
+
+ try {
+ imp = Long.parseLong(imps);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException("importance value " +
+ imps + " is not legal");
+ }
+
+ if (imp < 0)
+ throw new IllegalArgumentException("importance value " +
+ imps + " is not legal (must be positive)");
+ return (imp);
+ }
+
+ /**
+ * Ensure that the supplied keyword is a member of the
+ * supplied keys.
+ *
+ * @param keys Array of valid key strings.
+ * @param key Key sought.
+ *
+ * @throws IllegalArgumentException if the sought key is not
+ * a member of the keys array.
+ */
+ protected static void validateKeyword(String keys[], String key)
+ throws IllegalArgumentException
+ {
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].compareTo(key) == 0)
+ return;
+ }
+ throw new IllegalArgumentException("keyword " + key +
+ " is not recognized");
+ }
+
+ /**
+ * Return true if the supplied expression "contradicts" this
+ * expression. The definition of contradiction is left down to
+ * each implementing sub-class.
+ *
+ * @param o Expression to examine for contradiction.
+ */
+ public abstract boolean contradicts(Expression o);
+}
+
+/**
+ * This class implements the functionality for a key-value-operator
+ * expression.
+ *
+ * The general form of this expression is defined in the pattern
+ * member. A simplified rendition of which is:
+ *
+ * [[imp]:] <key> <op> <value>
+ *
+ * key is a string which identifies the expression
+ * op is the operator for the expression ( < | > | ~)
+ * value is the value of the expression
+ *
+ * For example:
+ *
+ * 10: utilization < 80
+ */
+final class KVOpExpression extends Expression
+{
+ /**
+ * The operator for this expression.
+ */
+ private char op;
+
+ /**
+ * The value of this expression.
+ */
+ private int val;
+
+ /**
+ * The pattern used to recognize this type of expression.
+ */
+ private static final Pattern pattern = Pattern.compile(
+ "\\s*((\\d+)\\s*:)?\\s*(\\w+)\\s*([~<>])\\s*(\\d+)\\s*");
+
+ /**
+ * The array of valid keys for this type of expression.
+ */
+ private static final String keys[] = { "utilization" };
+
+ /**
+ * A greater than operator.
+ */
+ static final char GT = '>';
+
+ /**
+ * A less than operator.
+ */
+ static final char LT = '<';
+
+ /**
+ * A near to operator.
+ */
+ static final char NT = '~';
+
+ /**
+ * Private constructor used in the valueOf() factory method.
+ *
+ * @param imp The importance of this expression.
+ * @param name The name of this expression.
+ * @param op The operator of this expression.
+ * @param val The value of this expression.
+ */
+ private KVOpExpression(long imp, String name, String op, int val)
+ {
+ super(imp, name);
+ this.op = op.charAt(0);
+ this.val = val;
+ }
+
+ /**
+ * Create and return an expression from the input string.
+ *
+ * Determine if the input string matches the syntax defined by
+ * this expression. If the expression cannot be matched, an
+ * exception will be thrown.
+ *
+ * @param raw Candidate expression string.
+ *
+ * @throws IllegalArgumentExpression if the string is not a
+ * valid expression of this type.
+ */
+ static Expression valueOf(String raw) throws IllegalArgumentException
+ {
+ KVOpExpression exp = null;
+ Matcher m = pattern.matcher(raw);
+
+ if (m.matches()) {
+ long imp = 1;
+ int val = Integer.parseInt(m.group(5));
+
+ if (m.group(2) != null)
+ imp = validateImportance(m.group(2));
+
+ validateKeyword(keys, m.group(3));
+ if (val > 100 || val < 0)
+ throw new IllegalArgumentException(
+ "expression value " + val +
+ " is outside the legal range (0-100)");
+ exp = new KVOpExpression(imp, m.group(3),
+ m.group(4), val);
+ }
+ return (exp);
+ }
+
+ /**
+ * Return the operator for this expression.
+ */
+ char getOp()
+ {
+ return (op);
+ }
+
+ /**
+ * Return the value of this expression.
+ */
+ int getValue()
+ {
+ return (val);
+ }
+
+ /**
+ * Return a string representation of this expresssion.
+ */
+ public String toString()
+ {
+ return ("(" + getImportance() + ", " + getName() + ", '" + op +
+ "', " + val + ")");
+ }
+
+ /**
+ * Indicates whether some other KVOpExpression is "equal to
+ * this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof KVOpExpression))
+ return (false);
+ KVOpExpression other = (KVOpExpression) o;
+ if (getName().compareTo(other.getName()) != 0 ||
+ op != other.getOp() || val != other.getValue())
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (getName().hashCode() + (int) op + val);
+ }
+
+ /**
+ * Return true if the supplied expression "contradicts" this
+ * expression. If the supplied expression is not of the same
+ * type, then it cannot contradict it. If the names are
+ * different then there can be no contradiction.
+ *
+ * Contradiction occurs if the operator is the same or if they
+ * aren't the same and the operator is < or > and the values
+ * aren't simultanteously achievable.
+ *
+ * @param o Expression to examine for contradiction.
+ */
+ public boolean contradicts(Expression o)
+ {
+ if (!(o instanceof KVOpExpression))
+ return (false);
+ KVOpExpression other = (KVOpExpression) o;
+ if (getName().compareTo(other.getName()) != 0)
+ return (false);
+ if (getOp() != other.getOp()) {
+ if (getOp() != NT && other.getOp() != NT) {
+ if (getOp() == GT) {
+ if (getValue() < other.getValue())
+ return (false);
+ } else {
+ if (getValue() > other.getValue())
+ return (false);
+ }
+ } else
+ return (false);
+ }
+ return (true);
+ }
+}
+
+/**
+ * This class implements the functionality for a key-value expression.
+ *
+ * The general form of this expression is defined in the pattern
+ * member. A simplified rendition of which is:
+ *
+ * [[imp]:] <key> <value>
+ *
+ * key is a string which identifies the expression
+ * value is the value of the expression
+ *
+ * For example:
+ *
+ * 10: locality tight
+ */
+final class KVExpression extends Expression
+{
+ /**
+ * The value of this expression.
+ */
+ private String val;
+
+ /**
+ * The pattern used to recognize this type of expression.
+ */
+ private static final Pattern pattern = Pattern.compile(
+ "\\s*((\\d+)\\s*:)?\\s*(\\w+)\\s+(tight|loose|none)\\s*");
+
+ /**
+ * The array of valid keys for this type of expression.
+ */
+ private static final String keys[] = { "locality" };
+
+ /**
+ * Private constructor used in the valueOf() factory method.
+ *
+ * @param imp The importance of this expression.
+ * @param name The name of this expression.
+ * @param val The value of this expression.
+ */
+ private KVExpression(long imp, String name, String val)
+ {
+ super(imp, name);
+ this.val = val;
+ }
+
+ /**
+ * Create and return an expression from the input string.
+ *
+ * Determine if the input string matches the syntax defined by
+ * this expression. If the expression cannot be matched, an
+ * exception will be thrown.
+ *
+ * @param raw Candidate expression string.
+ *
+ * @throws IllegalArgumentExpression if the string is not a
+ * valid expression of this type.
+ */
+ static Expression valueOf(String raw) throws IllegalArgumentException
+ {
+ KVExpression exp = null;
+ Matcher m = pattern.matcher(raw);
+
+ if (m.matches()) {
+ long imp = 1;
+
+ if (m.group(2) != null)
+ imp = validateImportance(m.group(2));
+
+ validateKeyword(keys, m.group(3));
+ exp = new KVExpression(imp, m.group(3), m.group(4));
+ }
+ return (exp);
+ }
+
+ /**
+ * Return the value of this expression.
+ */
+ String getValue()
+ {
+ return (val);
+ }
+
+ /**
+ * Return a string representation of this expresssion.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("(");
+ buf.append(getImportance());
+ buf.append(", ");
+ buf.append(getName());
+ buf.append(", ");
+ buf.append(val);
+ buf.append(")");
+
+ return (buf.toString());
+ }
+
+ /**
+ * Indicates whether some other KVExpression is "equal to
+ * this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof KVExpression))
+ return (false);
+ KVExpression other = (KVExpression) o;
+ if (getName().compareTo(other.getName()) != 0 ||
+ val.compareTo(other.getValue()) != 0)
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (getName().hashCode() + val.hashCode());
+ }
+
+ /**
+ * Return true if the supplied expression "contradicts" this
+ * expression. If the supplied expression is not of the same
+ * type, then it cannot contradict it. If the names are
+ * different then there can be no contradiction.
+ *
+ * Contradiction occurs if the value is different.
+ *
+ * @param o Expression to examine for contradiction.
+ */
+ public boolean contradicts(Expression o)
+ {
+ if (!(o instanceof KVExpression))
+ return (false);
+ KVExpression other = (KVExpression) o;
+ if (getName().compareTo(other.getName()) != 0)
+ return (false);
+ if (val.compareTo(other.getValue()) == 0)
+ return (false);
+ return (true);
+ }
+}
+
+/**
+ * This class implements the functionality for a key expression.
+ *
+ * The general form of this expression is defined in the pattern
+ * member. A simplified rendition of which is:
+ *
+ * [[imp]:] <key>
+ *
+ * key is a string which identifies the expression
+ *
+ * For example:
+ *
+ * 10: wt-load
+ */
+final class KExpression extends Expression
+{
+ /**
+ * The pattern used to recognize this type of expression.
+ */
+ private static final Pattern pattern = Pattern.compile(
+ "\\s*((\\d+)\\s*:)?\\s*([\\w-]+)\\s*");
+
+ /**
+ * The array of valid keys for this type of expression.
+ */
+ private static final String keys[] = { "wt-load" };
+
+ /**
+ * Private constructor used in the valueOf() factory method.
+ *
+ * @param imp The importance of this expression.
+ * @param name The name of this expression.
+ */
+ private KExpression(long imp, String name)
+ {
+ super(imp, name);
+ }
+
+ /**
+ * Create and return an expression from the input string.
+ *
+ * Determine if the input string matches the syntax defined by
+ * this expression. If the expression cannot be matched, an
+ * exception will be thrown.
+ *
+ * @param raw Candidate expression string.
+ *
+ * @throws IllegalArgumentExpression if the string is not a
+ * valid expression of this type.
+ */
+ static Expression valueOf(String raw) throws IllegalArgumentException
+ {
+ KExpression exp = null;
+ Matcher m = pattern.matcher(raw);
+
+ if (m.matches()) {
+ long imp = 1;
+
+ if (m.group(2) != null)
+ imp = validateImportance(m.group(2));
+
+ validateKeyword(keys, m.group(3));
+ exp = new KExpression(imp, m.group(3));
+ }
+ return (exp);
+ }
+
+ /**
+ * Return a string representation of this expresssion.
+ */
+ public String toString()
+ {
+ return ("(" + getImportance() + ", " + getName() + ")");
+ }
+
+ /**
+ * Indicates whether some other KExpression is "equal to
+ * this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof KExpression))
+ return (false);
+ KExpression other = (KExpression) o;
+ if (getName().compareTo(other.getName()) != 0)
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (getName().hashCode());
+ }
+
+ /**
+ * Return true if the supplied expression "contradicts" this
+ * expression. If the supplied expression is not of the same
+ * type, then it cannot contradict it. If the names are
+ * different then there can be no contradiction.
+ *
+ * @param o Expression to examine for contradiction.
+ */
+ public boolean contradicts(Expression o)
+ {
+ if (!(o instanceof KExpression))
+ return (false);
+ KExpression other = (KExpression) o;
+ if (getName().compareTo(other.getName()) != 0)
+ return (false);
+ return (true);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/LogDRM.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/LogDRM.java
new file mode 100644
index 0000000000..0e6e516c2b
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/LogDRM.java
@@ -0,0 +1,128 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.util.*;
+import java.util.logging.*;
+
+import com.sun.solaris.service.logging.Severity;
+import com.sun.solaris.service.pools.*;
+
+/**
+ * The <code>LogDRM</code> class implements the Distributed Resource
+ * Management (DRM) protocol as a logger.
+ *
+ * All actions are logged using the logging facilities offered by
+ * <code>Poold</code>.
+ */
+class LogDRM implements DRM
+{
+ /**
+ * Supported protocol version.
+ */
+ private final int version = 1;
+
+ /**
+ * Location of higher level resource manager.
+ */
+ private String url;
+
+ /**
+ * Connect to a higher level partitioning agent.
+ *
+ * @param requested The requested version of the protocol.
+ * @param url The location of the agent.
+ * @throws Exception If the connect fails.
+ */
+ public void connect(int requested, String url) throws Exception
+ {
+ if (requested > version) {
+ Poold.CONF_LOG.log(Severity.NOTICE,
+ "Requested protocol version (" + requested +
+ ") not supported");
+ return;
+ }
+ this.url = url;
+ Poold.CONF_LOG.log(Severity.INFO, "DRM protocol version:" +
+ version + ", server: " + url);
+ }
+
+
+ /**
+ * Disconnect from a higher level partitioning agent.
+ *
+ * @throws Exception If the client is not connected.
+ */
+ public void disconnect() throws Exception
+ {
+ Poold.CONF_LOG.log(Severity.INFO, "Disconnected from " + url);
+ }
+
+
+ /**
+ * Request resources via a higher level partitioning agent.
+ *
+ * TODO: Define request parameters.
+ *
+ * @throws Exception If the request fails.
+ */
+ public void request() throws Exception
+ {
+ Poold.MON_LOG.log(Severity.INFO, "Requesting additional " +
+ "resources ");
+ }
+
+
+ /**
+ * Offer resources via a higher level partitioning agent.
+ *
+ * TODO: Define offer parameters.
+ *
+ * @throws Exception If the offer fails.
+ */
+ public void offer() throws Exception
+ {
+ Poold.MON_LOG.log(Severity.INFO, "Requesting additional " +
+ "resources ");
+ }
+
+ /**
+ * Canel a previous offer or request.
+ *
+ * TODO: Define cancel parameters.
+ *
+ * @throws Exception If the cancel fails.
+ */
+ public void cancel() throws Exception
+ {
+ Poold.MON_LOG.log(Severity.INFO, "Requesting additional " +
+ "resources ");
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Makefile
new file mode 100644
index 0000000000..e99de5c8ad
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Makefile
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/domain/pools/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = Move.java \
+ Expression.java \
+ Statistic.java \
+ StatisticList.java \
+ Monitor.java \
+ Objective.java \
+ ResourceMonitor.java \
+ SystemMonitor.java \
+ Solver.java \
+ SystemSolver.java \
+ DecisionHistory.java \
+ DRM.java \
+ LogDRM.java \
+ Poold.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *.class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Monitor.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Monitor.java
new file mode 100644
index 0000000000..88d1841387
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Monitor.java
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.util.Map;
+
+import com.sun.solaris.service.pools.Configuration;
+import com.sun.solaris.service.pools.Resource;
+import com.sun.solaris.service.pools.PoolsException;
+
+/**
+ * A monitoring class. The user of this interface can retrieve
+ * monitoring information related to the configuration which is
+ * examined.
+ */
+
+public interface Monitor {
+ /**
+ * Initialize the monitoring object using details from the
+ * supplied configuration.
+ *
+ * @param conf The configuration to be monitored.
+ * @throws PoolsException If the initialize fails.
+ * @throws StaleMonitorException If the resource monitors
+ * cannot be accessed.
+ */
+ public void initialize(Configuration conf) throws PoolsException,
+ StaleMonitorException;
+
+ /**
+ * Return the next sample.
+ *
+ * This call is a blocking call. The sample will only be
+ * returned after pausing the invoking thread for the "sample
+ * interval".
+ *
+ * @throws StaleMonitorException If the sample fails.
+ * @throws PoolsException If there is an error manipulating the
+ * pools configuration.
+ * @throws InterruptedException If the thread is interrupted
+ * while waiting for the sampling time to arrive. The caller
+ * may wish to check other conditions before possibly
+ * reinitiating the sample.
+ */
+ public void getNext() throws StaleMonitorException, PoolsException,
+ InterruptedException;
+
+ /**
+ * Return the number of samples taken. This is the number of
+ * successful calls to <code>getNext()</code>.
+ */
+ public int getSampleCount();
+
+ /**
+ * Return the utilization for supplied resource.
+ *
+ * @param res The resource to be examined.
+ *
+ * @throws StaleMonitorException if the resource cannot be accessed.
+ */
+ public double getUtilization(Resource res) throws StaleMonitorException;
+ public boolean isValid();
+ public ResourceMonitor get(Resource res) throws StaleMonitorException;
+}
+
+/**
+ * Indicates that a monitor must be re-initialized. This can occur
+ * for a number of reasons, including:
+ *
+ * <ul>
+ * <li><p>
+ * Resources created, modified, destroyed whilst sampling
+ * </ul>
+ */
+class StaleMonitorException extends Exception {
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Move.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Move.java
new file mode 100644
index 0000000000..71d4aa423b
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Move.java
@@ -0,0 +1,221 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.util.*;
+
+import com.sun.solaris.service.pools.*;
+
+/**
+ * This class represents a move of resources between two resource
+ * sets. It is designed to be extended by classes which implement
+ * different types of moves.
+ */
+abstract class Move
+{
+ /**
+ * Source resource set
+ */
+ private Resource from;
+
+ /**
+ * Destination resource set
+ */
+ private Resource to;
+
+ /**
+ * Sole constructor. (For invocation by subclass constructors)
+ *
+ * @param from The source of the move
+ * @param to The destination of the move
+ */
+ protected Move(Resource from, Resource to)
+ {
+ this.from = from;
+ this.to = to;
+ }
+
+ /**
+ * Return the source of this move.
+ */
+ Resource getFrom()
+ {
+ return (from);
+ }
+
+ /**
+ * Return the destination of this move.
+ */
+ Resource getTo()
+ {
+ return (to);
+ }
+
+ /**
+ * Apply this move to the resources described.
+ *
+ * @throws PoolsException If the move fails for any reason.
+ */
+ abstract void apply() throws PoolsException;
+
+ /**
+ * Return the quantity of moved resource.
+ */
+ abstract long getQty();
+}
+
+/**
+ * This class represents a move of component resources between two
+ * resource sets. A component of a resource set is a uniquely
+ * identifiable component, such as a processor.
+ */
+final class ComponentMove extends Move
+{
+ /**
+ * List of components being moved.
+ */
+ private List compList;
+
+ /**
+ * Constructor
+ *
+ * @param from The source of the move
+ * @param to The destination of the move
+ * @param comp The component which is to be moved
+ */
+ ComponentMove(Resource from, Resource to, Component comp)
+ {
+ super(from, to);
+ compList = new ArrayList();
+ compList.add(comp);
+ }
+
+ /**
+ * Return a list of the components that comprise this move.
+ *
+ * The members of the list are guaranteed to be Component
+ * objects.
+ */
+ List getComponents()
+ {
+ return ((List) ((ArrayList) compList).clone());
+ }
+
+ /**
+ * Apply the move to the configuration to which the resources
+ * belong.
+ *
+ * @throws PoolsException if the transfer of resource fails.
+ */
+ void apply() throws PoolsException
+ {
+ getTo().transfer(getFrom(), compList);
+ }
+
+ /**
+ * Return the quantity of resource which is participating in
+ * this move.
+ */
+ long getQty()
+ {
+ return (compList.size());
+ }
+
+ /**
+ * Converts the <code>ComponentMove</code> to a
+ * <code>String</code> of the form:
+ */
+ public String toString()
+ {
+ return ("from " + getFrom().toString() + " to " +
+ getTo().toString() + " components " + compList);
+ }
+}
+
+/**
+ * This class represents a move of commodity resources between two
+ * resource sets. Such a resource cannot be uniquely identified in the
+ * resource abstraction and is thus different to a move consisting of
+ * uniquely identifiable resource components.
+ */
+class QuantityMove extends Move
+{
+ /**
+ * The resource quantity of the move.
+ */
+ private long qty;
+
+ /**
+ * Construct a quantity move using the supplied details.
+ *
+ * @param from The source of the resources.
+ * @param to The destination of the resources.
+ * @param qty The quantity of the resources.
+ *
+ * @throws IllegalArgumentException if the qty is negative.
+ */
+ QuantityMove(Resource from, Resource to, long qty)
+ {
+ super(from, to);
+ if (qty < 0)
+ throw new IllegalArgumentException(
+ "The resource quantity supplied (" + qty +
+ ") is illegal.");
+ this.qty = qty;
+ }
+
+ /**
+ * Apply the move to the configuration to which the resources
+ * belong.
+ *
+ * @throws PoolsException if the transfer of resource fails.
+ */
+ void apply() throws PoolsException
+ {
+ getTo().transfer(getFrom(), qty);
+ }
+
+ /**
+ * Return the quantity of resource which is participating in
+ * this move.
+ */
+ long getQty()
+ {
+ return (qty);
+ }
+
+ /**
+ * Return a string representation of the move.
+ */
+ public String toString()
+ {
+ return ("from " + getFrom().toString() + " to " +
+ getTo().toString() + " quantity " + qty);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Objective.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Objective.java
new file mode 100644
index 0000000000..a242885bb2
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Objective.java
@@ -0,0 +1,1034 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.logging.*;
+
+import com.sun.solaris.service.logging.Severity;
+import com.sun.solaris.service.locality.*;
+import com.sun.solaris.service.pools.*;
+
+
+/**
+ * An objective interface. All classes which wish to contribute to the
+ * Objective Function (OF hence) calculation must implement this
+ * interface. This interface defines a strategy which can be used to
+ * make a contribution to the Objective Function calculation.
+ *
+ * The OF calculation (which is implemented by <code>Poold</code>)
+ * consists of determining all possible resource moves across all
+ * resources. Once all moves are known, all registered objectives
+ * (i.e. instances of this interface) are called and asked to value
+ * the move.
+ *
+ * Note, the output of this method is constrained to be between -1 and
+ * 1, representing minimum and maximum desirability of this move in
+ * terms of this objective. This is enforced by <code>Poold</code> and
+ * an <code>IllegalOFValueException</code> will be thrown if this
+ * constraint is broken.
+ */
+interface Objective
+{
+ /**
+ * Return the contribution of this objective. The contribution
+ * is constrainted to be a value between -1 and +1 to ensure
+ * that no objective can make a disproportionate contribution
+ * to the total result.
+ *
+ * The more desirable this move appears in terms of this
+ * objective, the closer to +1 will be the value. A value of 0
+ * indicates that the move is neutral in terms of the
+ * objective. A negative value indicates that the move is
+ * undesirable.
+ *
+ * @param conf The configuration which is being examined
+ * @param move The move under consideration
+ * @param elem The element to which the objective applies
+ *
+ * @throws PoolsException if there is an error manipulating
+ * the configuration
+ */
+ public double calculate(Configuration conf, Move move, Element elem)
+ throws PoolsException;
+
+ /**
+ * Set the objective's expression to the supplied parameter.
+ *
+ * @param exp An expression for this objective.
+ */
+ public void setExpression(Expression exp);
+
+ /**
+ * Get the objective's expression.
+ */
+ public Expression getExpression();
+}
+
+/**
+ * This interface must be implemented by all Objectives which are
+ * workload dependent. The examine method is used by a Solver to
+ * determine if the objective is still being satisfied.
+ */
+interface WorkloadDependentObjective extends Objective
+{
+ /**
+ * This method returns true if the Objective is no longer
+ * satisfied. If the objective is still satisfied, then return
+ * false.
+ *
+ * @param conf The configuration to be examined
+ * @param solver The solving interface used to get utilization
+ * information
+ * @param elem The element to which the objective belongs
+ *
+ * @throws PoolsException if there is an error examining the
+ * pool configuration
+ * @throws StaleMonitorException if there is an error accessing
+ * the element's ResourceMonitor
+ */
+ public boolean examine(Configuration conf, Solver solver,
+ Element elem) throws PoolsException, StaleMonitorException;
+}
+
+/**
+ * This class provides a skeletal implementation of the
+ * <code>Objective</code> interface to minimize the effort required
+ * to implement this interface.
+ *
+ * To implement an objective, the programmer need only to extend this
+ * class and add the name of the class into the appropriate element
+ * objectives property in the <code>poold.properties</code> file.
+ */
+abstract class AbstractObjective implements Objective
+{
+ abstract public double calculate(Configuration conf, Move move,
+ Element elem) throws PoolsException;
+
+ /**
+ * The objectives which are recognized by this class
+ */
+ private static Map objectives;
+
+ /**
+ * The expression associated with this objective
+ */
+ private Expression exp;
+
+ /**
+ * Set the objective's expression to the supplied parameter.
+ *
+ * @param exp An expression for this objective.
+ */
+ public void setExpression(Expression exp)
+ {
+ this.exp = exp;
+ }
+
+ /**
+ * Get the objective's expression.
+ */
+ public Expression getExpression()
+ {
+ return (exp);
+ }
+
+ /**
+ * A factory method which returns a created objective which is
+ * associated with the supplied expression. The type and the
+ * expression are used to identify valid types of objectives
+ * to which this expression may be applied. If an acceptable
+ * objective cannot be found for the supplied type, then an
+ * <code>IllegalArgumentException</code> will be thrown.
+ *
+ * @param type The element type for which an objective must be
+ * found
+ * @param exp The expression which will be associated with the
+ * objective
+ *
+ * @throws IllegalArgumentExcetion if the supplied expression
+ * cannot be associated with an objective of the supplied type
+ */
+ public static Objective getInstance(String type, Expression exp)
+ throws IllegalArgumentException
+ {
+ Objective ret = null;
+ Map typeObjs = null;
+
+ initMapIfNecessary();
+ typeObjs = (Map)objectives.get(type);
+ if (typeObjs != null) {
+ Class objClass = (Class)typeObjs.get(exp.getName());
+ if (objClass != null) {
+ try {
+ ret = (Objective) objClass.
+ newInstance();
+ } catch (Exception e) {
+ Poold.utility.die(Poold.OPT_LOG, e,
+ true);
+ }
+ ret.setExpression(exp);
+ }
+ }
+ if (ret == null)
+ throw new IllegalArgumentException(
+ "unrecognized objective name for " + type + ": " +
+ exp.toString());
+ return (ret);
+ }
+
+ /**
+ * Return a string representation of this objective.
+ */
+ public String toString()
+ {
+ return (exp.toString());
+ }
+
+ /**
+ * Initialize the implementation map the first time it's
+ * called.
+ */
+ private static void initMapIfNecessary()
+ {
+ /*
+ * Setup the objectives map for the known classes
+ */
+ if (objectives == null) {
+ objectives = new HashMap();
+ Properties props = new Properties();
+ try {
+ props.load(
+ new FileInputStream(
+ Poold.POOLD_PROPERTIES_PATH));
+ } catch (IOException ioe) {
+ Poold.utility.die(Poold.CONF_LOG, ioe);
+ }
+ registerObjectives(props, objectives, "system");
+ registerObjectives(props, objectives, "pset");
+ }
+ }
+
+ /**
+ * Add the objectives contained in the supplied properties to
+ * the set of valid objectives. The objectives are updated
+ * with objectives of the supplied type contained in the
+ * properties.
+ *
+ * @param props The properties containing the objectives
+ * @param objectives The objectives to be updated
+ * @param type The type of objectives to be added
+ */
+ private static void registerObjectives(Properties props,
+ Map objectives, String type)
+ {
+ Map typeObjs = new HashMap();
+ String objs = props.getProperty(type + ".objectives");
+ String objNames[] = objs.split(",");
+ for (int i = 0; i < objNames.length; i++) {
+ String objName = objNames[i].trim();
+ try {
+ Class clazz = Class.forName(objName);
+ Field field = clazz.getDeclaredField("name");
+ String key = (String) field.get(null);
+ typeObjs.put(key, clazz);
+ } catch (ClassNotFoundException cnfe) {
+ Poold.utility.die(Poold.CONF_LOG, cnfe);
+ } catch (NoSuchFieldException nsfe) {
+ Poold.utility.die(Poold.CONF_LOG, nsfe);
+ } catch (IllegalAccessException iae) {
+ Poold.utility.die(Poold.CONF_LOG, iae);
+ }
+ }
+ objectives.put(type, typeObjs);
+ }
+
+ /**
+ * Indicates whether some other Objective is "equal to this
+ * one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof Objective))
+ return (false);
+ Objective other = (Objective) o;
+
+ return (getExpression().equals(other.getExpression()));
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (getExpression().hashCode());
+ }
+}
+
+
+/**
+ * The <code>WeightedLoadObjective</code> class implements a Weighted
+ * Load Objective for <code>Poold</code>.
+ *
+ * The goal is to allocate more resources to those resource partitions
+ * which are heavily loaded. The weighting is determined from the
+ * objective importance and the pool.importance.
+ */
+final class WeightedLoadObjective extends AbstractObjective
+ implements WorkloadDependentObjective
+{
+ /**
+ * The name of the class.
+ */
+ static final String name = "wt-load";
+
+ /**
+ * The list of calculations made during examination.
+ */
+ List calcList;
+
+ /**
+ * Determine whether an objective is satisfied. If the
+ * objective is still satisfied, return false; otherwise
+ * return true.
+ *
+ * This objective examination determines if all resource sets
+ * are allocated the share of resources that their utilization
+ * would indicate they should be. This attempts to ensure that
+ * highly utilized resource sets recieve the greater
+ * proportion of available resources.
+ *
+ * @param conf The configuration to be examined
+ * @param solver The solving interface used to get utilization
+ * information
+ * @param elem The element to which the objective belongs
+ *
+ * @throws PoolsException if there is an error examining the
+ * pool configuration
+ * @throws StaleMonitorException if there is an error accessing
+ * the element's ResourceMonitor
+ */
+ public boolean examine(Configuration conf, Solver solver,
+ Element elem) throws PoolsException, StaleMonitorException
+ {
+ Monitor mon = solver.getMonitor();
+ Value val = new Value("type", "pset");
+ List valueList = new LinkedList();
+ calcList = new LinkedList();
+ valueList.add(val);
+
+ List resList = conf.getResources(valueList);
+ val.close();
+ Iterator itRes = resList.iterator();
+
+ Calculation.totalUtil = 0;
+ Calculation.resQ = 0;
+
+ while (itRes.hasNext()) {
+ Resource res = (Resource) itRes.next();
+ List CPUs = res.getComponents(null);
+
+ try {
+ Calculation calc = new Calculation(res, CPUs,
+ mon.getUtilization(res),
+ res.getLongProperty("pset.min"),
+ res.getLongProperty("pset.max"));
+ calcList.add(calc);
+ } catch (StaleMonitorException sme) {
+ Poold.MON_LOG.log(Severity.INFO,
+ res.toString() +
+ " not participating in " + toString() +
+ " calculatation as it has no " +
+ "available statistics.");
+ }
+ }
+ Iterator itCalc = calcList.iterator();
+ while (itCalc.hasNext()) {
+ Calculation calc = (Calculation) itCalc.next();
+ if (calc.getShare() != calc.comp.size()) {
+ Poold.MON_LOG.log(Severity.INFO,
+ elem.toString() +
+ " utilization objective not satisfied " +
+ toString() + " with desired share " +
+ calc.getShare() + " and actual share " +
+ calc.comp.size());
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+ /**
+ * Holds data about weighted load calculations. This class is
+ * basically a structure which holds information specific to a
+ * weighted-load calculation
+ */
+ static class Calculation {
+ /**
+ * The resource on which this calculation is based.
+ */
+ Resource res;
+
+ /**
+ * The list of component resources held by this resource.
+ */
+ List comp;
+
+ /**
+ * The utilization of this resource.
+ */
+ double util;
+
+ /**
+ * The minimum value of this resource's size.
+ */
+ long min;
+
+ /**
+ * The maximum value of this resource's size.
+ */
+ long max;
+
+ /**
+ * The total utilization of all instances of this class.
+ */
+ static double totalUtil;
+
+ /**
+ * The total quantity of resource for all instances of
+ * this class.
+ */
+ static int resQ;
+
+ /**
+ * Constructor. The class is immutable and holds
+ * information specific to a set of calculations about
+ * load.
+ *
+ * @param res The resource set
+ * @param comp The resource components
+ * @param util The resource utilization
+ * @param min The minimum qty of resource for this set
+ * @param max The maximum qty of resource for this set
+ */
+ public Calculation(Resource res, List comp, double util,
+ long min, long max)
+ {
+ this.res = res;
+ this.comp = comp;
+ this.min = min;
+ this.max = max;
+ this.util = (util / 100) * comp.size();
+ if (this.util < min)
+ this.util = min;
+ if (this.util > max)
+ this.util = max;
+ Calculation.totalUtil += this.util;
+ Calculation.resQ += comp.size();
+ }
+
+ /**
+ * Return the share of the total resource for this
+ * resource.
+ */
+ long getShare()
+ {
+ if (totalUtil == 0)
+ return (min);
+ return (Math.round((util / totalUtil) * resQ));
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("res: " + res.toString());
+ buf.append(" components: " + comp.toString());
+ buf.append(" min: " + min);
+ buf.append(" max: " + max);
+ buf.append(" util: " + util);
+ buf.append(" total resource: " + resQ);
+ buf.append(" total utilization: " + totalUtil);
+ buf.append(" share: " + getShare());
+ return (buf.toString());
+ }
+ }
+
+ /**
+ * Calculates the value of a configuration in terms of this
+ * objective.
+ *
+ * In the examination step, calculations of each resource's
+ * current and desired share were made. The moves can thus be
+ * assessed in terms of their desired impact upon the desired
+ * share. The current difference from desired is already
+ * known, so each move will serve to reduce or increase that
+ * difference. Moves that increase the difference have a
+ * negative score, those that reduce it have a positive
+ * score. All scores are normalized to return a value between
+ * -1 and 1.
+ *
+ * @param conf Configuration to be scored.
+ * @param move Move to be scored.
+ * @param elem The element to which the objective applies
+ * @throws PoolsException If an there is an error in execution.
+ */
+ public double calculate(Configuration conf, Move move, Element elem)
+ throws PoolsException
+ {
+ double ret = 0;
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "Calculating objective type: " + name);
+ /*
+ * There shouldn't be any empty moves, but if there
+ * are they are rated at 0.
+ */
+ if (move.getQty() == 0)
+ return (0);
+ Iterator itCalc = calcList.iterator();
+ while (itCalc.hasNext()) {
+ Calculation calc = (Calculation) itCalc.next();
+ long diff = calc.comp.size() - calc.getShare();
+
+ if (Math.abs(diff) > 1) {
+ double delta = 1 -
+ (move.getQty() / (double)Math.abs(diff));
+
+ if (calc.res.equals(move.getFrom())) {
+ if (diff > 0)
+ ret += delta;
+ else
+ ret -= delta;
+ } else if (calc.res.equals(move.getTo())) {
+ if (diff > 0)
+ ret -= delta;
+ else
+ ret += delta;
+ }
+ } else {
+ if (calc.res.equals(move.getFrom()))
+ ret += diff;
+ else if (calc.res.equals(move.getTo()))
+ ret -= diff;
+ }
+
+ }
+ /*
+ * Normalize
+ */
+ ret /= 2;
+
+ Poold.MON_LOG.log(Severity.DEBUG, "ret: " + ret);
+ return (ret);
+ }
+}
+
+/**
+ * A locality based objective which will assess moves in terms of
+ * their impact on the locality of the sets of resources which are
+ * impacted.
+ *
+ * The objective will assess moves with respect to the type of
+ * locality specified in the objective:
+ *
+ * <ul>
+ * <li><p>
+ * tight - resource locality is sought
+ * <li><p>
+ * loose - resource locality is avoided
+ * <li><p>
+ * none - resource locality has no impact
+ * </ul>
+ */
+final class LocalityObjective extends AbstractObjective
+{
+ /**
+ * The name of the class.
+ */
+ static final String name = "locality";
+
+ /**
+ * The locality domain used to describe locality for this
+ * objective.
+ */
+ private LocalityDomain ldom;
+
+ /**
+ * Prepare the calculation for this objective for the resource
+ * to which it applies.
+ *
+ * @param ldom LocalityDomain containing these resources.
+ * @param res Resource to which this objective is applied.
+ *
+ * @throws PoolsException if accessing the supplied resource
+ * fails.
+ */
+ public void prepare(LocalityDomain ldom, Resource res)
+ throws PoolsException
+ {
+ this.ldom = ldom;
+ }
+
+ /**
+ * Calculates the value of a configuration in terms of this
+ * objective.
+ *
+ * Firstly check to see if it is possible to short-cut the
+ * calculation. If not, then start to examine the disposition
+ * of CPUs and locality groups in relation to the processor
+ * set being evaluated. The objective scores moves in terms of
+ * their impact upon the quotient of cpus contained in each
+ * locality group.
+ *
+ * @param conf Configuration to be scored.
+ * @param move Move to be scored.
+ * @param elem The element to which the objective applies
+ * @throws Exception If an there is an error in execution.
+ */
+ public double calculate(Configuration conf, Move move, Element elem)
+ throws PoolsException
+ {
+ KVExpression kve = (KVExpression) getExpression();
+ double ret = 0;
+ double qA = 0;
+ double qB = 0;
+ Resource res = (Resource) elem;
+ ComponentMove cm = (ComponentMove) move;
+ Poold.MON_LOG.log(Severity.DEBUG,
+ "Calculating objective type: " + name + " for: " + elem);
+
+ /*
+ * If we are set to "none" then we don't care which
+ * configuration so just return 0
+ */
+ if (kve.getValue().compareTo("none") == 0)
+ return (ret);
+ /*
+ * If the maximum latency is 0, we don't care about
+ * latency
+ */
+ if (ldom.getMaxLatency() == 0)
+ return (ret);
+ /*
+ * If this element doesn't participate in the move, we
+ * should return 0.
+ */
+ if (elem.equals(move.getFrom()) == false &&
+ elem.equals(move.getTo()) == false)
+ return (ret);
+
+ /*
+ * Assess the effect on lgrp quotient for all
+ * moves. Try to maximise lgrp quotient for "tight"
+ * objectives and minimize if for "loose" objectives.
+ */
+ /*
+ * All contained cpus
+ */
+ List contains = res.getComponents(null);
+ /*
+ * All lgrps
+ */
+ Set groups = ldom.foreignGroups(new HashSet(), contains);
+
+ qB = calcQ(contains, groups);
+
+ if (elem.equals(move.getFrom()))
+ contains.removeAll(cm.getComponents());
+ else
+ contains.addAll(cm.getComponents());
+ /*
+ * Recalculate lgrps to take account of new components
+ */
+ groups = ldom.foreignGroups(new HashSet(), contains);
+ qA = calcQ(contains, groups);
+
+ ret = qA - qB;
+
+ if (kve.getValue().compareTo("loose") == 0)
+ ret = 0 - ret;
+
+ Poold.MON_LOG.log(Severity.DEBUG, "ret: " + ret);
+ return (ret);
+ }
+
+ /**
+ * Calculate a quotient using the supplied list of components
+ * and set of locality groups. The quotient represents the
+ * average (as in mean) number of CPUs (from the population in
+ * contains) present in each of the LocalityGroups contained
+ * in groups.
+ *
+ * @param contains The population of Components.
+ * @param groups The population of LocalityGroups.
+ *
+ * @throws PoolsException if there is an error accessing the
+ * CPUs.
+ */
+ private double calcQ(List contains, Set groups) throws PoolsException
+ {
+ Iterator groupIt = groups.iterator();
+ double q = 0.0;
+ while (groupIt.hasNext()) {
+ LocalityGroup grp = (LocalityGroup)groupIt.next();
+ int cpu_ids[] = grp.getCPUIDs();
+ Iterator containsIt = contains.iterator();
+ int intersection = 0;
+ double total = 0;
+ while (containsIt.hasNext()) {
+ Component comp = (Component) containsIt.next();
+ for (int i = 0; i < cpu_ids.length; i++) {
+ if (cpu_ids[i] == (int) comp.
+ getLongProperty("cpu.sys_id")) {
+ intersection++;
+ break;
+ }
+ }
+ }
+ double factor = 0;
+ for (int i = 1; i <= cpu_ids.length; i++)
+ factor += i;
+ factor = 1 / factor;
+ for (int i = 1; i <= intersection; i++)
+ q += i * factor;
+ }
+ q /= groups.size();
+ return (q);
+ }
+}
+
+/**
+ * A resource set utilization based objective which will assess moves
+ * in terms of their (likely) impact on the future performance of a
+ * resource set with respect to it's specified utilization objective.
+ *
+ * The utilization objective must be specified in terms of a
+ * KVOpExpression, see the class definition for information about the
+ * form of these expressions. The objective can be examined in terms
+ * of it's compliance with the aid of a monitoring object. The actual
+ * assessment of compliance is indicated by the associated monitoring
+ * object, with this class simply acting as a co-ordinator of the
+ * relevent information.
+ */
+final class UtilizationObjective extends AbstractObjective
+ implements WorkloadDependentObjective
+{
+ /**
+ * The name of the class.
+ */
+ static final String name = "utilization";
+
+ /**
+ * Short run detection.
+ */
+ private List zoneList = new LinkedList();
+
+ /**
+ * Format for printing utilization.
+ */
+ private static final DecimalFormat uf = new DecimalFormat("0.00");
+
+ /**
+ * Solver used to calculate delta, i.e. gap, between target and
+ * actual utilization values.
+ */
+ private Solver gapSolver;
+
+ /**
+ * Determine whether an objective is satisfied. If the
+ * objective is still satisfied, return false; otherwise
+ * return true.
+ *
+ * The assessment of control is made by the monitoring class
+ * using the supplied Expression and resource.
+ *
+ * @param conf The configuration to be examined
+ * @param solver The solving interface used to get utilization
+ * information
+ * @param elem The element to which the objective belongs
+ *
+ * @throws PoolsException if there is an error examining the
+ * pool configuration
+ * @throws StaleMonitorException if there is an error accessing
+ * the element's ResourceMonitor
+ */
+ public boolean examine(Configuration conf, Solver solver,
+ Element elem) throws PoolsException, StaleMonitorException
+ {
+ KVOpExpression kve = (KVOpExpression) getExpression();
+ ResourceMonitor mon;
+
+ /*
+ * If there is no resource monitor, then we cannot
+ * make an assessment of the objective's achievability.
+ * Log a message to make clear that this objective is
+ * not being assessed and then indicate that
+ * the objective has been achieved.
+ */
+ try {
+ mon = solver.getMonitor().get((Resource)elem);
+ } catch (StaleMonitorException sme) {
+ Poold.MON_LOG.log(Severity.INFO,
+ elem.toString() +
+ " utilization objective not measured " +
+ toString() + " as there are no available " +
+ "statistics.");
+ return (false);
+ }
+ gapSolver = solver;
+
+ double val = solver.getMonitor().getUtilization((Resource)elem);
+
+ StatisticList sl = (StatisticList) mon.get("utilization");
+ int zone = sl.getZone(kve, val);
+
+ if (zoneList.size() == 9) {
+ zoneList.remove(0);
+ }
+ zoneList.add(new Integer(sl.getZoneMean(val)));
+
+ /*
+ * Evaluate whether or not this objective is under
+ * control.
+ */
+ if ((zone & StatisticOperations.ZONEZ) ==
+ StatisticOperations.ZONEZ) {
+ /*
+ * If the objective is GT or LT, then don't
+ * return true as long as the objective is
+ * satisfied.
+ */
+ if (kve.getOp() == KVOpExpression.LT &&
+ (zone & StatisticOperations.ZONET) ==
+ StatisticOperations.ZONELT)
+ return (false);
+
+ if (kve.getOp() == KVOpExpression.GT &&
+ (zone & StatisticOperations.ZONET) ==
+ StatisticOperations.ZONEGT)
+ return (false);
+ Poold.MON_LOG.log(Severity.INFO,
+ elem.toString() +
+ " utilization objective not satisfied " +
+ toString() + " with utilization " + uf.format(val) +
+ " (control zone bounds exceeded)");
+ return (true);
+ }
+ /*
+ * Check if our statistics need to be recalculated.
+ */
+ checkShort(mon, elem, val);
+ return (false);
+ }
+
+ /**
+ * Calculates the value of a configuration in terms of this
+ * objective.
+ *
+ * Every set must be classified with a control zone when this
+ * function is called. The move can be assessed in terms of
+ * the control violation type. zone violations which are minor
+ * are offered a lower contribution than more significant
+ * violations.
+ *
+ * @param conf Configuration to be scored.
+ * @param move Move to be scored.
+ * @param elem The element to which the objective applies
+ * @throws Exception If an there is an error in execution.
+ */
+ public double calculate(Configuration conf, Move move, Element elem)
+ throws PoolsException
+ {
+ KVOpExpression kve = (KVOpExpression) getExpression();
+ double ret;
+
+ /*
+ * If the move is from the examined element, then
+ * check to see if the recipient has any
+ * objectives. If not, score the move poorly since we
+ * should never want to transfer resources to a
+ * recipient with no objectives. If there are
+ * objectives, then return the delta between target
+ * performance and actual performance for this
+ * element.
+ *
+ * If the move is to the examined element, then check
+ * to see if the donor has any objectives. If not,
+ * score the move highly, since we want to favour
+ * those resources with objectives. If there are
+ * objectives, return the delta between actual and
+ * target performance.
+ *
+ * If the element is neither the recipient or the
+ * donor of this proposed move, then score the move
+ * neutrally as 0.
+ */
+ try {
+ double val, gap;
+ StatisticList sl;
+
+ if (elem.equals(move.getFrom())) {
+ val = gapSolver.getMonitor().
+ getUtilization(move.getFrom());
+ sl = (StatisticList) gapSolver.getMonitor().
+ get(move.getFrom()).get("utilization");
+ gap = sl.getGap(kve, val) / 100;
+
+ if (gapSolver.getObjectives(move.getTo()) ==
+ null) {
+ /*
+ * Moving to a resource with
+ * no objectives should always
+ * be viewed unfavourably. The
+ * degree of favourability is
+ * thus bound between 0 and
+ * -1. If the source gap is
+ * negative, then subtract it
+ * from -1 to get the
+ * score. If positive,
+ * just return -1.
+ */
+ if (gap < 0) {
+ ret = -1 - gap;
+ } else {
+ ret = -1;
+ }
+ } else {
+ ret = 0 - gap;
+ }
+ } else if (elem.equals(move.getTo())) {
+ val = gapSolver.getMonitor().
+ getUtilization(move.getTo());
+ sl = (StatisticList) gapSolver.getMonitor().
+ get(move.getTo()).get("utilization");
+ gap = sl.getGap(kve, val) / 100;
+
+ if (gapSolver.getObjectives(move.getFrom()) ==
+ null) {
+ /*
+ * Moving from a resource with
+ * no objectives should always
+ * be viewed favourably. The
+ * degree of favourability is
+ * thus bound between 0 and
+ * 1. If the destination gap
+ * is negative, then add to 1
+ * to get the score. If
+ * positive, just return 1.
+ */
+ if (gap < 0) {
+ ret = 0 - gap;
+ } else {
+ ret = 1;
+ }
+ } else {
+ ret = 0 + gap;
+ }
+ } else {
+ ret = 0;
+ }
+ } catch (StaleMonitorException sme) {
+ /*
+ * We should always find a monitor,
+ * but if we can't then just assume
+ * this is a neutral move and return
+ * 0.
+ */
+ ret = 0;
+ }
+ Poold.MON_LOG.log(Severity.DEBUG, "ret: " + ret);
+ return (ret);
+ }
+
+ /**
+ * Check whether or not a set's statistics are still useful
+ * for making decision..
+ *
+ * Each set is controlled in terms of the zones of control
+ * based in terms of standard deviations from a mean. If the
+ * utilization of the set is not fluctuating normally around a
+ * mean, these checks will cause the accumulated statistics to
+ * be discarded and control suspended until a new sufficient
+ * set of data is accumulated.
+ *
+ * @param mon Resource monitor to examine.
+ * @param elem Element to which the resource monitor belongs.
+ * @param val Latest monitored value.
+ */
+ private void checkShort(ResourceMonitor mon, Element elem, double val)
+ {
+ boolean checkOne = true;
+ int checkOnePos = 0;
+ boolean doCheckOne = false;
+
+ Iterator itZones = zoneList.iterator();
+ while (itZones.hasNext()) {
+ int zone = ((Integer) itZones.next()).intValue();
+ if (doCheckOne) {
+ if (checkOne) {
+ if ((zone & StatisticOperations.ZONET)
+ != checkOnePos) {
+ checkOne = false;
+ }
+ }
+ } else {
+ if (zoneList.size() >= 9) {
+ checkOnePos = zone &
+ StatisticOperations.ZONET;
+ doCheckOne = true;
+ }
+ }
+ }
+ if (zoneList.size() >= 9 && checkOne) {
+ Poold.MON_LOG.log(Severity.INFO,
+ elem.toString() +
+ " utilization objective statistics reinitialized " +
+ toString() + " with utilization " + uf.format(val) +
+ " (nine points on same side of mean)");
+ mon.resetData("utilization");
+ zoneList.clear();
+ }
+ }
+
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Poold.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Poold.java
new file mode 100644
index 0000000000..8ff1bd7fd5
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Poold.java
@@ -0,0 +1,1155 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.io.*;
+import java.util.*;
+import java.util.logging.*;
+import java.text.DecimalFormat;
+import java.util.concurrent.atomic.*;
+
+import com.sun.solaris.service.locality.*;
+import com.sun.solaris.service.logging.*;
+import com.sun.solaris.service.pools.*;
+import com.sun.solaris.service.exception.*;
+
+/*
+ * poold overview
+ * ----- --------
+ *
+ * poold manipulates system resources in accordance with administrator
+ * specified constraints and objectives. The "goal" of the application
+ * is to maximise the efficiency of available resources within these
+ * parameters.
+ *
+ * Constraints are specified as follows:
+ *
+ * On a resource set:
+ *
+ * - min Is the minimum amount of resource a set should
+ * receive. poold will never elect to move resource so that a set
+ * falls below its minimum value. It is possible for a set to
+ * fall below its minimum as a consequence of administrative
+ * intervention, in which case poold will endeavour to bring a
+ * set back to its minimum level at the earliest opportunity.
+ *
+ * - max Is the maximum amount of resource a set should
+ * recieve. poold will never elect to move resource so that a set
+ * rises above its maximum value. It is possible for a set to
+ * rise above its maximum as a consequence of administrative
+ * intervention, in which case poold will endeavour to bring a
+ * set back to its maximum level at the earliest opportunity.
+ *
+ * On a resource component:
+ *
+ * - cpu.pinned Is an indication that a CPU should be ignored by
+ * poold for purposes of reallocation. A pinned CPU will never be
+ * moved by poold from one set to another.
+ *
+ * In addition to constraints, an administrator may also specify
+ * objectives. Currently three types of objectives are supported:
+ *
+ * - system.wt-load Is an objective set across an entire
+ * configuration. It attempts to ensure that resource is shared
+ * in accordance with current consumption. Those partitions which
+ * are most heavily utilized are give more resource in an attempt
+ * to lower their utilization levels.
+ *
+ * - set.locality Is a locality objective which attempts to
+ * minimize or maximize resource locality for a set.
+ *
+ * - set.utilization Is a utilization based objective which an
+ * administrator may use to explicitly dictate the utilization
+ * levels which should be achieved for a set.
+ *
+ * When executing, poold uses information about the current pools
+ * configuration; monitored resource utilization and specified
+ * constraints and objectives to determine if a move of resources is
+ * likely to lead to an increase in objective satisfaction.
+ *
+ * Candidate moves are generated by observing resource constraints.
+ * These moves are evaluated and scored in terms of their contribution
+ * to objective satisfaction (note: objectives are weighted according
+ * to their importance) and ranked accordingly. If a move can be
+ * identified that delivers an improvement, the move is made. Data is
+ * collected about past moves and recorded as "Decision History",
+ * before the move is made this data is consulted and if the move is
+ * expected not to yield an improvement, it may be cancelled. This
+ * refinement is designed to improve the quality of decision making by
+ * reflecting upon the past performance of decisions as well as the
+ * contribution to objective satisfaction.
+ *
+ * poold structure
+ * ----- ---------
+ *
+ * The common package name begins with:
+ *
+ * com.sun.solaris
+ *
+ * The software is divided into two main functional areas:
+ *
+ * service
+ *
+ * These packages collaborate to provide services to poold
+ * (typically, they use JNI to access exising
+ * functionality). They are not designed to be extended. For more
+ * details on these classes examine the source files in each
+ * directory.
+ *
+ * exception Stack trace formatter
+ * kstat Interface to Solaris kstat facility
+ * locality Interface to Solaris lgrp facility
+ * logging Interface to Solaris syslog facility
+ * pools Interface to Solaris libpool facility
+ * timer High resolution timestamps
+ *
+ * domain:
+ *
+ * These package reflect problem domain concepts and are
+ * responsible for application logic related to these
+ * concepts.
+ *
+ * pools Dynamic Resource Pools specific functionality.
+ *
+ * This code block will continue to explain in more detail how poold
+ * is organized.
+ *
+ * poold provides the following basic facilities:
+ *
+ * Monitoring:
+ *
+ * Basic statistic access is provided by the
+ * com.sun.solaris.service.kstat package. The following interfaces and
+ * classes collaborate to provide higher level statistic and
+ * monitoring facilities to the application:
+ *
+ * INTERFACES
+ *
+ * AggregateStatistic
+ * Monitor
+ * Statistic
+ * StatisticListener
+ *
+ * CLASSES
+ *
+ * AbstractStatistic
+ * DoubleStatistic
+ * LongStatistic
+ * ResourceMonitor
+ * StatisticEvent
+ * StatisticList
+ * StatisticOperations
+ * SystemMonitor
+ * UnsignedInt64Statistic
+ *
+ * Logging:
+ *
+ * Logging services are provided by the com.sun.solaris.logging
+ * package. In addition, the following class implements Poold's
+ * specific logging requirements.
+ *
+ * CLASSES
+ *
+ * Poold
+ *
+ * Optimization:
+ *
+ * lgrp service are provided by the com.sun.solaris.service.lgrp
+ * package. pools services are provided by the
+ * com.sun.solaris.service.pools package. In addition, optimization is
+ * implemented in the following Interfaces and Classes:
+ *
+ * INTERFACES
+ *
+ * Objective
+ * Solver
+ * WorkloadDependentObjective
+ *
+ * CLASSES
+ *
+ * AbstractObjective
+ * ComponentMove
+ * DecisionHistory
+ * Expression
+ * KExpression
+ * KVEpression
+ * KVOpExpression
+ * LocalityObjective
+ * Move
+ * Poold
+ * QuantityMove
+ * SystemSolver
+ * UtilizationObjective
+ * WeightedLoadObjective
+ *
+ * Configuration:
+ *
+ * pools services are provided by the com.sun.solaris.service.pools
+ * package, this is used to read poold configuration details from a
+ * libpool configuration. In addition, configuration is implemented in
+ * the following Classes:
+ *
+ * CLASSES
+ *
+ * AbstractObjective
+ * Expression
+ * Poold
+ * SystemSolver
+ *
+ * (NB: Some classes were mentioned in multiple categories where there
+ * responsbilities overlap. Inner classes are not listed as their
+ * responsibilities can be clearly inferred from their context.)
+ *
+ * For more details on any of the packages, classes or interfaces
+ * mentioned above, look at the documentation associated with each
+ * class.
+ */
+
+/**
+ * The <code>Poold</code> class implements a dynamic resource
+ * allocation system for Solaris.
+ *
+ * <code>Poold</code> is a monitoring daemon, designed to evaluate
+ * user specified objectives, monitor workload behaviour and
+ * dynamically assign resources in order to satisfy the evaluated
+ * objectives. For more details see:
+ *
+ * <a href="http://sac.eng.sun.com/PSARC/2002/287/">PSARC/2002/287</a>
+ */
+final class Poold
+{
+ /**
+ * The configuration which is manipulated.
+ */
+ private Configuration conf;
+
+ /**
+ * The monitoring interface.
+ */
+ private Monitor monitor;
+
+ /**
+ * The interface to higher level resource managers.
+ */
+ private DRM drm;
+
+ /**
+ * The interface to the configuration solver.
+ */
+ private Solver solver;
+
+ /**
+ * Default path to the logging properties file.
+ */
+ public static final String POOLD_PROPERTIES_PATH =
+ "/usr/lib/pool/poold.properties";
+
+ /**
+ * Logger for records which aren't produced in the Monitoring,
+ * Configuration, or Optimization states. This logger is the
+ * parent to the loggers used in those states.
+ */
+ public static final Logger BASE_LOG = Logger.getLogger(
+ "com.sun.solaris.domain.pools.poold");
+
+ /**
+ * Logger for records produced in the Configuration state.
+ */
+ public static final Logger CONF_LOG = Logger.getLogger(
+ "com.sun.solaris.domain.pools.poold.Configuration");
+
+ /**
+ * Logger for records produced in the Monitoring state.
+ */
+ public static final Logger MON_LOG = Logger.getLogger(
+ "com.sun.solaris.domain.pools.poold.Monitoring");
+
+ /**
+ * Logger for records produced in the Optimization state.
+ */
+ public static final Logger OPT_LOG = Logger.getLogger(
+ "com.sun.solaris.domain.pools.poold.Optimization");
+
+ /**
+ * Singleton instance of Poold.
+ */
+ private static Poold instance;
+
+ /**
+ * The main sampling and solving thread.
+ */
+ private Thread mainThread;
+
+ /**
+ * Process exit code indicating a failure.
+ */
+ private static final int E_PO_FAILURE = 2;
+
+ /**
+ * Keep track of whether initialize() has been invoked, to
+ * output the "starting" message on the first.
+ */
+ private AtomicBoolean firstInitialization = new AtomicBoolean(true);
+
+ /**
+ * Ignore configuration updates for the next interval?
+ */
+ private boolean ignoreUpdates = true;
+
+ /**
+ * Flags whether poold should run or exit.
+ */
+ private AtomicBoolean shouldRun = new AtomicBoolean(true);
+
+ private static class logHelper {
+ /**
+ * Default logfile location
+ */
+ public static final String DEF_LOG_LOC = "/var/log/pool/poold";
+
+ /**
+ * Log location indicating <code>syslog</code>, as
+ * opposed to a file, should be used.
+ */
+ public static final String SYSLOG_LOG_LOC = "SYSLOG";
+
+ /**
+ * Default Log severity (if not overridden)
+ */
+ public static final Severity DEF_SEVERITY = Severity.INFO;
+
+ /**
+ * Name of configuration property, log location.
+ */
+ public static final String PROPERTY_NAME_LOG_LOC =
+ "system.poold.log-location";
+
+ /**
+ * Name of configuration property, log level.
+ */
+ public static final String PROPERTY_NAME_LOG_LEVEL =
+ "system.poold.log-level";
+
+ /**
+ * Location of logfile -- an absolute filename, or
+ * "SYSLOG".
+ */
+ private static String location;
+
+ /**
+ * Logfile handler, responsible for taking log messages
+ * and exporting them.
+ */
+ private static Handler handler;
+
+ /**
+ * Logfile severity, log messages below this severity are
+ * ignored.
+ */
+ private static Severity severity;
+
+ /**
+ * Flag recording whether preinitialization has occurred.
+ */
+ private static boolean preinitialized = false;
+
+ /**
+ * Flag recording whether the logging Severity has been
+ * overridden with the -l command-line option, which
+ * means the console is the only thing being logged to,
+ * and the configuration's logging properties are
+ * ignored.
+ */
+ private static boolean usingConsole;
+
+ /**
+ * Indicates whether logging semantics should be changed
+ * to facilitate debugging.
+ */
+ private static final boolean loggingDebugging = false;
+
+ /**
+ * Do the pre-initialization initialization: install
+ * loggers for reporting errors during initialization.
+ *
+ * @param consoleSeverity If non-null, indicates that
+ * the configuration property-controlled logging behavior
+ * is to be overridden (the <code>-l</code> option was
+ * specified), and messages are to be logged only to the
+ * console, with (at most) the given maximum severity.
+ */
+ private static void preinitialize(Severity consoleSeverity) {
+ if (preinitialized)
+ return;
+
+ /*
+ * Read logging properties affecting the
+ * FileHandler and ConsoleHandler from
+ * <code>poold.properties</code>.
+ */
+ Properties props = new Properties();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ props.load(
+ new FileInputStream(POOLD_PROPERTIES_PATH));
+ props.store(bos, "");
+ LogManager.getLogManager().readConfiguration(
+ new ByteArrayInputStream(
+ bos.toByteArray()));
+ } catch (IOException ioe) {
+ Poold.MON_LOG.log(Severity.WARNING, "could not "
+ + "read logging properties from "
+ + "poold.properties: " + ioe);
+ }
+
+ if (consoleSeverity == null || loggingDebugging) {
+ /*
+ * Log messages to /var/log/pool/poold,
+ * the default location, until the pools
+ * configuration properties are read and
+ * applied, which may change the logging
+ * file and severity.
+ *
+ * Under normal circumstances, it's
+ * expected that NO INFO-level messages
+ * will be emitted until that time; this
+ * is only a measure to ensure that
+ * unanticipated errors are reported in
+ * some log.
+ */
+ location = SYSLOG_LOG_LOC;
+ handler = SyslogHandler.getInstance("poold",
+ Facility.DAEMON);
+ severity = DEF_SEVERITY;
+ handler.setLevel(severity);
+ BASE_LOG.addHandler(handler);
+ }
+
+ if (consoleSeverity != null) {
+ /*
+ * If -l is specified, log to the
+ * console. Unless loggingDebug is
+ * true, this will also mean that the
+ * logging properties are ignored.
+ *
+ * Determine if the user has specified
+ * the use of a ConsoleHandler through
+ * poold.properties.
+ */
+ Logger root = Logger.getLogger("");
+ Handler[] handler = root.getHandlers();
+ ConsoleHandler ch = null;
+ for (int i = 0; i < handler.length && ch ==
+ null; i++)
+ if (handler[i]
+ instanceof ConsoleHandler)
+ ch = (ConsoleHandler)handler[i];
+ /*
+ * If none was previously, install a
+ * ConsoleHandler.
+ */
+ if (ch == null) {
+ ch = new ConsoleHandler();
+
+ ch.setFormatter(
+ new SysloglikeFormatter());
+ ch.setLevel(consoleSeverity);
+ root.addHandler(ch);
+ }
+ severity = consoleSeverity;
+ BASE_LOG.log(Severity.DEBUG,
+ "logging with level " + severity);
+
+ /**
+ * Allow logging properties to be
+ * effective if loggingDebugging is not
+ * set.
+ */
+ if (!loggingDebugging)
+ usingConsole = true;
+ }
+ preinitialized = true;
+ }
+
+ /**
+ * Configure loggers based on the logging-related
+ * configuration properties. Outputs a description of
+ * any changes to the configuration logger.
+ *
+ * @throws ConfigurationException if there is an error
+ * applying libpool configuration properties to
+ * <code>poold</code>
+ */
+ public static void initializeWithConfiguration(
+ Configuration conf) throws ConfigurationException
+ {
+ String newLogLocation;
+ Severity newLogSeverity;
+ String newLogSeverityName = null;
+
+ /*
+ * Set the log location as specified by the
+ * configuration's system properties.
+ */
+ try {
+ newLogLocation = conf.getStringProperty(
+ PROPERTY_NAME_LOG_LOC);
+ } catch (PoolsException e) {
+ newLogLocation = DEF_LOG_LOC;
+ }
+
+ try {
+ newLogSeverityName = conf.getStringProperty(
+ PROPERTY_NAME_LOG_LEVEL);
+ newLogSeverity = Severity.getSeverityWithName(
+ newLogSeverityName);
+ assert(newLogSeverity != null);
+ } catch (PoolsException e) {
+ newLogSeverity = DEF_SEVERITY;
+ } catch (IllegalArgumentException e) {
+ throw(ConfigurationException)
+ (new ConfigurationException(
+ "invalid " + PROPERTY_NAME_LOG_LEVEL +
+ "value: " + newLogSeverityName)
+ .initCause(e));
+ }
+
+ Handler newLogHandler = null;
+
+ /*
+ * (Re)install the logger for the poold class
+ * hierarchy. This means that only poold
+ * messages are controlled by the pools
+ * configuration properties/command-line
+ * options.
+ */
+
+ /*
+ * The logfile is always re-opened, in case the
+ * cause for reinitialization is due to SIGHUP
+ * following a log rotation.
+ */
+ if (handler != null) {
+ BASE_LOG.removeHandler(handler);
+ handler.close();
+ handler = null;
+ }
+
+ if (newLogLocation.toUpperCase().equals(
+ SYSLOG_LOG_LOC.toUpperCase()))
+ newLogHandler =
+ SyslogHandler.getInstance("poold",
+ Facility.DAEMON);
+ else {
+ if (!newLogLocation.startsWith("/"))
+ throw
+ new ConfigurationException(
+ PROPERTY_NAME_LOG_LOC +
+ " value is not an" +
+ " absolute path");
+ try {
+ newLogHandler =
+ new FileHandler(
+ newLogLocation, 0, 1, true);
+ newLogHandler.setFormatter(
+ new SysloglikeFormatter());
+ } catch (java.io.IOException ioe) {
+ Poold.utility.die(
+ Poold.CONF_LOG,
+ new PooldException(
+ newLogLocation +
+ ": can't write")
+ .initCause(ioe), false);
+ }
+ }
+
+ if (!severity.equals(newLogSeverity) ||
+ !location.equals(newLogLocation))
+ CONF_LOG.log(Severity.DEBUG,
+ "logging with level " + severity);
+
+ severity = newLogSeverity;
+ handler = newLogHandler;
+ location = newLogLocation;
+
+ handler.setLevel(severity);
+ BASE_LOG.addHandler(handler);
+ }
+
+ /**
+ * Configure the loggers based on the pool's logging
+ * properties, or, if the -l option was specified on the
+ * command line, continue to use the console.
+ */
+ public static void initialize(Configuration conf)
+ throws ConfigurationException
+ {
+ if (usingConsole)
+ return;
+ else
+ initializeWithConfiguration(conf);
+ }
+
+ /**
+ * Return the current logging level.
+ */
+ public static Severity getSeverity()
+ {
+ return (severity);
+ }
+
+ public static void close()
+ {
+ if (handler != null) {
+ BASE_LOG.removeHandler(handler);
+ handler.close();
+ }
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * Only one poold instance should be running per system.
+ *
+ * @param consoleSeverity If non-null, indicates that the
+ * configuration property-controlled logging behavior is to be
+ * overridden (the <code>-l</code> option was specified), and
+ * messages are to be logged only to the console, with (at most)
+ * the given maximum severity.
+ */
+ private Poold(Severity consoleSeverity)
+ {
+ /*
+ * Establish loggers for recording errors during
+ * initialization. Under normal circumstances, no
+ * messages will be emitted; this is only a measure to
+ * make sure that unanticipated errors are reported in
+ * some log, or the console, if the -l option is used.
+ */
+ logHelper.preinitialize(consoleSeverity);
+
+ /*
+ * Try opening the configuration read-write in hopes the
+ * ability will be possessed henceforth.
+ */
+ try {
+ conf = new Configuration(PoolInternal.
+ pool_dynamic_location(), PoolInternal.PO_RDWR);
+ conf.close();
+ } catch (PoolsException pe) {
+ Poold.utility.die(CONF_LOG, new PooldException(
+ "cannot open dynamic pools configuration " +
+ "read-write (" + pe.getMessage() + ")")
+ .initCause(pe), false);
+ }
+
+ try {
+ conf = new Configuration(PoolInternal.
+ pool_dynamic_location(), PoolInternal.PO_RDONLY);
+ } catch (PoolsException pe) {
+ Poold.utility.die(CONF_LOG, pe);
+ }
+
+ /*
+ * Create the required sub-components:
+ * - a monitoring object
+ * - a DRM implementer
+ * - a solver
+ */
+ monitor = new SystemMonitor();
+ drm = new LogDRM();
+ solver = new SystemSolver(monitor);
+ }
+
+ /**
+ * Returns a reference to the singleton <code>Poold</code>,
+ * constructing one if necessary.
+ *
+ * @param consoleSeverity If non-null, indicates that the
+ * configuration property-controlled logging behavior is to be
+ * overridden (the <code>-l</code> option was specified), and
+ * messages are to be logged only to the console, with (at most)
+ * the given maximum severity.
+ * @throws IllegalArgumentException if the given console
+ * severity doesn't match that of an existing instance.
+ */
+ public static Poold getInstanceWithConsoleLogging(
+ Severity consoleSeverity)
+ {
+ if (instance == null)
+ return (instance = new Poold(consoleSeverity));
+ else
+ if (logHelper.usingConsole == false &&
+ consoleSeverity == null || consoleSeverity !=
+ null && logHelper.getSeverity().equals(
+ consoleSeverity))
+ return (instance);
+ else
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Initializes <code>Poold</code> for operation at startup or
+ * in response to a detected libpool configuration change.
+ */
+ private void initialize()
+ {
+ try {
+ logHelper.initialize(conf);
+ if (firstInitialization.get())
+ CONF_LOG.log(Severity.INFO, "starting");
+ /*
+ * When a system is extremely busy, it may
+ * prove difficult to initialize poold. Just
+ * keep trying until we succeed.
+ */
+ boolean busy = true;
+ while (busy && shouldRun.get()) {
+ busy = false;
+ try {
+ monitor.initialize(conf);
+ CONF_LOG.log(Severity.DEBUG,
+ "configuring solver...");
+ solver.initialize(conf);
+ CONF_LOG.log(Severity.INFO,
+ "configuration complete");
+ } catch (PoolsException pe) {
+ CONF_LOG.log(Severity.INFO,
+ "The system is too busy to " +
+ "initialize, attempting " +
+ "initialization again");
+ /*
+ * pause for a while before
+ * re-attempting the
+ * initialization.
+ */
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException ie) {
+ /*
+ * Safe to ignore this
+ * exception as we
+ * will simply try
+ * again sooner.
+ */
+ }
+ busy = true;
+ } catch (StaleMonitorException sme) {
+ CONF_LOG.log(Severity.INFO,
+ "The system is too busy to " +
+ "initialize, attempting " +
+ "initialization again");
+ /*
+ * pause for a while before
+ * re-attempting the
+ * initialization.
+ */
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException ie) {
+ /*
+ * Safe to ignore this
+ * exception as we
+ * will simply try
+ * again sooner.
+ */
+ }
+ busy = true;
+ }
+ }
+ if (firstInitialization.get())
+ firstInitialization.set(false);
+ } catch (ConfigurationException ce) {
+ Poold.utility.die(CONF_LOG, ce);
+ }
+ }
+
+ /**
+ * Execute <code>Poold</code> indefinitely. This method is
+ * invoked after <code>Poold</code> completes
+ * configuration. It will continue to execute until
+ * <code>Poold</code> is terminated.
+ *
+ * @throws Exception If an there is an error in execution.
+ */
+ private void execute() throws Exception
+ {
+ int changed = 0;
+ boolean confRequired = false;
+
+ while (shouldRun.get()) {
+ try {
+ changed = conf.update();
+ /*
+ * poold modifies the configuration
+ * during startup (updating the PID of
+ * poold) so we have to ignore our
+ * first ever configuration update.
+ */
+ if (ignoreUpdates) {
+ ignoreUpdates = false;
+ changed = 0;
+ }
+ assert(!confRequired || confRequired &&
+ changed != 0);
+ if (changed != 0) {
+ CONF_LOG.log(Severity.DEBUG,
+ "configuration change detected");
+ if (!confRequired)
+ CONF_LOG.log(Severity.INFO,
+ "configuration changed " +
+ "externally");
+ CONF_LOG.log(Severity.INFO,
+ "reconfiguring...");
+ }
+ confRequired = false;
+ } catch (PoolsException pe) {
+ Poold.utility.die(CONF_LOG, pe);
+ }
+ if (changed != 0)
+ initialize();
+
+ boolean gotNext = false;
+ while (shouldRun.get() && !gotNext) {
+ try {
+ monitor.getNext();
+ gotNext = true;
+
+ /*
+ * All workload-dependent
+ * objectives must now be
+ * checked for violations. The
+ * solver holds all objectives
+ * and it makes the decision
+ * about whether a
+ * reconfiguration is required.
+ */
+ if (solver.examine(monitor)) {
+ MON_LOG.log(Severity.INFO,
+ "reconfiguration required");
+ confRequired = solver.solve();
+ } else {
+ MON_LOG.log(Severity.INFO,
+ "all evaluated objectives"
+ + " satisfied");
+ }
+ } catch (StaleMonitorException e) {
+ /*
+ * Later, assert that every
+ * cause of the
+ * StaleMonitorException is
+ * handled by the above
+ * conf.update().
+ */
+ confRequired = true;
+ } catch (InterruptedException ie) {
+ Poold.MON_LOG.log(Severity.INFO,
+ "interrupted");
+ break;
+ }
+ }
+ if (!shouldRun.get())
+ break;
+ System.runFinalization();
+ }
+ Poold.BASE_LOG.log(Severity.NOTICE, "exiting");
+ }
+
+ /**
+ * Cleanup any resources when the application terminates.
+ */
+ private void cleanup()
+ {
+ conf.close();
+ logHelper.close();
+ instance = null;
+ }
+
+ /**
+ * Invoke <code>Poold</code>. This main function is provided
+ * so that <code>poold</code> can be executed. Execution will
+ * continue indefinitely unless there is an error, in which case
+ * when execute() terminates.
+ */
+ public void run()
+ {
+ mainThread = Thread.currentThread();
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ try {
+ cleanup();
+ } catch (Throwable t) {
+ }
+ }
+ });
+
+ try {
+ initialize();
+ execute();
+ } catch (Throwable t) {
+ Poold.utility.die(BASE_LOG, t);
+ }
+ }
+
+ /**
+ * Stops <code>Poold</code>. Sets a flag indicating that run()
+ * should break out of the monitor/solve loop and clean up.
+ */
+ public void shutdown() {
+ /*
+ * Flag that the main thread should break out of the
+ * sample/solve loop as soon as possible.
+ */
+ shouldRun.set(false);
+
+ /*
+ * Interrupt the main thread, which will cause the
+ * monitor to break out of its sleep if it's waiting for
+ * the sample time to arrive, and cause the sample/solve
+ * loop condition to be evaluated sooner. But make some
+ * effort not to cause an InterruptedIOException if
+ * we're not even through initialization yet; we'll get
+ * around to shutting down soon enough.
+ */
+ if (!firstInitialization.get() && mainThread != null)
+ mainThread.interrupt();
+ }
+
+ public static void main(String args[]) throws IllegalArgumentException
+ {
+ Severity severity = null;
+
+ if (args.length > 0) {
+ if (args[0].compareTo("-l") == 0 && args.length == 2) {
+ severity = (Severity) Severity.parse(args[1]);
+ } else
+ throw new IllegalArgumentException(
+ "usage: poold [-l level]");
+ }
+ Poold p = getInstanceWithConsoleLogging(severity);
+ p.run();
+ }
+
+ /**
+ * The <code>utility</code> class provides various
+ * <code>Poold</code> related static utility methods that
+ * don't naturally reside on any class.
+ */
+ static class utility {
+ /**
+ * Outputs a near-final message corresponding
+ * to an exception (or other throwable) to the named
+ * logger before causing the VM to exit. The message
+ * will have ERROR severity unless an instance of
+ * PoolsException is given, in which case the message
+ * will adopt the PoolsException's severity. Similarly,
+ * if the PoolsException specifies an exit code, it will
+ * be used; otherwise the default of
+ * <code>E_PO_FAILURE</code> will be used.
+ *
+ * @param logger Logger used to log the message
+ * @param t The cause. A stack trace will be affixed to
+ * the message.
+ */
+ public static void die(Logger logger, Throwable t)
+ {
+ die(logger, t, true);
+ }
+
+ /**
+ * Outputs a near-final message corresponding
+ * to an exception (or other throwable) to the named
+ * logger before causing the VM to exit. The message
+ * will have ERROR severity unless an instance of
+ * PoolsException is given, in which case the message
+ * will adopt the PoolsException's severity. Similarly,
+ * if the PoolsException specifies an exit code, it will
+ * be used; otherwise the default of
+ * <code>E_PO_FAILURE</code> will be used.
+ *
+ * @param logger Logger used to log the message
+ * @param t The cause.
+ * @param showStackTrace If true, a stack trace will be
+ * affixed to the message.
+ */
+ public static void die(Logger logger, Throwable t,
+ boolean showStackTrace)
+ {
+ try {
+ Severity severity;
+ /*
+ * Configure the message's exception and
+ * severity.
+ */
+ LogRecord record;
+ if (t instanceof PooldException)
+ record = new LogRecord(
+ ((PooldException)t).getSeverity(),
+ t.getMessage());
+ else
+ record = new LogRecord(Severity.ERR,
+ t.getMessage());
+ if (record.getMessage() == null)
+ record.setMessage("exception " +
+ t.getClass().getName());
+ if (showStackTrace)
+ record.setThrown(t);
+
+ record.setLoggerName(logger.getName());
+ logger.log(record);
+
+ if (logHelper.handler != null)
+ logHelper.handler.flush();
+ if (t instanceof PooldException)
+ System.exit(((PooldException)t)
+ .getExitCode());
+ else
+ System.exit(E_PO_FAILURE);
+ } catch (Exception e) {
+ SuccinctStackTraceFormatter.printStackTrace(e);
+ System.exit(-1);
+ }
+ }
+
+ /**
+ * Outputs a warning-level message to the named logger.
+ *
+ * @param logger Logger used to log the message
+ * @param t The cause.
+ * @param showStackTrace If true, a stack trace will be
+ * affixed to the message.
+ */
+ public static void warn(Logger logger, Throwable t,
+ boolean showStackTrace)
+ {
+ try {
+ Severity severity;
+ /*
+ * Configure the message's exception and
+ * severity.
+ */
+ LogRecord record;
+ if (t instanceof PooldException)
+ record = new LogRecord(
+ ((PooldException)t).getSeverity(),
+ t.getMessage());
+ else
+ record = new LogRecord(Severity.WARNING,
+ t.getMessage());
+ if (record.getMessage() == null)
+ record.setMessage("exception " +
+ t.getClass().getName());
+ if (showStackTrace)
+ record.setThrown(t);
+
+ record.setLoggerName(logger.getName());
+ logger.log(record);
+
+ if (logHelper.handler != null)
+ logHelper.handler.flush();
+ } catch (Exception e) {
+ SuccinctStackTraceFormatter.printStackTrace(e);
+ System.exit(-1);
+ }
+ }
+ }
+}
+
+class ConfigurationException extends Exception
+{
+ public ConfigurationException(String message)
+ {
+ super(message);
+ }
+}
+
+class IllegalOFValueException extends RuntimeException
+{
+ public IllegalOFValueException(String message)
+ {
+ super(message);
+ }
+}
+
+class PooldException extends Exception {
+ /**
+ * The exit code which the virtual machine should exit at if
+ * this exception cannot be handled.
+ */
+ private int exitCode;
+
+ /**
+ * The severity of this message. See <code>Severity</code>.
+ */
+ private Severity severity;
+
+ /**
+ * Constructs a message with default exit code and
+ * <code>System.ERR</code> severity.
+ */
+ public PooldException(String message)
+ {
+ this(message, 1, Severity.ERR);
+ }
+
+ /**
+ * Constructs a message with given exit code and
+ * <code>System.ERR</code> severity.
+ */
+ public PooldException(String message, int exitCode)
+ {
+ this(message, exitCode, Severity.ERR);
+ }
+
+ /**
+ * Constructs a message with a given exit code and severity.
+ */
+ public PooldException(String message, int exitCode, Severity severity)
+ {
+ super(message);
+ this.exitCode = exitCode;
+ this.severity = severity;
+ }
+
+ /**
+ * The exit code which the virtual machine should exit at if
+ * this exception cannot be handled.
+ */
+ public int getExitCode()
+ {
+ return (exitCode);
+ }
+
+ public Severity getSeverity()
+ {
+ return (severity);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/ResourceMonitor.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/ResourceMonitor.java
new file mode 100644
index 0000000000..36280e425e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/ResourceMonitor.java
@@ -0,0 +1,255 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Iterator;
+import com.sun.solaris.service.pools.Component;
+import com.sun.solaris.service.pools.Resource;
+import com.sun.solaris.service.pools.PoolsException;
+import com.sun.solaris.service.pools.UnsignedInt64;
+
+/**
+ * This represents a monitored resource and the techniques used to
+ * monitor the resource.
+ */
+class ResourceMonitor extends HashMap
+{
+ /**
+ * The monitored resource.
+ */
+ private Resource target;
+
+ /**
+ * The size of the statistic buffer.
+ */
+ private final int maxSize;
+
+ /**
+ * Cached list of components to be monitored.
+ */
+ private LinkedList compList;
+
+ /**
+ * Constructor. No monitor target and a default buffer size of
+ * 50.
+ */
+ public ResourceMonitor()
+ {
+ this(null, 50);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param target The resource to be monitored.
+ * @param maxSize The maximum number of samples to be held.
+ */
+ public ResourceMonitor(Resource target, int maxSize)
+ {
+ super();
+ this.target = target;
+ this.maxSize = maxSize;
+ compList = new LinkedList();
+
+ }
+
+ /**
+ * Initialize the resource monitor with it's list of
+ * components. Components which are off-line or powered-off
+ * cannot be monitored, so they should be removed from the
+ * list of components.
+ *
+ * @throws PoolsException if there is an error accessing the
+ * pool elements.
+ */
+ public void initialize() throws PoolsException
+ {
+ compList.clear();
+ List candidates = target.getComponents(null);
+ Iterator candIt = candidates.iterator();
+ while (candIt.hasNext()) {
+ Component comp = (Component) candIt.next();
+ String status = comp.getStringProperty("cpu.status");
+ if (status.compareTo("off-line") != 0 &&
+ status.compareTo("powered-off") != 0)
+ compList.add(comp);
+ }
+ }
+
+ /**
+ * Get the list of components which are actively monitored by
+ * this resource.
+ */
+ public List getComponents()
+ {
+ return ((List) compList.clone());
+ }
+
+ /**
+ * Return the maximum number of samples this monitor will
+ * hold.
+ */
+ public int getMaxSampleSize()
+ {
+ return (maxSize);
+ }
+
+ /**
+ * Return the object which is being monitored.
+ */
+ public Resource getMonitored()
+ {
+ return (target);
+ }
+
+ /**
+ * Set the resource to be monitored. A resource target can
+ * only be set once, if you attempt to modify it then an
+ * IllegalArgumentException is thrown.
+ *
+ * @param target The resource to be monitored.
+ * @throws IllegalArgumentException if the target has already
+ * been set.
+ */
+ public void setResource(Resource target)
+ {
+ if (this.target != null)
+ this.target = target;
+ else
+ throw new IllegalArgumentException("Once the target " +
+ "of a ResourceMonitor is set, it cannot be " +
+ "changed.");
+ }
+
+ /**
+ * Return the name of the monitored object.
+ *
+ * @throws PoolsException if there is an error accessing the
+ * pool element.
+ */
+ public String getName() throws PoolsException
+ {
+ String type = target.getStringProperty("type");
+ return (target.getStringProperty(type + ".name"));
+ }
+
+ /**
+ * Update the derived statistics.
+ */
+ public void updateDerived()
+ {
+ StatisticList util = (StatisticList) get("utilization");
+ AggregateStatistic stat = calcDerivedStatistic("utilization");
+ if (stat != null)
+ util.add(stat);
+ }
+
+ /**
+ * Get a derived statistic.
+ *
+ * @param name The name of the statistic to get.
+ */
+ public AggregateStatistic getDerivedStatistic(String name)
+ {
+ return ((AggregateStatistic)((StatisticList)get(name)).
+ getLast());
+ }
+
+ /**
+ * Return the latest value of a derived statistic.
+ *
+ * @param name is the name of the derived statistic to be
+ * returned.
+ */
+ private AggregateStatistic calcDerivedStatistic(String name)
+ {
+ /*
+ * The only statistic which can be obtained from this
+ * resource monitor is utilization. A utilization
+ * statistic actually represents a complex
+ * manipulation of several lower level
+ * statistics. This manipulation is performed here
+ * until a good interface can be thought through which
+ * best captures this abstraction.
+ */
+ if (name.compareTo("utilization") != 0)
+ throw new IllegalArgumentException("No such derived "
+ + "statistic: " + name);
+ /*
+ * This statistic is based on lower level
+ * monotonically increasing numbers. The statistic can
+ * thus only be derived as an observation of the
+ * change in value over time of these values.
+ */
+
+ StatisticList first = (StatisticList) get("idle");
+
+ switch (first.size()) {
+ case 0:
+ case 1:
+ return (null);
+ default:
+ BigInteger total = new BigInteger("0");
+ double utilV = 0.0;
+ double idleV = 0.0;
+ LinkedList keys = new LinkedList(keySet());
+ keys.remove("utilization");
+ for (int i = 0; i < keys.size(); i++) {
+ StatisticList sl = (StatisticList) get(keys.
+ get(i));
+ AggregateStatistic sv1 = (AggregateStatistic)
+ sl.getLast();
+ AggregateStatistic sv2 = (AggregateStatistic)
+ sl.get(sl.size() - 2);
+ if (sl.getName().compareTo("idle") == 0)
+ idleV = ((UnsignedInt64) sv1.
+ subtract(sv2).getValue()).
+ doubleValue();
+ total = total.add((UnsignedInt64) sv1.
+ subtract(sv2).getValue());
+ }
+ utilV = 100 * ((total.doubleValue() - idleV) /
+ total.doubleValue());
+ return (new DoubleStatistic(new Double(utilV),
+ ((AggregateStatistic)first.get(first.size() -
+ 2)).getStart(), ((AggregateStatistic)first.
+ getLast()).getEnd()));
+ }
+ }
+
+ void resetData(String name)
+ {
+ StatisticList sl = (StatisticList) get(name);
+ sl.clear();
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Solver.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Solver.java
new file mode 100644
index 0000000000..cae0549f51
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Solver.java
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.util.Set;
+
+import com.sun.solaris.service.pools.Configuration;
+import com.sun.solaris.service.pools.Element;
+import com.sun.solaris.service.pools.PoolsException;
+
+/**
+ * This interface specifies the contract between poold and the poold
+ * allocation algorithms.
+ */
+
+public interface Solver {
+ /**
+ * Initialize the solver.
+ *
+ * @param conf The configuration to be manipulated.
+ * @throws PoolsException If the initialization fails.
+ */
+ public void initialize(Configuration conf) throws PoolsException;
+
+ /**
+ * Evaluate whether a workload based reconfiguration is
+ * required.
+ *
+ * @param mon The monitor to be used during examination.
+ * @throws PoolsException If the examination fails.
+ * @throws StaleMonitorException If the monitor is stale.
+ */
+ public boolean examine(Monitor mon) throws PoolsException,
+ StaleMonitorException;
+
+ /**
+ * Allocate resources. Return true if a change was made.
+ *
+ * @throws Exception If the solve fails.
+ */
+ public boolean solve() throws Exception;
+
+ /**
+ * Return true if all examined resources are capable of
+ * providing statistically valid data.
+ *
+ * If any of the monitored resources have not accumulated
+ * enough data to be statistically significant, then this
+ * monitor is not ready to be used to obtain data for all
+ * resources. In this case, false is returned.
+ *
+ */
+ public boolean isValid();
+
+ /**
+ * Return a reference to the monitor which this solver is
+ * using to provide statistics about the configuration which
+ * is to be solved.
+ */
+ public Monitor getMonitor();
+
+ /**
+ * Return the set of objectives associated with the supplied
+ * element.
+ *
+ * @param elem Retrieve objectives for this element.
+ */
+ public Set getObjectives(Element elem);
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Statistic.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Statistic.java
new file mode 100644
index 0000000000..819c13266b
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/Statistic.java
@@ -0,0 +1,491 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Iterator;
+import java.text.*;
+
+import com.sun.solaris.service.pools.UnsignedInt64;
+
+/**
+ * Contains the information relating to a specific statistic for an
+ * object. The Statistic has no notion of the source of the data, it
+ * is simply a repository for holding statistical information.
+ */
+interface Statistic
+{
+ /**
+ * Return the start of the sample period for which the
+ * statistic is representative.
+ */
+ public Date getStart();
+
+ /**
+ * Return the end of the sample period for which the
+ * statistic is representative.
+ */
+ public Date getEnd();
+
+ /**
+ * Get the value of this statistic.
+ */
+ public Object getValue();
+
+ /**
+ * Get the value of this statistic as a Long.
+ */
+ public Long getLongValue();
+
+ /**
+ * Get the value of this statistic as a Double.
+ */
+ public Double getDoubleValue();
+
+ /**
+ * Get the value of this statistic as a UnsignedInt64.
+ */
+ public UnsignedInt64 getUnsignedInt64Value();
+}
+
+/**
+ * An interface for Statistics which may be aggregated.
+ */
+interface AggregateStatistic extends Statistic
+{
+ /**
+ * Add the supplied statistic to this.
+ *
+ * @param o The other statistic.
+ */
+ public AggregateStatistic add(AggregateStatistic o);
+
+ /**
+ * Subtract the supplied statistic from this.
+ *
+ * @param o The other statistic.
+ */
+ public AggregateStatistic subtract(AggregateStatistic o);
+
+ /**
+ * Produce the aggregate of all objects in the supplied
+ * iterator (which must be of the same type) whose start and
+ * end dates lie within the supplied ranges. If either start
+ * or end is null, then that bound is not applied. i.e. if no
+ * start date is supplied, then start checking is disabled.
+ *
+ * @param start The start date for qualification in the snapshot.
+ * @param end The end date for qualification in the snapshot.
+ * @throws IllegalArgumentException If the iterator is empty.
+ */
+ public AggregateStatistic getSnapshotForInterval(Iterator it,
+ Date start, Date end) throws IllegalArgumentException;
+}
+
+/**
+ * A basic Statistic implementation which makes it easy to derive
+ * concrete statistic types. This is an immutable class, the state is
+ * set when the object is constructed and cannot be later changed.
+ */
+abstract class AbstractStatistic implements Statistic
+{
+ /**
+ * The value of the statistic.
+ */
+ private final Object value;
+
+ /**
+ * The start of the interval during which the statistic was
+ * captured.
+ */
+ private final Date start;
+
+ /**
+ * The end of the interval during which the statistic was
+ * captured.
+ */
+ private final Date end;
+
+ /**
+ * Formatter for the sample start time, used by toString().
+ */
+ private static final DateFormat df = new SimpleDateFormat("kk:mm:ss");
+
+ /**
+ * Constructor. This is provided as a mechanism to allow
+ * inherited classes to correctly initialize their state.
+ *
+ * @param value The value of this statistic.
+ */
+ protected AbstractStatistic(Object value)
+ {
+ this(value, null, null);
+ }
+
+ /**
+ * Constructor. This is provided as a mechanism to allow
+ * inherited classes to correctly initialize their state.
+ *
+ * @param value The value of this statistic.
+ * @param start The start of the sample period which this
+ * statistic represents.
+ * @param end The end of the sample period which this
+ * statistic represents.
+ */
+ protected AbstractStatistic(Object value, Date start, Date end)
+ {
+ this.value = value;
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * Return the start of the sample period for which the
+ * statistic is representative.
+ */
+ public Date getStart()
+ {
+ return (start);
+ }
+
+
+ /**
+ * Return the end of the sample period for which the
+ * statistic is representative.
+ */
+ public Date getEnd()
+ {
+ return (end);
+ }
+
+ /**
+ * Get the value of this statistic.
+ */
+ public Object getValue()
+ {
+ return (value);
+ }
+
+ public abstract Long getLongValue();
+ public abstract Double getDoubleValue();
+ public abstract UnsignedInt64 getUnsignedInt64Value();
+
+ /**
+ * Return the string representation of this statistic.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(value);
+ if (start != null && end != null) {
+ buf.append(" from ");
+ buf.append(df.format(start));
+ buf.append(" to ");
+ buf.append(df.format(end));
+ }
+ return (buf.toString());
+ }
+}
+
+/**
+ * A statistic of type Double.
+ */
+final class DoubleStatistic extends AbstractStatistic
+ implements AggregateStatistic
+{
+
+ /**
+ * Constructor.
+ *
+ * @param value The value of this statistic.
+ */
+ public DoubleStatistic(Double value)
+ {
+ super(value);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param value The value of this statistic.
+ * @param start The start of the interval over which this
+ * statistic is representative.
+ * @param end The end of the interval over which this
+ * statistic is representative.
+ */
+ public DoubleStatistic(Double value, Date start, Date end)
+ {
+ super(value, start, end);
+ }
+
+ public Double getDoubleValue()
+ {
+ return ((Double) getValue());
+ }
+
+ public Long getLongValue()
+ {
+ return (new Long(((Double) getValue()).longValue()));
+ }
+
+ public UnsignedInt64 getUnsignedInt64Value()
+ {
+ return (new UnsignedInt64(Long.toString(((Double) getValue()).
+ longValue())));
+ }
+
+ public AggregateStatistic add(AggregateStatistic o)
+ {
+ Double v1 = getDoubleValue();
+ Double v2 = o.getDoubleValue();
+
+ return (new DoubleStatistic(new Double(v1.doubleValue() +
+ v2.doubleValue()),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic subtract(AggregateStatistic o)
+ {
+ Double v1 = getDoubleValue();
+ Double v2 = o.getDoubleValue();
+
+ return (new DoubleStatistic(new Double(v1.doubleValue() -
+ v2.doubleValue()),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic getSnapshotForInterval(Iterator it,
+ Date start, Date end) throws IllegalArgumentException
+ {
+ double total = 0;
+ int count = 0;
+ Date first = start, last = end;
+
+ while (it.hasNext()) {
+ DoubleStatistic s = (DoubleStatistic) it.next();
+ if (start != null) {
+ if (s.getStart().compareTo(start) < 0)
+ continue;
+ }
+ if (first == null)
+ first = s.getStart();
+ if (end != null) {
+ if (s.getEnd().compareTo(end) > 0)
+ continue;
+ }
+ last = s.getEnd();
+ total += s.getDoubleValue().doubleValue();
+ count++;
+ }
+ if (count == 0)
+ throw new IllegalArgumentException("Cannot derive a " +
+ "snapshot from an empty iterator");
+ return (new DoubleStatistic(new Double(total / count), first,
+ last));
+ }
+}
+
+/**
+ * A statistic of type Long.
+ */
+final class LongStatistic extends AbstractStatistic
+ implements AggregateStatistic
+{
+
+ /**
+ * Constructor.
+ *
+ * @param value The value of this statistic.
+ * @param start The start of the interval over which this
+ * statistic is representative.
+ * @param end The end of the interval over which this
+ * statistic is representative.
+ */
+ public LongStatistic(Long value, Date start, Date end)
+ {
+ super(value, start, end);
+ }
+
+ public Double getDoubleValue()
+ {
+ return (new Double(((Long) getValue()).longValue()));
+ }
+
+ public Long getLongValue()
+ {
+ return ((Long) getValue());
+ }
+
+ public UnsignedInt64 getUnsignedInt64Value()
+ {
+ return (new UnsignedInt64(Long.toString(((Long) getValue()).
+ longValue())));
+ }
+
+ public AggregateStatistic add(AggregateStatistic o)
+ {
+ Long v1 = getLongValue();
+ Long v2 = o.getLongValue();
+
+ return (new LongStatistic(new Long(v1.longValue() +
+ v2.longValue()),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic subtract(AggregateStatistic o)
+ {
+ Long v1 = getLongValue();
+ Long v2 = o.getLongValue();
+
+ return (new LongStatistic(new Long(v1.longValue() -
+ v2.longValue()),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic getSnapshotForInterval(Iterator it,
+ Date start, Date end) throws IllegalArgumentException
+ {
+ long total = 0;
+ int count = 0;
+ Date first = start, last = end;
+ while (it.hasNext()) {
+ LongStatistic s = (LongStatistic) it.next();
+ if (start != null) {
+ if (s.getStart().compareTo(start) < 0)
+ continue;
+ }
+ if (first == null)
+ first = s.getStart();
+ if (end != null) {
+ if (s.getEnd().compareTo(end) > 0)
+ continue;
+ }
+ last = s.getEnd();
+ total += s.getLongValue().longValue();
+ count++;
+ }
+ if (count == 0)
+ throw new IllegalArgumentException("Cannot derive a " +
+ "snapshot from an empty iterator");
+ return (new LongStatistic(new Long(total / count), first,
+ last));
+ }
+}
+
+/**
+ * A statistic of type UnsignedInt64.
+ */
+final class UnsignedInt64Statistic extends AbstractStatistic
+ implements AggregateStatistic
+{
+
+ /**
+ * Constructor.
+ *
+ * @param value The value of this statistic.
+ * @param start The start of the interval over which this
+ * statistic is representative.
+ * @param end The end of the interval over which this
+ * statistic is representative.
+ */
+ public UnsignedInt64Statistic(UnsignedInt64 value, Date start,
+ Date end)
+ {
+ super(value, start, end);
+ }
+
+ public Double getDoubleValue()
+ {
+ return (new Double(((UnsignedInt64) getValue()).longValue()));
+ }
+
+ public Long getLongValue()
+ {
+ return (new Long(((UnsignedInt64) getValue()).longValue()));
+ }
+
+ public UnsignedInt64 getUnsignedInt64Value()
+ {
+ return ((UnsignedInt64) getValue());
+ }
+
+ public AggregateStatistic add(AggregateStatistic o)
+ {
+ UnsignedInt64 v1 = getUnsignedInt64Value();
+ UnsignedInt64 v2 = o.getUnsignedInt64Value();
+
+ return (new UnsignedInt64Statistic(
+ new UnsignedInt64(v1.add(v2)),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic subtract(AggregateStatistic o)
+ {
+ UnsignedInt64 v1 = getUnsignedInt64Value();
+ UnsignedInt64 v2 = o.getUnsignedInt64Value();
+
+ return (new UnsignedInt64Statistic(
+ new UnsignedInt64(v1.subtract(v2)),
+ getStart(), getEnd()));
+ }
+
+ public AggregateStatistic getSnapshotForInterval(Iterator it,
+ Date start, Date end) throws IllegalArgumentException
+ {
+ BigInteger total = new BigInteger("0");
+ int count = 0;
+ Date first = start, last = end;
+ while (it.hasNext()) {
+ UnsignedInt64Statistic s = (UnsignedInt64Statistic)
+ it.next();
+ if (start != null) {
+ if (s.getStart().compareTo(start) < 0)
+ continue;
+ }
+ if (first == null)
+ first = s.getStart();
+
+ if (end != null) {
+ if (s.getEnd().compareTo(end) > 0)
+ continue;
+ }
+ last = s.getEnd();
+ total = total.add(s.getUnsignedInt64Value());
+ count++;
+ }
+ if (count == 0)
+ throw new IllegalArgumentException("Cannot derive a " +
+ "snapshot from an empty iterator");
+ return (new UnsignedInt64Statistic(
+ new UnsignedInt64(total.divide(new BigInteger(
+ Integer.toString(count)))), first, last));
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/StatisticList.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/StatisticList.java
new file mode 100644
index 0000000000..64dcb8ed45
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/StatisticList.java
@@ -0,0 +1,737 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+
+import java.util.*;
+import java.text.DecimalFormat;
+
+import com.sun.solaris.service.logging.*;
+
+/**
+ * Contains information about statistics. An instance must only
+ * contain Statistics of the same type.
+ */
+class StatisticList extends LinkedList
+{
+ /**
+ * The name of the statistic.
+ */
+ private final String name;
+
+ /**
+ * The maximum number of samples to be stored.
+ */
+ private final int maxSize;
+
+ /**
+ * The list of StatisticListeners.
+ */
+ private List listeners;
+
+ /**
+ * Statistically assess utilization.
+ */
+ private StatisticOperations statisticOperations;
+
+ /**
+ * Constructor.
+ */
+ public StatisticList()
+ {
+ this("default", 10);
+ }
+
+ /**
+ * Constructor. Statistics will not be held for this set.
+ *
+ * @param name is the name of the contained statistics
+ * @param size is the maximum number of statistics to hold
+ */
+ public StatisticList(String name, int size)
+ {
+ this(name, size, false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name is the name of the contained statistics
+ * @param size is the maximum number of statistics to hold
+ * @param doStats indicates whether or not statistics should
+ * be calculated for the data.
+ */
+ public StatisticList(String name, int size, boolean doStats)
+ throws IllegalArgumentException
+ {
+ super();
+ this.name = name;
+ if (size < 1)
+ throw new IllegalArgumentException("Size must be > 0");
+ this.maxSize = size;
+ listeners = new LinkedList();
+ if (doStats) {
+ statisticOperations = new StatisticOperations(this);
+ addStatisticListener(statisticOperations);
+ }
+ }
+
+ /**
+ * Return the name of the Statistics being sampled.
+ */
+ public String getName()
+ {
+ return (name);
+ }
+
+ /**
+ * Return a "snapshot" which is the aggregation of all
+ * statistic records.
+ *
+ * @throws NoSuchElementException if there is an error
+ * accessing a list member.
+ */
+ public AggregateStatistic getSnapshot()
+ throws NoSuchElementException
+ {
+ return (getSnapshotForInterval(iterator(), null, null));
+ }
+
+ /**
+ * Return a "snapshot" of the data using the supplied
+ * iterator.
+ *
+ * @param it An iterator over the contained elements to be
+ * used as the basis for the snapshot.
+ * @throws NoSuchElementException if there is an error
+ * accessing a list member.
+ */
+ private AggregateStatistic getSnapshot(Iterator it)
+ throws NoSuchElementException
+ {
+ return (getSnapshotForInterval(it, null, null));
+ }
+
+ /**
+ * Returns the aggregated value for the StatisticList only
+ * including samples which satisfy the start and end criteria.
+ *
+ * @param start start time or null if unspecified.
+ * @param end end time or null if unspecified.
+ * @throws NoSuchElementException if there is an error
+ * accessing a list member.
+ */
+ public AggregateStatistic getSnapshotForInterval(Date start,
+ Date end) throws NoSuchElementException
+
+ {
+ return (getSnapshotForInterval(iterator(), start, end));
+ }
+
+ /**
+ * Returns the aggregated value for the StatisticList only
+ * including samples which satisfy the start and end criteria.
+ *
+ * @param it An iterator over the contained elements to be
+ * used as the basis for the snapshot.
+ * @param start start time or null if unspecified.
+ * @param end end time or null if unspecified.
+ * @throws NoSuchElementException if there is an error
+ * accessing a list member.
+ */
+ private AggregateStatistic getSnapshotForInterval(Iterator it,
+ Date start, Date end)
+ {
+ AggregateStatistic f = (AggregateStatistic) getFirst();
+ return (f.getSnapshotForInterval(it, start, end));
+ }
+
+ /**
+ * Add the supplied object to the list. If the list is full,
+ * remove the first entry before adding the new entry.
+ *
+ * @param o Object to add to the list.
+ */
+ public boolean add(Object o)
+ {
+ boolean ret;
+ if (size() == maxSize)
+ removeFirst();
+ ret = super.add(o);
+ if (ret)
+ notifyStatisticAdd((AggregateStatistic) o);
+ return (ret);
+ }
+
+ /**
+ * Remove the supplied object from the list.
+ *
+ * @param o Object to remove from the list.
+ */
+ public boolean remove(Object o)
+ {
+ boolean ret;
+ ret = super.remove(o);
+ if (ret)
+ notifyStatisticRemove((AggregateStatistic) o);
+ return (ret);
+ }
+
+ /**
+ * Removes and returns the first element from this list.
+ *
+ * @return the first element from this list.
+ * @throws NoSuchElementException if this list is empty.
+ */
+ public Object removeFirst() {
+ Object first = getFirst();
+ remove(first);
+ return (first);
+ }
+
+ /**
+ * Add a listener for StatisticEvents.
+ *
+ * @param l Listener to add.
+ */
+ public void addStatisticListener(StatisticListener l) {
+ listeners.add(l);
+ }
+
+ /**
+ * Remove a listener for StatisticEvents.
+ *
+ * @param l Listener to remove.
+ */
+ public void removeStatisticListener(StatisticListener l) {
+ listeners.remove(l);
+ }
+
+ /**
+ * Notify all StatisticEvent listeners of a new Add event.
+ *
+ * @param s Event payload.
+ */
+ private void notifyStatisticAdd(AggregateStatistic s)
+ {
+ StatisticEvent e = new StatisticEvent(this,
+ StatisticEvent.ADD, s);
+
+ Iterator listIt = listeners.iterator();
+
+ while (listIt.hasNext()) {
+
+ StatisticListener l = (StatisticListener)listIt.next();
+ l.onStatisticAdd(e);
+ }
+ }
+
+ /**
+ * Notify all StatisticEvent listeners of a new Remove event.
+ *
+ * @param s Event payload.
+ */
+ private void notifyStatisticRemove(AggregateStatistic s)
+ {
+ StatisticEvent e = new StatisticEvent(this,
+ StatisticEvent.REMOVE, s);
+
+ Iterator listIt = listeners.iterator();
+
+ while (listIt.hasNext()) {
+
+ StatisticListener l = (StatisticListener)listIt.next();
+ l.onStatisticRemove(e);
+ }
+ }
+
+ /**
+ * Return true if the contents of the instance are
+ * statistically valid.
+ */
+ boolean isValid()
+ {
+ return (statisticOperations.isValid());
+ }
+
+ /**
+ * Return the zone of control to which the supplied val
+ * belongs based on the target details in the supplied
+ * objective expression.
+ *
+ * @param kve Objective expression used to determine zone
+ * details.
+ * @param val The value to be assessed.
+ */
+ int getZone(KVOpExpression kve, double val)
+ {
+ return (statisticOperations.getZone(kve, val));
+ }
+
+ /**
+ * Return the zone of control to which the supplied val
+ * belongs based on the mean of the sampled data.
+ *
+ * @param val The value to be assessed.
+ */
+ int getZoneMean(double val)
+ {
+ return (statisticOperations.getZoneMean(val));
+ }
+
+ /**
+ * Return the difference (gap) between the target utilization
+ * expressed in the supplied objective expression and the
+ * supplied value.
+ *
+ * @param kve Objective expression used to determine target
+ * utilization details.
+ * @param val The value to be assessed.
+ */
+ double getGap(KVOpExpression kve, double val)
+ {
+ return (statisticOperations.getGap(kve, val));
+ }
+
+ /**
+ * Clear all the data from the StatisticList and reset all the
+ * statistic counters.
+ */
+ public void clear()
+ {
+ if (statisticOperations != null) {
+ removeStatisticListener(statisticOperations);
+ statisticOperations = new StatisticOperations(this);
+ addStatisticListener(statisticOperations);
+ }
+ super.clear();
+ }
+
+ /**
+ * Return a string which describes the zones for this set of
+ * data.
+ *
+ * @param kve The expression containing objectives.
+ * @param val The value to be assessed against objectives.
+ */
+ public String toZoneString(KVOpExpression kve, double val)
+ {
+ return (statisticOperations.toZoneString(kve, val));
+ }
+}
+
+/**
+ * Event class which describes modifications (Add, Remove) to a
+ * StatisticList instance.
+ */
+final class StatisticEvent extends EventObject
+{
+ /**
+ * Identifier for an ADD event.
+ */
+ public static final int ADD = 0x1;
+
+ /**
+ * Identifier for a REMOVE event.
+ */
+ public static final int REMOVE = 0x2;
+
+ /**
+ * The target of the event.
+ */
+ private final AggregateStatistic target;
+
+ /**
+ * The identifier of this event.
+ */
+ private final int id;
+
+ /**
+ * Constructor.
+ *
+ * @param source The source of the event.
+ * @param id The type of the event.
+ * @param target The target of the event.
+ */
+ public StatisticEvent(Object source, int id, AggregateStatistic target)
+ {
+ super(source);
+ this.id = id;
+ this.target = target;
+ }
+
+ /**
+ * Return the target of the event.
+ */
+ public AggregateStatistic getTarget()
+ {
+ return (target);
+ }
+
+ /**
+ * Return the ID (type) of the event.
+ */
+ public int getID()
+ {
+ return (id);
+ }
+
+ /**
+ * Return the source of the event. This is a typesafe
+ * alternative to using getSource().
+ */
+ public StatisticList getStatisticList()
+ {
+ return ((StatisticList) source);
+ }
+
+}
+
+/**
+ * The listener interface for receiving statistic events. The class
+ * that is interested in processing a statistic event implements this
+ * interface, and the object created with that class is registered
+ * with a component, using the component's addStatisticListener
+ * method. When the statistic event occurs, the relevant method in the
+ * listener object is invoked, and the StatisticEvent is passed to it.
+ */
+interface StatisticListener extends EventListener
+{
+ /**
+ * Invoked when a statistic is added to the source
+ * StatisticList.
+ *
+ * @param e The event.
+ */
+ public void onStatisticAdd(StatisticEvent e);
+
+ /**
+ * Invoked when a statistic is removed from the source
+ * StatisticList.
+ *
+ * @param e The event.
+ */
+ public void onStatisticRemove(StatisticEvent e);
+}
+
+/**
+ * This class performs statistical calculations on a source
+ * StatisticList. Zones are regions in a set of samples which are set
+ * to be at 1, 2 and 3 standard deviations from the mean. ZONEC is
+ * closest to the center, with ZONEZ representing the region beyond
+ * ZONEA.
+ */
+class StatisticOperations implements StatisticListener
+{
+ /**
+ * Control zone C.
+ */
+ public static final int ZONEC = 0x00010;
+
+ /**
+ * Control zone B.
+ */
+ public static final int ZONEB = 0x00100;
+
+ /**
+ * Control zone A.
+ */
+ public static final int ZONEA = 0x01000;
+
+ /**
+ * Control zone Z.
+ */
+ public static final int ZONEZ = 0x10000;
+
+ /**
+ * Direction from mean (used to test ZONELT and ZONEGT).
+ */
+ public static final int ZONET = 0x00001;
+
+ /**
+ * Less than the mean.
+ */
+ public static final int ZONELT = 0x00000;
+
+ /**
+ * Greater than the mean.
+ */
+ public static final int ZONEGT = 0x00001;
+
+ /**
+ * The raw statistical data.
+ */
+ private final StatisticList statistics;
+
+ /**
+ * The mean of the samples.
+ */
+ private double mean;
+
+ /**
+ * The standard deviation of the samples.
+ */
+ private double sd;
+
+ /**
+ * The total of the samples.
+ */
+ private AggregateStatistic total;
+
+ /**
+ * Constructs a new StatisticOperations object for working on
+ * the given statistic, whose values are in the given
+ * (modifiable) data set.
+ *
+ * @param statistics The statistics to operate on.
+ */
+ public StatisticOperations(StatisticList statistics)
+ {
+ this.statistics = statistics;
+ total = new DoubleStatistic(new Double(0.0));
+ }
+
+ /**
+ * Calculate the standard deviation for the data held in the
+ * associated StatisticsList.
+ */
+ private void calc_sd()
+ {
+ Iterator it;
+
+ sd = 0;
+ it = statistics.iterator();
+ while (it.hasNext()) {
+ Double val = (Double)((DoubleStatistic)
+ ((AggregateStatistic)it.next())).getValue();
+
+ sd += java.lang.Math.pow(val.doubleValue() - mean, 2);
+ }
+ sd /= statistics.size();
+ sd = java.lang.Math.sqrt(sd);
+ }
+
+ /**
+ * Return a string which describes the zones for this set of
+ * data.
+ *
+ * @param kve The expression containing objectives.
+ * @param val The value to be assessed against objectives.
+ */
+ public String toZoneString(KVOpExpression kve, double val)
+ {
+ if (isValid()) {
+ DecimalFormat f = new DecimalFormat("00.00");
+ double target = kve.getValue();
+
+ if (kve.getOp() == KVOpExpression.LT) {
+ target -= 3 * sd;
+ } else if (kve.getOp() == KVOpExpression.GT) {
+ target += 3 * sd;
+ }
+ StringBuffer buf = new StringBuffer();
+ buf.append(kve.toString());
+ buf.append("\nsample = " + statistics.size());
+ buf.append("\n\ttarget: " + f.format(target));
+ buf.append("\n\tvalue: " + f.format(val));
+ buf.append("\n\tsd: " + f.format(sd));
+ buf.append("\n\tZones:");
+ buf.append("\n\t\tC:" + f.format(target - sd));
+ buf.append("-" + f.format(target + sd));
+ buf.append("\n\t\tB:" + f.format(target - 2 * sd));
+ buf.append("-" + f.format(target + 2 * sd));
+ buf.append("\n\t\tA:" + f.format(target - 3 * sd));
+ buf.append("-" + f.format(target + 3 * sd));
+ return (buf.toString());
+ } else {
+ return ("Still sampling...");
+ }
+ }
+
+
+ /**
+ * Return a string which describes this instance.
+ */
+ public String toString()
+ {
+ DecimalFormat f = new DecimalFormat("00.00");
+
+ if (isValid()) {
+ return ("sample = " + statistics.size() +
+ "\n\tmean: " + f.format(mean) +
+ "\n\tsd: " + f.format(sd) +
+ "\n\tZones:" +
+ "\n\t\tC:" + f.format(mean - sd) +
+ "-" + f.format(mean + sd) +
+ "\n\t\tB:" + f.format(mean - 2 * sd) +
+ "-" + f.format(mean + 2 * sd) +
+ "\n\t\tA:" + f.format(mean - 3 * sd) +
+ "-" + f.format(mean + 3 * sd));
+ } else {
+ return ("Still sampling...");
+ }
+ }
+
+ /**
+ * Return true if the data is normally distributed. This
+ * method currently just returns true if the sample size is >=
+ * 5. It could be extended to use a test of normality, for
+ * instance "Pearson's Chi-Squared Test" or "Shapiro-Wilks W
+ * Test".
+ */
+ public boolean isValid()
+ {
+ if (statistics.size() >= 5)
+ return (true);
+ return (false);
+ }
+
+ /**
+ * Calculate the statistical values for the associated
+ * samples. This method should be called when the sample
+ * population changes.
+ */
+ private final void process()
+ {
+ mean = ((Double)((DoubleStatistic)total).getValue()).
+ doubleValue() / statistics.size();
+ calc_sd();
+ }
+
+ /**
+ * Return the control zone for the supplied value using the
+ * information derived from the monitored statistics and the
+ * objective expressed in the supplied objective expression.
+ *
+ * @param kve The target utilization expression.
+ * @param val The value to be evaluated.
+ */
+ public int getZone(KVOpExpression kve, double val)
+ {
+ if (!isValid())
+ return (StatisticOperations.ZONEC);
+
+ double target = kve.getValue();
+
+ if (kve.getOp() == KVOpExpression.LT) {
+ target -= 3 * sd;
+ } else if (kve.getOp() == KVOpExpression.GT) {
+ target += 3 * sd;
+ }
+
+ return (getZone(target, val));
+ }
+
+ /**
+ * Return the control zone for the supplied value using the
+ * information derived from the monitored statistics.
+ *
+ * @param val The value to be evaluated.
+ */
+ public int getZoneMean(double val)
+ {
+ if (!isValid())
+ return (StatisticOperations.ZONEC);
+
+ return (getZone(mean, val));
+ }
+
+ /**
+ * Return the control zone for the supplied value using the
+ * information derived from the supplied target.
+ *
+ * @param val The value to be evaluated.
+ */
+ private int getZone(double target, double val)
+ {
+ if (!isValid())
+ return (StatisticOperations.ZONEC);
+
+ return ((val < target - 3 * sd) ?
+ ZONEZ | ZONELT : (val > target + 3 * sd) ?
+ ZONEZ | ZONEGT : (val < target - 2 * sd) ?
+ ZONEA | ZONELT : (val > target + 2 * sd) ?
+ ZONEA | ZONEGT : (val < target - sd) ?
+ ZONEB | ZONELT : (val > target + sd) ?
+ ZONEB | ZONEGT : (val < target) ?
+ ZONEC | ZONELT : ZONEC | ZONEGT);
+ }
+
+ /**
+ * Return the difference (gap) between the target utilization
+ * expressed in the supplied objective expression and the
+ * supplied value.
+ *
+ * @param kve Objective expression used to determine target
+ * utilization details.
+ * @param val The value to be assessed.
+ */
+ public double getGap(KVOpExpression kve, double val)
+ {
+ if (!isValid())
+ return (0.0);
+
+ double target = kve.getValue();
+
+ if (kve.getOp() == KVOpExpression.LT) {
+ target -= 3 * sd;
+ } else if (kve.getOp() == KVOpExpression.GT) {
+ target += 3 * sd;
+ }
+ if (val - target < -100)
+ return (-100);
+ else if (val - target > 100)
+ return (100);
+ else
+ return (val - target);
+ }
+
+ /**
+ * Event handler for added statistics.
+ *
+ * @param e The event.
+ */
+ public void onStatisticAdd(StatisticEvent e)
+ {
+ total = total.add(e.getTarget());
+ process();
+
+ }
+
+ /**
+ * Event handler for removed statistics.
+ *
+ * @param e The event.
+ */
+ public void onStatisticRemove(StatisticEvent e)
+ {
+ total = total.subtract(e.getTarget());
+ process();
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemMonitor.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemMonitor.java
new file mode 100644
index 0000000000..b458d56e45
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemMonitor.java
@@ -0,0 +1,366 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.math.BigInteger;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.logging.*;
+
+import com.sun.solaris.service.kstat.*;
+import com.sun.solaris.service.logging.Severity;
+import com.sun.solaris.domain.pools.*;
+import com.sun.solaris.service.pools.*;
+import com.sun.solaris.service.timer.*;
+
+/**
+ * Regularly samples the objective-related utilization statistics of
+ * the resource in the pool with the given configuration.
+ */
+class SystemMonitor implements Monitor
+{
+ /**
+ * The pool configuration with resources to be monitored.
+ */
+ private Configuration conf;
+
+ /**
+ * The map of monitored resources.The map is keyed by
+ * resource, with the values being the monitorable instances.
+ */
+ private Map monitored;
+
+ /**
+ * Default sample interval (milliseconds).
+ */
+ public static final int DEF_SAMPLE_INT = 15000;
+
+ /**
+ * Sample interval (milliseconds, default 15000).
+ */
+ private int interval;
+
+ /**
+ * Sample interval property name.
+ */
+ static final String SAMPLE_INTERVAL_PROP_NAME =
+ "system.poold.monitor-interval";
+
+ /**
+ * Kstat interface for raw data
+ */
+ private KstatCtl kc;
+
+ /**
+ * Raw statistics which are sampled each interval.
+ */
+ private final String stats[] = { "idle", "kernel", "wait", "user" };
+
+ /**
+ * Timer regulating sampling frequency.
+ */
+ private RecurringEventTimer timer;
+
+ /**
+ * The number of samples taken.
+ */
+ private int sampleCount = 0;
+
+ /**
+ * Time the last sample was taken.
+ */
+ private Date lastSampleTime = null;
+
+ /**
+ * Constructs a new monitor which is not associated with a
+ * specific configuration.
+ */
+ public SystemMonitor()
+ {
+ this(null);
+ }
+
+ /**
+ * Constructs a new Monitor for monitoring the resources in the
+ * given configuration using the given statistic source.
+ *
+ * @param conf The configuration which is monitored.
+ */
+ public SystemMonitor(Configuration conf)
+ {
+ this.conf = conf;
+ monitored = new HashMap();
+ kc = new KstatCtl();
+ }
+
+ /**
+ * Initialize the monitor with the configuration which is to
+ * be monitored.
+ *
+ * @param conf The configuration which is monitored.
+ *
+ * @throws PoolsException if manipulating the configuration
+ * fails.
+ * @throws StaleMonitorException if the resource monitors
+ * cannot be set.
+ */
+ public void initialize(Configuration conf) throws PoolsException,
+ StaleMonitorException
+ {
+ Poold.CONF_LOG.log(Severity.DEBUG, "initializing");
+ this.conf = conf;
+ try {
+ kc.chainUpdate();
+ } catch (KstatChainUpdateException kcue) {
+ Poold.utility.die(Poold.CONF_LOG, kcue);
+ }
+
+ try {
+ interval = (int)conf.getLongProperty(
+ SAMPLE_INTERVAL_PROP_NAME);
+ } catch (PoolsException pe) {
+ interval = DEF_SAMPLE_INT;
+ }
+ timer = new SimpleRecurringEventTimer(interval);
+
+ setResourceMonitors("pset");
+ }
+
+ /**
+ * Add all resources of the supplied type in the monitored
+ * configuration to the set of monitored resources. Remove
+ * redundant monitors for resources which no longer exist.
+ * Don't monitor resource sets which are empty.
+ *
+ * @param type The type of the resources to be added
+ */
+ private void setResourceMonitors(String type) throws PoolsException,
+ StaleMonitorException
+ {
+ Value val = new Value("type", type);
+
+ List valueList = new LinkedList();
+ valueList.add(val);
+ Iterator resIt = conf.getResources(valueList).iterator();
+ val.close();
+ HashSet oldKeys = new HashSet(monitored.keySet());
+ while (resIt.hasNext()) {
+ Resource res = (Resource)resIt.next();
+ ResourceMonitor mon = null;
+ boolean activeComponents = false;
+
+ List compList = res.getComponents(null);
+ Iterator compIt = compList.iterator();
+ while (compIt.hasNext()) {
+ Component comp = (Component) compIt.next();
+ String status = comp.getStringProperty(
+ "cpu.status");
+ if (status.compareTo("off-line") != 0 &&
+ status.compareTo("powered-off") != 0) {
+ activeComponents = true;
+ break;
+ }
+ }
+ if (activeComponents == false)
+ continue;
+
+ if (monitored.containsKey(res)) {
+ mon = get(res);
+ for (int i = 0; i < stats.length; i++)
+ mon.resetData(stats[i]);
+ } else {
+ mon = new ResourceMonitor(res, 50);
+ for (int i = 0; i < stats.length; i++) {
+ StatisticList sl = new StatisticList(
+ stats[i], 2);
+ mon.put(stats[i], sl);
+ }
+ mon.put("utilization", new StatisticList(
+ "utilization", mon.getMaxSampleSize(),
+ true));
+ monitored.put(res, mon);
+ }
+ mon.initialize();
+ oldKeys.remove(res);
+ }
+ monitored.keySet().removeAll(oldKeys);
+ }
+
+ /**
+ * Get the next sample. Before obtaining the sample, the call
+ * will block for the interval which was specified when this
+ * monitor was initialized.
+ *
+ * @throws StaleMonitorException if a statistic cannot be obtained.
+ * @throws PoolsException if there is an error manipulating the
+ * pools configuration.
+ * @throws InterruptedException if the thread is interrupted
+ * while waiting for the sampling time to arrive. The caller
+ * may wish to check other conditions before possibly
+ * reinitiating the sample.
+ */
+ public void getNext() throws StaleMonitorException, PoolsException,
+ InterruptedException
+ {
+ Poold.MON_LOG.log(Severity.DEBUG, "waiting sampling interval");
+
+ Date start = lastSampleTime;
+ if (start == null)
+ start = new Date();
+
+ timer.waitUntilNextFiring();
+ Date end = new Date();
+
+ Poold.MON_LOG.log(Severity.DEBUG, "sampling");
+ Iterator itMon = monitored.values().iterator();
+ while (itMon.hasNext()) {
+ ResourceMonitor mon = (ResourceMonitor) itMon.next();
+ List compList = mon.getComponents();
+ Iterator itComp = compList.iterator();
+ BigInteger statsv[] = new BigInteger[4];
+ while (itComp.hasNext()) {
+ Component cpu = (Component) itComp.next();
+ Kstat kstat = kc.lookup("cpu",
+ (int) cpu.getLongProperty("cpu.sys_id"),
+ "sys");
+ if (kstat == null)
+ throw new StaleMonitorException();
+ UnsignedInt64 value;
+ try {
+ kstat.read();
+ for (int i = 0; i < stats.length; i++) {
+ value = (UnsignedInt64) kstat.
+ getValue("cpu_ticks_" +
+ stats[i]);
+ if (value == null)
+ throw new
+ StaleMonitorException();
+ if (statsv[i] == null)
+ statsv[i] = value;
+ else
+ statsv[i] = statsv[i].
+ add(value);
+ }
+ } catch (KstatException ke) {
+ StaleMonitorException sme =
+ new StaleMonitorException();
+ sme.initCause(ke);
+ Poold.MON_LOG.log(Severity.DEBUG,
+ "configuration necessary due to "
+ + ke);
+ throw(sme);
+ }
+ }
+ if (compList.isEmpty() == false) {
+ for (int i = 0; i < stats.length; i++) {
+ StatisticList sl;
+ sl = (StatisticList) mon.get(stats[i]);
+ sl.add(new UnsignedInt64Statistic(
+ new UnsignedInt64(statsv[i].
+ divide(new BigInteger(
+ Integer.toString(
+ compList.size())))),
+ start, end));
+ }
+ }
+ mon.updateDerived();
+ }
+
+ sampleCount++;
+ lastSampleTime = end;
+ }
+
+ /**
+ * Return the number of samples taken. This is the number of
+ * successful calls to <code>getNext()</code>.
+ */
+ public int getSampleCount()
+ {
+ return (sampleCount);
+ }
+
+ /**
+ * Return the utilization of the supplied resource. The
+ * utilization is represented as a percentage between 0
+ * and 100.
+ *
+ * @param res A reference to a configuration resource.
+ */
+ public double getUtilization(Resource res) throws StaleMonitorException
+ {
+ ResourceMonitor mon = get(res);
+ DoubleStatistic util = null;
+ try {
+ util = (DoubleStatistic)mon.getDerivedStatistic(
+ "utilization");
+ } catch (NoSuchElementException nsee) {
+ util = new DoubleStatistic(new Double(0));
+ }
+ Poold.MON_LOG.log(Severity.DEBUG,
+ res + " utilization " + util.toString());
+ return (((Double)util.getValue()).doubleValue());
+ }
+
+ /**
+ * Return true if the system contains enough sampled data for
+ * monitoring to be worthwhile.
+ */
+ public boolean isValid()
+ {
+ Iterator itMon = monitored.values().iterator();
+ while (itMon.hasNext()) {
+ ResourceMonitor mon = (ResourceMonitor) itMon.next();
+
+ Iterator itSL = mon.values().iterator();
+ while (itSL.hasNext()) {
+ StatisticList sl = (StatisticList) itSL.next();
+ if (sl.getName().compareTo("utilization") ==
+ 0) {
+ if (sl.isValid() == false)
+ return (false);
+ }
+ }
+ }
+ return (true);
+ }
+
+ /**
+ * Return the ResourceMonitor for the supplied Resource
+ *
+ * @throws StaleMonitorException if the ResourceMonitor cannot be found.
+ */
+ public ResourceMonitor get(Resource res) throws StaleMonitorException
+ {
+ ResourceMonitor rm = (ResourceMonitor)monitored.get(res);
+
+ if (rm == null)
+ throw new StaleMonitorException();
+ return (rm);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemSolver.java b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemSolver.java
new file mode 100644
index 0000000000..51b37aa5a6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/SystemSolver.java
@@ -0,0 +1,986 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.domain.pools;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.util.regex.*;
+import java.text.DecimalFormat;
+
+import com.sun.solaris.service.locality.*;
+import com.sun.solaris.service.logging.*;
+import com.sun.solaris.service.pools.*;
+import com.sun.solaris.service.exception.*;
+
+/**
+ * The <code>SystemSolver</code> class implements a dynamic resource
+ * allocation solver. The Solver takes a configuration and "solves"
+ * the resource allocation problem.
+ *
+ * This class operates upon a configuration which is suppplied during
+ * initialization. Its responsibilities include:
+ * <ul>
+ * <li><p>
+ * Maintaining decision history
+ * <li><p>
+ * Maintaining information about the locality domain
+ * <li><p>
+ * Maintaining a map of all elements and their associated set of objectives
+ * <li><p>
+ * Identifying objective expressions with a configuration
+ * </ul>
+ */
+class SystemSolver implements Solver {
+ /**
+ * The default location of this history file.
+ */
+ public static final String DH_FILE_DEF_PATH =
+ "/var/adm/pool/history";
+
+ /**
+ * The property overriding the default decision history path.
+ */
+ public static final String DH_FILE_PROP_NAME =
+ "system.poold.history-file";
+
+ /**
+ * The LocalityDomain extracted from the configuration.
+ */
+ private LocalityDomain ldom;
+
+ /**
+ * The objective map used to link all elements with their set
+ * of objectives.
+ */
+ private Map objMap;
+
+ /**
+ * The pattern used to identify objective expressions.
+ */
+ private static final Pattern p0 = Pattern.compile(";");
+
+ /**
+ * The configuration for which this solver is "solving".
+ */
+ private Configuration conf;
+
+ /**
+ * Monitor providing statistics for this solver.
+ */
+ private final Monitor monitor;
+
+ /**
+ * The decision history maintainer.
+ */
+ private DecisionHistory dh;
+
+ /**
+ * The path to the decision history file.
+ */
+ private String dhPath;
+
+ /**
+ * The number of CPUs on the system.
+ */
+ private int cpuCount;
+
+ /**
+ * The number of locality triggered examinations made.
+ */
+ private int examineCount;
+
+ /**
+ * Constructs a solver which initialises a decision history
+ * maintainer. The decision history is be used during operation
+ * to veto historically-poor decisions output from the objective
+ * function.
+ */
+ SystemSolver(Monitor monitor)
+ {
+ /*
+ * Create a HashMap to store all objectives.
+ */
+ objMap = new HashMap();
+ this.monitor = monitor;
+ }
+
+ /**
+ * Initialize the solver for operation upon the supplied
+ * configuration. Possible objective expressions set upon
+ * target elements are identified and stored in an objective
+ * map which associates elements with the set of their
+ * objectives.
+ *
+ * @param conf The configuration to be manipulated.
+ * @throws PoolsException If the initialization fails.
+ */
+ public void initialize(Configuration conf) throws PoolsException
+ {
+ String oString = null;
+ String exps[];
+
+ this.conf = conf;
+ /*
+ * Count the CPUs in the system, this is used to
+ * control locality objective processing in the
+ * examine() method.
+ */
+ cpuCount = conf.getComponents(null).size();
+ examineCount = 0;
+ /*
+ * Remove any old objectives
+ */
+ objMap.clear();
+
+ /*
+ * Extract any configuration objectives
+ */
+ try {
+ oString = conf.getStringProperty(
+ "system.poold.objectives");
+ if (oString.length() > 0) {
+ Set oSet = new HashSet();
+ objMap.put(conf, oSet);
+ Poold.CONF_LOG.log(Severity.DEBUG,
+ "adding configuration objective " +
+ oString);
+ exps = p0.split(oString);
+ for (int i = 0; i < exps.length; i++) {
+ try {
+ Expression exp =
+ Expression.valueOf(
+ exps[i]);
+ addObjective(oSet, "system",
+ exp);
+ } catch (IllegalArgumentException iae) {
+ Poold.utility.warn(
+ Poold.CONF_LOG, iae, false);
+ }
+ }
+ }
+ } catch (PoolsException pe) {
+ /*
+ * Ignore as this means there is no objective
+ * property
+ */
+ }
+ /*
+ * Now extract all pset objectives
+ */
+ Value typeProp = new Value("type", "pset");
+ List valueList = new LinkedList();
+ valueList.add(typeProp);
+ Iterator resIt = conf.getResources(valueList).iterator();
+ typeProp.close();
+ while (resIt.hasNext()) {
+ Resource resource = (Resource)resIt.next();
+
+ try {
+ oString = resource.getStringProperty(
+ "pset.poold.objectives");
+ if (oString.length() > 0) {
+ Set oSet = new HashSet();
+ objMap.put(resource, oSet);
+ Poold.CONF_LOG.log(Severity.DEBUG,
+ "adding " +
+ resource.getStringProperty(
+ "pset.name") +
+ " objective \"" + oString + "\"");
+ exps = p0.split(oString);
+ for (int i = 0; i < exps.length; i++) {
+ Expression exp = null;
+ try {
+ exp = Expression.
+ valueOf(exps[i]);
+ addObjective(oSet,
+ "pset", exp);
+ } catch
+ (IllegalArgumentException e)
+ {
+ Poold.utility.warn(
+ Poold.CONF_LOG, e,
+ false);
+ }
+ }
+ }
+ } catch (PoolsException pe) {
+ continue;
+ }
+ }
+ Poold.CONF_LOG.log(Severity.DEBUG, "objective map: " +
+ objMap.toString());
+
+ /*
+ * Capture the LocalityDomain details.
+ */
+ if (ldom != null) {
+ ldom.close();
+ }
+ try {
+ ldom = new LocalityDomain(LocalityDomain.LGRP_VIEW_OS);
+ } catch (Exception e) {
+ Poold.utility.die(Poold.OPT_LOG, e);
+ }
+
+ /*
+ * Load or create the decision history.
+ */
+ String newDhPath;
+ try {
+ newDhPath = conf.getStringProperty(
+ DH_FILE_PROP_NAME);
+ } catch (PoolsException pe) {
+ newDhPath = DH_FILE_DEF_PATH;
+ }
+
+ if (!newDhPath.equals(dhPath)) {
+ try {
+ dh = DecisionHistory.loadFromFile(newDhPath);
+ Poold.CONF_LOG.log(Severity.DEBUG,
+ "loaded history file " + newDhPath);
+ } catch (Exception e) {
+ if (!(e instanceof FileNotFoundException)) {
+ Poold.CONF_LOG.log(Severity.WARNING,
+ newDhPath +
+ ": contents unusable; ignoring");
+ Poold.CONF_LOG.log(Severity.DEBUG,
+ newDhPath + ": contents unusable",
+ e);
+ }
+ /*
+ * Use current DecisionHistory instead,
+ * if any.
+ */
+ if (dh == null)
+ dh = new DecisionHistory();
+ }
+
+ /*
+ * Try using the new path.
+ */
+ try {
+ dh.syncToFile(newDhPath);
+ } catch (Exception e) {
+ Poold.utility.die(Poold.CONF_LOG,
+ new PooldException(newDhPath +
+ ": couldn't synchronize history file")
+ .initCause(e), false);
+ }
+ dhPath = newDhPath;
+ }
+ }
+
+ /**
+ * Determine if the given resource has non-workload-dependent
+ * objectives.
+ * @param elem The element to examine.
+ */
+ private boolean hasNonWorkloadDependentObjectives(Element elem)
+ {
+ Set elemObj = (Set)objMap.get(elem);
+
+ /*
+ * This code relies upon the fact that an element with
+ * no objectives will not have an empty set, but rather
+ * no value in the objMap.
+ */
+
+ if (elemObj == null)
+ return (false);
+
+ Iterator elemObjIt = elemObj.iterator();
+ while (elemObjIt.hasNext())
+ if (elemObjIt.next() instanceof
+ WorkloadDependentObjective)
+ return (false);
+
+ return (true);
+ }
+
+ /**
+ * Determine if the given resource has workload-dependent
+ * objectives.
+ * @param elem The element to examine.
+ */
+ private boolean hasWorkloadDependentObjectives(Element elem)
+ {
+ Set elemObj = (Set)objMap.get(elem);
+
+ /*
+ * This code relies upon the fact that an element with
+ * no objectives will not have an empty set, but rather
+ * no value in the objMap.
+ */
+
+ if (elemObj == null)
+ return (false);
+
+ Iterator elemObjIt = elemObj.iterator();
+ while (elemObjIt.hasNext())
+ if (elemObjIt.next() instanceof
+ WorkloadDependentObjective)
+ return (true);
+
+ return (false);
+ }
+
+ /**
+ * Return true if the monitored configuration should be
+ * reconfigured. All workload-dependent objectives are
+ * examined to determine if the configuration is still
+ * satisfying all specified objectives on all elements. If any
+ * objectives are failing, then this method will return true.
+ *
+ * @param mon The monitoring object used to assess objective
+ * compliance.
+ */
+ public boolean examine(Monitor mon) throws PoolsException,
+ StaleMonitorException
+ {
+ /*
+ * Take advantage of the guaranteed-valid monitor data
+ * for measuring the improvement of any past decisions.
+ */
+ dh.expireAndMeasureImprovements(mon);
+
+ Iterator objIt = objMap.keySet().iterator();
+ boolean ret = false;
+ boolean hasLocalityObjectives = false;
+ boolean isMonitorValid = true;
+
+ /*
+ * All objectives are examined, even though failure
+ * could be detected earlier. This is because logging
+ * of all objectives is required and the information
+ * about failure can be stored and used during
+ * solving.
+ */
+ while (objIt.hasNext()) {
+ Element elem = (Element) objIt.next();
+ Set elemObj = (Set) objMap.get(elem);
+ Iterator elemObjIt = elemObj.iterator();
+ while (elemObjIt.hasNext()) {
+ Objective obj = (Objective) elemObjIt.next();
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "checking objective " + obj);
+ if (obj instanceof WorkloadDependentObjective) {
+ if (isValid()) {
+ /*
+ * If any objectives
+ * are violated, then
+ * we must
+ * reconfigure, so
+ * check them all in
+ * turn.
+ */
+ ret = ((WorkloadDependentObjective)
+ obj).examine(conf, this, elem) ||
+ ret;
+ } else
+ isMonitorValid = false;
+ }
+ }
+
+ /*
+ * Check if this is the first element, seen in
+ * this pass, that has locality objectives.
+ */
+ if (!hasLocalityObjectives &&
+ hasNonWorkloadDependentObjectives(elem))
+ hasLocalityObjectives = true;
+ }
+ if (isMonitorValid == false) {
+ Poold.MON_LOG.log(Severity.INFO,
+ "not evaluating workload-dependent objectives " +
+ "until sufficient statistics are collected");
+ }
+ /*
+ * If we don't have locality objectives, we don't force
+ * the reexamination. This is controlled by
+ * hasLocalityObjectives.
+ *
+ * So that we don't continually trigger
+ * reconfiguration examinations for locality
+ * objectives we stop forcing recalculations when we
+ * reach cpuCount / 2. This should be enough moves to
+ * get good locality for those configurations which
+ * have no WorkloadDependentObjectives.
+ */
+ return (ret || (hasLocalityObjectives && (examineCount++ <
+ cpuCount / 2)));
+ }
+
+ /**
+ * Reallocate resources in a configuration to achieve user
+ * specified objectives. Return true if the configuration has
+ * been updated, false otherwise.
+ *
+ * This method should only be invoked if a previous
+ * examination of the configuration which is monitored
+ * indicates that objectives are failing. The monitored
+ * configuration is re-opened for editing, locking that
+ * configuration for the duration of this operation.
+ *
+ * @throws Exception If the solve fails.
+ */
+ public boolean solve() throws Exception
+ {
+ boolean madeMove = false;
+ /*
+ * All solving operations must be done in an
+ * "editable" context, so create a new modifiable
+ * configuration which is at the same location as the
+ * monitored configuration
+ */
+ Configuration rwConf = new Configuration(conf.getLocation(),
+ PoolInternal.PO_RDWR);
+
+ try {
+ /*
+ * Build a resource set importance map for use
+ * when propagating pool importance to each
+ * possible solution. Use the same logic as
+ * libpool and let a resource take the highest
+ * importance value from all pools associated
+ * with the set.
+ */
+ Map resImp = new HashMap();
+ List poolList = rwConf.getPools(null);
+ Iterator itPool = poolList.iterator();
+ while (itPool.hasNext()) {
+ Pool pool = (Pool) itPool.next();
+ long newImp = pool.
+ getLongProperty("pool.importance");
+ List resList = pool.getResources(null);
+ Iterator itRes = resList.iterator();
+ while (itRes.hasNext()) {
+ Resource res = (Resource) itRes.next();
+ if (resImp.containsKey(res)) {
+ Long imp = (Long) resImp.
+ get(res);
+ if (newImp > imp.longValue())
+ resImp.put(res,
+ new Long(newImp));
+ } else
+ resImp.put(res,
+ new Long(newImp));
+ }
+ }
+ /*
+ * Consider all possible alternative
+ * configurations. This list is generated as a
+ * series of moves. Administrative constraints
+ * are applied to the moves to prune the list of
+ * possible configurations.
+ */
+ Value val = new Value("type", "pset");
+ List valueList = new LinkedList();
+ valueList.add(val);
+
+
+ List resList = rwConf.getResources(valueList);
+ val.close();
+ List donors = getDonors(resList);
+ List receivers = getRecipients(resList);
+ Poold.OPT_LOG.log(Severity.DEBUG, "donors: " +
+ donors);
+ Poold.OPT_LOG.log(Severity.DEBUG, "receivers: " +
+ receivers);
+ Iterator itDonor = donors.iterator();
+ List moves = new ArrayList();
+ while (itDonor.hasNext()) {
+ Resource donor = (Resource) itDonor.next();
+ List processors = getProcessors(donor);
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "donor processors: " + processors);
+ Iterator itProcessor = processors.iterator();
+ while (itProcessor.hasNext()) {
+ Component cpu = (Component) itProcessor.
+ next();
+ Iterator itReceiver = receivers.
+ iterator();
+ while (itReceiver.hasNext()) {
+ Resource receiver =
+ (Resource) itReceiver.
+ next();
+ /*
+ * Can't move to yourself
+ */
+ if (receiver == donor)
+ continue;
+ moves.add(new ComponentMove(
+ donor, receiver, cpu));
+ }
+ }
+ }
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "potential moves: " + moves);
+ /*
+ * Now that we have our alternative configurations,
+ * score each configuration by applying all objectives
+ * to each configuration. Hold the scores in the
+ * score set.
+ */
+ HashSet scores = new HashSet();
+ Iterator itMoves = moves.iterator();
+ while (itMoves.hasNext()) {
+ double totalContrib = 0;
+ Move move = (Move) itMoves.next();
+ Iterator objIt = objMap.keySet().iterator();
+ while (objIt.hasNext()) {
+ Element elem = (Element) objIt.next();
+ Set elemObj = (Set) objMap.get(elem);
+ Iterator elemObjIt = elemObj.iterator();
+ while (elemObjIt.hasNext()) {
+ Objective obj =
+ (Objective)elemObjIt.next();
+ if (obj instanceof
+ LocalityObjective)
+ ((LocalityObjective)obj)
+ .prepare(ldom,
+ (Resource)elem);
+ /*
+ * If the monitor is
+ * invalid, do not
+ * process
+ * WorkloadDependentObjectives
+ * since they have an
+ * implicit dependency
+ * on the monitor
+ * data.
+ */
+ if (obj instanceof
+ WorkloadDependentObjective)
+ if (!isValid())
+ continue;
+ double contrib = obj.calculate(
+ rwConf, move, elem);
+ if (contrib < -1 || contrib > 1)
+ throw new
+ IllegalOFValueException(
+ "x: " + contrib +
+ " is invalid, legal " +
+ "range is -1 <= x <= " +
+ "1");
+ /*
+ * Modify the basic
+ * score by the
+ * importance of the
+ * objective and (if
+ * appropriate) the
+ * importance of an
+ * associated pool.
+ */
+ if (resImp.containsKey(elem)) {
+ contrib *= ((Long)
+ resImp.get(elem)).
+ longValue();
+ }
+
+ totalContrib += contrib *
+ obj.getExpression().
+ getImportance();
+ }
+ }
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "scored move (" + move + ") " +
+ totalContrib);
+ scores.add(new ScoreMove(move, totalContrib));
+ }
+ if (scores.size() != 0) {
+ /*
+ * Try to find a move to apply which
+ * yields a positive contribution.
+ */
+ Object scoresArray[] = scores.toArray();
+ Arrays.sort(scoresArray,
+ Collections.reverseOrder());
+ if ((madeMove = processMoves(rwConf,
+ scoresArray, false)) == false)
+ madeMove = processMoves(rwConf,
+ scoresArray, true);
+ } else
+ Poold.OPT_LOG.log(Severity.INFO,
+ "no moves found");
+ rwConf.close();
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "synchronizing decision history");
+ dh.syncToFile(dhPath);
+ } catch (Exception ex) {
+ rwConf.close();
+ throw ex;
+ }
+ return (madeMove);
+ }
+
+ /*
+ * Process the supplied array of scored moves, trying to find
+ * a move to apply. Return true if a move could be applied,
+ * false otherwise.
+ *
+ * @param conf The configuration to be modified.
+ * @param scores The areay of scored moves to be tried.
+ * @param ignoreDH Ignore Decision History details.
+ */
+ private boolean processMoves(Configuration rwConf, Object scores[],
+ boolean ignoreDH) throws PoolsException, StaleMonitorException
+ {
+ boolean madeMove = false;
+
+ for (int i = 0; i < scores.length; i++) {
+ ScoreMove move = (ScoreMove) scores[i];
+ if (move.getScore() <= 0) {
+ if (ignoreDH)
+ Poold.OPT_LOG.log(Severity.INFO,
+ move + " not applied as " +
+ "benefit not significant");
+ break;
+ }
+ if ((madeMove = applyMove(rwConf, move, ignoreDH)) ==
+ true)
+ break;
+ }
+ return (madeMove);
+ }
+
+ /*
+ * Attempt to apply the supplied move to the
+ * configuration. Return true if the move could be applied,
+ * false otherwise.
+ *
+ * @param conf The configuration to be modified.
+ * @param move The move to be applied.
+ * @param ignoreDH Ignore Decision History details.
+ */
+ private boolean applyMove(Configuration conf, ScoreMove move,
+ boolean ignoreDH)
+ throws PoolsException, StaleMonitorException
+ {
+ boolean madeMove = false;
+ boolean wdpInvolved = false;
+ double utilization = 0.0;
+
+ Poold.OPT_LOG.log(Severity.DEBUG, "selected " + move);
+ if (hasWorkloadDependentObjectives(move.getMove().getTo()) ||
+ hasWorkloadDependentObjectives(conf)) {
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "Attempting to retrieve utilization for:" + move
+ .getMove().getTo());
+ utilization = monitor.getUtilization(move
+ .getMove().getTo());
+ wdpInvolved = true;
+ }
+
+ /*
+ * Unless a move can be vetoed (i.e. decision history
+ * is effective and there are is a workload-dependent
+ * involved), the move should alwways be applied.
+ */
+ if (ignoreDH || !wdpInvolved || !dh.veto(move.getMove(),
+ utilization)) {
+ Poold.OPT_LOG.log(Severity.INFO,
+ "applying move " + move.getMove());
+ move.getMove().apply();
+ ResourceMonitor mon = getMonitor().get(move.getMove().
+ getFrom());
+ mon.resetData("utilization");
+ mon = getMonitor().get(move.getMove().getTo());
+ mon.resetData("utilization");
+ try {
+ Poold.OPT_LOG.log(Severity.DEBUG,
+ "committing configuration");
+ conf.commit(0);
+ try {
+ if (move.getMove() instanceof
+ ComponentMove)
+ if (wdpInvolved)
+ dh.recordProcessorMove(
+ (ComponentMove)move
+ .getMove(),
+ utilization,
+ monitor
+ .getSampleCount());
+ else
+ Poold.OPT_LOG.log(
+ Severity.DEBUG,
+ "decision not " +
+ "recorded due to " +
+ "lack of workload-"
+ + "dependent " +
+ "objectives");
+ } catch (Exception e) {
+ Poold.OPT_LOG.log(Severity.INFO,
+ "couldn't update " +
+ "decision history (" +
+ e.toString() + ")");
+ }
+ madeMove = true;
+ } catch (PoolsException pe) {
+ conf.rollback();
+ Poold.OPT_LOG.log(Severity.INFO,
+ "move failed, possibly due to a " +
+ "bound process in a 1-processor " +
+ "set");
+ }
+ } else {
+ /*
+ * Move was vetoed.
+ */
+ if (!ignoreDH && wdpInvolved)
+ Poold.OPT_LOG.log(Severity.INFO,
+ move.getMove() + " not applied due to " +
+ "poor past results");
+ }
+ return (madeMove);
+ }
+
+ /**
+ * Add an objective based on the supplied expression to the
+ * supplied set of objectives.
+ *
+ * @param oSet Set of objectives to be extended
+ * @param type Type of element to which the expression is applied
+ * @param exp Expression to be used in the objective
+ * @throws IllegalArgumentException If a duplicate objective
+ * is identified or an invalid expression is supplied for this
+ * type of element
+ */
+ private void addObjective(Set oSet, String type, Expression exp)
+ throws IllegalArgumentException
+ {
+ Objective o = AbstractObjective.getInstance(type, exp);
+ Poold.CONF_LOG.log(Severity.DEBUG, "parsed objective " + o);
+ /*
+ * Check the set of objectives and find contradictions.
+ */
+ Iterator itObjs = oSet.iterator();
+ while (itObjs.hasNext()) {
+ Objective other = (Objective) itObjs.next();
+ if (o.getExpression().contradicts(
+ other.getExpression()))
+ throw new IllegalArgumentException(
+ "contradictory objectives:" + other +
+ ", " + o);
+ }
+
+ if (oSet.add(o) != true)
+ throw new IllegalArgumentException(
+ "duplicate objective:" + o);
+ }
+
+ /**
+ * Return a list of resource sets prepared to receive
+ * resources
+ *
+ * The list consists of all resource setss (of the supplied
+ * type) whose size is < their max constraint.
+ *
+ * @param resList The list of all resource sets from which
+ * recipients will be chosen
+ * @throws PoolsException if there is an error manipulation
+ * the pool resources
+ */
+ private List getRecipients(List resList) throws PoolsException
+ {
+ List recipientList = new ArrayList();
+ long size, max;
+ for (int i = 0; i < resList.size(); i++) {
+ Resource res;
+ res = (Resource)resList.get(i);
+ String type = res.getStringProperty("type");
+ size = res.getLongProperty(type+".size");
+ max = res.getLongProperty(type+".max");
+ if (size < max)
+ recipientList.add(res);
+ }
+ return (recipientList);
+ }
+
+ /**
+ * Return a list of resource sets prepared to donate resources
+ *
+ * The list consists of all resource sets (of the supplied
+ * type) whose size (minus the number of pinned resources
+ * where applicable) is > their min constraint.
+ *
+ * @param resList The list of all resource sets from which
+ * recipients will be chosen
+ * @throws PoolsException if there is an error manipulation
+ * the pool resources
+ */
+ private List getDonors(List resList) throws PoolsException
+ {
+ List donorList = new ArrayList();
+ long size, min;
+ for (int i = 0; i < resList.size(); i++) {
+ Value bValue;
+ Resource res;
+ List pinned;
+ ArrayList valueList = new ArrayList();
+
+ res = (Resource)resList.get(i);
+ String type = res.getStringProperty("type");
+ size = res.getLongProperty(type+".size");
+ bValue = new Value("cpu.pinned", true);
+ valueList.add(bValue);
+ pinned = res.getComponents(valueList);
+ bValue.close();
+ min = res.getLongProperty(type+".min");
+ if (pinned.size() > min)
+ size -= pinned.size() - min;
+ if (size > min)
+ donorList.add(res);
+ }
+ return (donorList);
+ }
+
+ /**
+ * Return a list of Processors for the supplied resource.
+ *
+ * The list consists of all Processors (excluding the pinned
+ * Processors) in the set.
+ *
+ * @param set The resource for which Processors should be found
+ * @throws PoolsException if there is an error manipulation
+ * the pool resources
+ */
+ private List getProcessors(Resource set) throws PoolsException
+ {
+ Iterator it = set.getComponents(null).iterator();
+ List ret = new ArrayList();
+
+ while (it.hasNext()) {
+ Component cpu = (Component) it.next();
+ try
+ {
+ if (cpu.getBoolProperty("cpu.pinned") == false)
+ ret.add(cpu);
+ } catch (PoolsException pe)
+ {
+ ret.add(cpu);
+ }
+ }
+ return (ret);
+ }
+
+ /**
+ * Return true if the solver is capable of working with
+ * statistically valid data.
+ */
+ public boolean isValid()
+ {
+ return (monitor.isValid());
+ }
+
+ /**
+ * Return the monitor used by this solver.
+ */
+ public Monitor getMonitor()
+ {
+ return (monitor);
+ }
+
+ /**
+ * Return the set of objectives associated with the supplied
+ * element.
+ *
+ * @param elem Retrieve objectives for this element.
+ */
+ public Set getObjectives(Element elem)
+ {
+ return ((Set)objMap.get(elem));
+ }
+
+ /**
+ * Holds details about the score of a proposed configuration
+ * move. Each move must be scored so that they can ranked in
+ * terms of increasing desirability
+ */
+ static class ScoreMove implements Comparable {
+ /**
+ * The move which is being scored.
+ */
+ private final Move m;
+
+ /**
+ * The score of the move.
+ */
+ private final double score;
+
+ /**
+ * Score formatter.
+ */
+ private static final DecimalFormat scoreFormat =
+ new DecimalFormat("0.00");
+
+ /**
+ * Constructor.
+ *
+ * @param m The move under consideration.
+ * @param score The score of the move.
+ */
+ public ScoreMove(Move m, double score)
+ {
+ this.m = m;
+ this.score = score;
+ }
+
+ public int compareTo(Object o)
+ {
+ ScoreMove other = (ScoreMove) o;
+
+ return ((score < other.getScore()) ? -1 :
+ (score > other.getScore()) ? 1 : 0);
+ }
+
+ public String toString()
+ {
+ return ("move (" + m + ") score "
+ + scoreFormat.format(score));
+ }
+
+ /**
+ * Return the score.
+ */
+ double getScore()
+ {
+ return (score);
+ }
+
+ /**
+ * Return the move.
+ */
+ Move getMove()
+ {
+ return (m);
+ }
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/package.html
new file mode 100644
index 0000000000..6b34156ec0
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for automated resource management in Solaris.
+
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2002/287/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/dynamic-resource-pools/">Dynamic Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/Makefile
new file mode 100644
index 0000000000..b20cd0bac2
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/Makefile
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/exception/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = SuccinctStackTraceFormatter.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/SuccinctStackTraceFormatter.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/SuccinctStackTraceFormatter.java
new file mode 100644
index 0000000000..d02e0f6a25
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/SuccinctStackTraceFormatter.java
@@ -0,0 +1,142 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* ident "%Z%%M% %I% %E% SMI" */
+
+package com.sun.solaris.service.exception;
+
+import java.io.*;
+
+/**
+ * Formats a stack trace in a single line. The format is meant to
+ * convey the stack trace as a sequence of class names and line numbers,
+ * with the topmost frame first, suitable for logging. Beware, the
+ * format may evolve.
+ */
+public class SuccinctStackTraceFormatter {
+ /**
+ * Formats a Throwable and adds an optional description string.
+ * The string should be suitable to precede the top stack
+ * element, and include any punctuation that should
+ * differentiate it from the element.
+ */
+ public static String formatWithDescription(Throwable t,
+ String description)
+ {
+ StringBuffer s = new StringBuffer();
+
+ s.append("(");
+
+ if (description != null)
+ s.append(description);
+
+ s.append(t.getClass().getName());
+ s.append(", ");
+ StackTraceElement[] trace = t.getStackTrace();
+ for (int i = 0; i < trace.length; i++) {
+ appendStackTraceElement(i > 0 ? trace[i - 1] : null,
+ trace[i], s);
+ if (i != trace.length - 1)
+ s.append(", ");
+ }
+ s.append(")");
+
+ if (t.getCause() != null) {
+ s.append(" caused by ");
+ s.append(format(t.getCause()));
+ }
+
+ return (s.toString());
+ }
+
+ /**
+ * Formats a Throwable's stack trace. The format is meant to be
+ * a single line of output, conveying the stack trace as a
+ * sequence of class names and line numbers, with the topmost
+ * frame first, suitable for logging. If two adjacent stack
+ * trace elements share some portion of a class name, the
+ * bottommost element may have the common part replaced with an
+ * ampersand.
+ */
+ public static String format(Throwable t)
+ {
+ return (formatWithDescription(t, null));
+ }
+
+ /**
+ * Formats a stack trace element as per <code>format()</code>.
+ */
+ private static void appendStackTraceElement(StackTraceElement last,
+ StackTraceElement e, StringBuffer s)
+ {
+ /*
+ * This could grab more of a common class name. (See
+ * SuccinctStackTraceFormatter.format())
+ */
+ if (last == null || !last.getClassName().equals(
+ e.getClassName())) {
+ s.append(e.getClassName());
+ s.append(".");
+ } else
+ s.append("&.");
+
+ s.append(e.getMethodName());
+ if (e.getLineNumber() > 0) {
+ s.append(":");
+ s.append(e.getLineNumber());
+ }
+ if (e.isNativeMethod()) {
+ s.append(":");
+ s.append("native");
+ }
+ }
+
+ public static void printStackTrace(Throwable t)
+ {
+ printStackTrace(t, System.err);
+ }
+
+ public static void printStackTrace(Throwable t, PrintStream out)
+ {
+ out.print(t);
+ out.print(" at ");
+ out.print(format(t));
+ }
+
+ public static final void main(String args[])
+ {
+ SuccinctStackTraceFormatter.printStackTrace(big());
+ }
+
+ public static final Throwable big() {
+ return new Throwable().initCause(little());
+ }
+
+ public static final Throwable little() {
+ return new Throwable();
+ }
+
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/package.html
new file mode 100644
index 0000000000..38ff408766
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/exception/package.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Provides service-related exceptions and classes for generating or
+interpreting them.
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2002/287/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation,
+please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/dynamic-resource-pools/">Dynamic Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Kstat.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Kstat.java
new file mode 100644
index 0000000000..54b1f91be2
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Kstat.java
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+import com.sun.solaris.service.pools.*;
+
+/**
+ * Wraps <code>libkstat(3lib)</code>. See
+ * <code>/usr/include/sys/kstat.h</code> for details.
+ */
+public final class Kstat {
+ /**
+ * Pointer to native <code>kstat_ctl_t</code>.
+ */
+ private long kctl;
+
+ /**
+ * Pointer to native <code>kstat_t</code>.
+ */
+ private long ksp;
+
+ Kstat(long kctl, long ksp)
+ {
+ this.kctl = kctl;
+ this.ksp = ksp;
+ }
+
+ /**
+ * Returns the kstat's <code>ks_snaptime</code> field.
+ */
+ public native HRTime getSnapTime();
+
+ /**
+ * Returns the kstat's <code>ks_crtime</code> field.
+ */
+ public native HRTime getCreationTime();
+
+ /**
+ * Returns the named value -- the value of the named kstat, or
+ * field in a raw kstat, as applicable, and available. Returns
+ * <i>null</i> if no such named kstat or field is available.
+ *
+ * @throws KstatTypeNotSupportedException if the raw kstat is not
+ * understood. (Presenstly, none are.)
+ */
+ public native Object getValue(String name)
+ throws KstatTypeNotSupportedException;
+
+ /**
+ * Invokes <code>kstat_read(3kstat)</code> for tho underlying kstat.
+ * Throws KstatException if the native function returns an error.
+ */
+ public native void read() throws KstatReadException;
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatChainUpdateException.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatChainUpdateException.java
new file mode 100644
index 0000000000..82a9612dfc
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatChainUpdateException.java
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+/**
+ * Indicates a that <code>kstat_chain_update(3KSTAT)</code> failed for the
+ * given KstatCtl.
+ */
+public class KstatChainUpdateException extends KstatException {
+ /**
+ * The offending KstatCtl.
+ */
+ private KstatCtl kstatCtl;
+
+ public KstatChainUpdateException(KstatCtl kctl)
+ {
+ this.kstatCtl = kstatCtl;
+ }
+
+ /**
+ * Returns the offending KstatCtl.
+ */
+ public KstatCtl getKstatCtl()
+ {
+ return (kstatCtl);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatCtl.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatCtl.java
new file mode 100644
index 0000000000..a18727db55
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatCtl.java
@@ -0,0 +1,94 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+/**
+ * <code>kstat</code> controlling object. Allows kstats to be looked up
+ * so they can later be sampled.
+ */
+public final class KstatCtl
+{
+ static {
+ System.loadLibrary("jkstat");
+ KstatCtl.init();
+ }
+
+ /**
+ * Pointer to a <code>kstat_ctl_t</code>.
+ */
+ private long kctl;
+
+ /**
+ * Invokes <code>kstat_open(3KSTAT)</code>. The returned object
+ * should be explicitly finalized when it's no longer needed.
+ */
+ public KstatCtl()
+ {
+ kctl = open();
+ assert(kctl != 0);
+ }
+
+ /**
+ * Calls <code>kstat_close(3KSTAT)</code>.
+ */
+ public void finalize()
+ {
+ close(kctl);
+ kctl = 0;
+ }
+
+ /**
+ * Invokes <code>kstat_open(3KSTAT)</code>.
+ */
+ private native long open();
+
+ /**
+ * Invokes <code>kstat_close(3KSTAT)</code>.
+ */
+ private native int close(long kctl);
+
+ /**
+ * Invokes <code>kstat_lookup(3KSTAT)</code> and returns a Kstat
+ * for any result, or null if none is found.
+ */
+ public native Kstat lookup(String module, int instance, String name);
+
+ /**
+ * Invokes <code>kstat_chain_update(3KSTAT)</code>.
+ *
+ * @throws KstatChainUpdateException if the native function
+ * returns -1.
+ */
+ public native void chainUpdate() throws KstatChainUpdateException;
+
+ /**
+ * Initialize cached class, method, and field IDs.
+ */
+ private static native void init();
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatException.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatException.java
new file mode 100644
index 0000000000..34867cd11e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatException.java
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+/**
+ * Abstract base class from which kstat-related exceptions are
+ * descended.
+ */
+public abstract class KstatException extends Exception {
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatReadException.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatReadException.java
new file mode 100644
index 0000000000..f3e682f77c
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatReadException.java
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+/**
+ * Indicates a that <code>kstat_read</code> failed for the given Kstat.
+ */
+public class KstatReadException extends KstatException {
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatTypeNotSupportedException.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatTypeNotSupportedException.java
new file mode 100644
index 0000000000..648ac236a0
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/KstatTypeNotSupportedException.java
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.kstat;
+
+/**
+ * Indicates a that <code>Kstat.getValue()</code> was invoked for a raw
+ * kstat whose structure is not understood.
+ */
+public class KstatTypeNotSupportedException extends KstatException {
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Makefile
new file mode 100644
index 0000000000..cc3b61b363
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/Makefile
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/kstat/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = Kstat.java \
+ KstatChainUpdateException.java \
+ KstatCtl.java \
+ KstatException.java \
+ KstatReadException.java \
+ KstatTypeNotSupportedException.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/package.html
new file mode 100644
index 0000000000..3eee0d0b3e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/kstat/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+kstat(9S) interfaces.
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2002/287/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation,
+please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/dynamic-resource-pools/">Dynamic Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityDomain.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityDomain.java
new file mode 100644
index 0000000000..a0b4c7aa3a
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityDomain.java
@@ -0,0 +1,350 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.locality;
+
+import java.util.*;
+
+import com.sun.solaris.service.pools.*;
+
+/**
+ * A representation of the Locality Groups for a single Solaris
+ * instance.
+ */
+public class LocalityDomain
+{
+ /**
+ * Obtain a Locality Group snapshot based on the view
+ * available to the caller.
+ */
+ public static final int LGRP_VIEW_CALLER = 0;
+
+ /**
+ * Obtain a Locality Group snapshot based on the view
+ * of the Operating System.
+ */
+ public static final int LGRP_VIEW_OS = 1;
+
+ static
+ {
+ System.loadLibrary("jlgrp");
+ }
+
+ /**
+ * The view used to create this LocalityDomain.
+ */
+ private int view;
+
+ /**
+ * The cookie which represents the snapshot of locality
+ * information held by the lgrp library.
+ */
+ private long cookie;
+
+ /**
+ * The root LocalityGroup for the LocalityDomain
+ */
+ private LocalityGroup root;
+
+ /**
+ * Cached value of maxLatency.
+ */
+ private final int maxLatency;
+
+ /**
+ * String representation of often used property.
+ */
+ private final static String CPU_SYS_ID = "cpu.sys_id";
+
+ /**
+ * Constructor.
+ *
+ * @param view to use when creating the LocalityDomain.
+ * @throws Exception if there is a problem initializing the
+ * lgrp snapshot.
+ */
+ public LocalityDomain(int view) throws Exception
+ {
+ this.view = view;
+ cookie = jl_init(view);
+ root = jl_root();
+ /*
+ * The maxLatency calculation is expensive and is used
+ * every time a locality objective is examined. Since
+ * it will never change over the lifetime of a
+ * LocalityDomain, we calculate it once in the
+ * constructor and cache for future use.
+ */
+ maxLatency = calcMaxLatency();
+ }
+
+ /**
+ * Reclaim the resource allocated by the C proxy.
+ *
+ * @throws Throwable if there is a problem reclaiming the reosurces.
+ */
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Return the "root" LocalityGroup.
+ */
+ public LocalityGroup getRoot()
+ {
+ return (root);
+ }
+
+ /**
+ * Close this LocalityDomain. Resources are reclaimed in the C
+ * proxy and this LocalityDomain should never be used
+ * again. None of the LocalityGroups which are referenced from
+ * this LocalityDomain should be used after this method is
+ * invoked. NB: jl_fini returns a success indicator which is
+ * ignored as we are closing this domain.
+ */
+ public void close()
+ {
+ if (cookie != 0) {
+ jl_fini();
+ cookie = 0;
+ root = null;
+ }
+ }
+
+ /**
+ * Return a string representation of this instance.
+ */
+ public String toString()
+ {
+ return (root.toString());
+ }
+
+ /**
+ * Return the groups in this domain to which the supplied cpus
+ * belong, excluding the supplied set of groups.
+ *
+ * @param exclude Set of groups to be excluded.
+ * @param cpus List of cpus
+ *
+ * @throws PoolsException if there is an error accessing the
+ * cpu details.
+ */
+ public Set foreignGroups(Set exclude, List cpus) throws PoolsException
+ {
+ Iterator cpuIt = cpus.iterator();
+ Set result = new HashSet();
+ while (cpuIt.hasNext()) {
+ Component comp = (Component) cpuIt.next();
+ int id = (int) comp.getLongProperty(CPU_SYS_ID);
+ LocalityGroup group = getGroup(id);
+ if (group != null && exclude.contains(group) == false)
+ result.add(group);
+ }
+ return (result);
+ }
+
+ /**
+ * Return the locality group which contains the majority of
+ * the cpus in the supplied list. If more than one group
+ * satisfies this criteria, then the choice of group is
+ * deterministic but unspecified.
+ *
+ * @param cpus List of cpus to be examined.
+ *
+ * @throws PoolsException if there is an error accessing the
+ * cpu details.
+ */
+ public LocalityGroup getRepresentativeGroup(List cpus)
+ throws PoolsException
+ {
+ Iterator cpuIt = cpus.iterator();
+ Map grps = new HashMap();
+ while (cpuIt.hasNext()) {
+ Component comp = (Component) cpuIt.next();
+ int id = (int) comp.getLongProperty(CPU_SYS_ID);
+ LocalityGroup group = getGroup(id);
+ Integer score = (Integer) grps.get(group);
+ if (score != null) {
+ int iscore = score.intValue() + 1;
+ grps.put(group, new Integer(iscore));
+ } else {
+ grps.put(group, new Integer(1));
+ }
+ }
+ Iterator groupIt = grps.keySet().iterator();
+ LocalityGroup centre = null;
+ Integer highest = new Integer(0);
+ while (groupIt.hasNext()) {
+ LocalityGroup cand = (LocalityGroup) groupIt.next();
+ Integer value = (Integer) grps.get(cand);
+ if (value.intValue() > highest.intValue()) {
+ highest = value;
+ centre = cand;
+ }
+ }
+ return (centre);
+ }
+
+ /**
+ * Return the maximum latency between the groups in this
+ * domain.
+ *
+ */
+ private int calcMaxLatency()
+ {
+ int max = 0;
+
+ Set groups = getGroups();
+ Iterator outer = groups.iterator();
+ while (outer.hasNext()) {
+ Iterator inner = groups.iterator();
+ LocalityGroup g1 = (LocalityGroup) outer.next();
+ while (inner.hasNext()) {
+ LocalityGroup g2 = (LocalityGroup) inner.next();
+ int latency = g1.getLatency(g2);
+ if (latency > max)
+ max = latency;
+ }
+ }
+ return (max);
+ }
+
+ /**
+ * Return the maximum possible latency between all locality
+ * groups in this domain.
+ */
+ public int getMaxLatency()
+ {
+ return (maxLatency);
+ }
+
+ /**
+ * Return the set of all LocalityGroups for this LocalityDomain.
+ */
+ public Set getGroups()
+ {
+ Set groups = new HashSet();
+ groups.add(root);
+ getGroups(root, groups);
+ return (groups);
+ }
+
+ /**
+ * Add all the descendent LocalityGroups for the supplied
+ * group into the supplied set.
+ *
+ * @param group is the group whose descendents are processed.
+ * @param descendents the set to add descendents of group.
+ */
+ private void getGroups(LocalityGroup group, Set descendents)
+ {
+ Set children = group.getChildren();
+
+ if (! children.isEmpty()) {
+ Iterator itChild = children.iterator();
+ while (itChild.hasNext()) {
+ LocalityGroup child = (LocalityGroup) itChild.
+ next();
+ getGroups(child, descendents);
+ }
+ descendents.addAll(children);
+ }
+ }
+
+ /**
+ * Return the LocalityGroup containing the supplied CPU
+ * id. Search all LocalityGroups starting at the root group.
+ *
+ * @param cpuid is the sys-id of the CPU to search for.
+ */
+ public LocalityGroup getGroup(int cpuid)
+ {
+ LocalityGroup answer = getGroup(root, cpuid);
+ return (getGroup(root, cpuid));
+ }
+
+ /**
+ * Return the LocalityGroup containing the supplied CPU
+ * id. Search LocalityGroups starting at the supplied group.
+ *
+ * @param group is the group to start searching from.
+ * @param cpuid is the sys-id of the CPU to search for.
+ */
+ private LocalityGroup getGroup(LocalityGroup group, int cpuid)
+ {
+ Set children = group.getChildren();
+
+ if (children.isEmpty()) {
+ int cpus[] = group.getCPUIDs();
+
+
+ for (int i = 0; i < cpus.length; i++)
+ if (cpus[i] == cpuid) {
+ return (group);
+ }
+ } else {
+ Iterator itGroup = children.iterator();
+ while (itGroup.hasNext()) {
+ LocalityGroup owner;
+ LocalityGroup child = (LocalityGroup) itGroup.
+ next();
+ if ((owner = getGroup(child, cpuid)) != null)
+ return (owner);
+ }
+ }
+ return (null);
+ }
+
+ /**
+ * Initialise the LocalityDomain with an lgrp snapshot.
+ *
+ * @param view is the type of snapshot to obtain.
+ */
+ private native long jl_init(int view) throws Exception;
+
+ /**
+ * Release the lgrp snapshot.
+ */
+ private native int jl_fini();
+
+ /**
+ * Find the root LocalityGroup.
+ */
+ private native LocalityGroup jl_root();
+
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityGroup.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityGroup.java
new file mode 100644
index 0000000000..f0d8694bdf
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/LocalityGroup.java
@@ -0,0 +1,211 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.locality;
+
+import java.util.*;
+
+import com.sun.solaris.service.pools.*;
+
+/**
+ * A representation of an individual Locality Group. A Locality Group
+ * resides within a Locality Domain.
+ */
+public class LocalityGroup
+{
+ /**
+ * The locality domain which contains this group.
+ */
+ private LocalityDomain domain;
+
+ /**
+ * The C proxy id for this instance.
+ */
+ private long id;
+
+ /**
+ * The parent group of this instance.
+ */
+ private LocalityGroup parent;
+
+ /**
+ * The array of CPU IDs which are assigned to this instance.
+ */
+ private int cpu_ids[];
+
+ /**
+ * The child groups of this instance.
+ */
+ private Set children;
+
+ /**
+ * Constructor.
+ *
+ * @param domain is the domain to which this instance belongs.
+ * @param id is the id of this instance.
+ * @param parent is the parent of this instance.
+ */
+ public LocalityGroup(LocalityDomain domain, long id,
+ LocalityGroup parent)
+ {
+ this.domain = domain;
+ this.id = id;
+ this.parent = parent;
+ this.cpu_ids = jl_cpus();
+ long nativeChildren[] = jl_children();
+ children = new HashSet();
+ for (int i = 0; i < nativeChildren.length; i++)
+ children.add(new LocalityGroup(domain,
+ nativeChildren[i], this));
+ }
+
+ /**
+ * Return a string representation of this instance.
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer().append("locality group ")
+ .append(id)
+ .append(" with cpus [");
+
+ String sep = "";
+ for (int i = 0; i < cpu_ids.length; i++) {
+ sb.append(sep);
+ sb.append(cpu_ids[i]);
+ sep = " ";
+ }
+ sb.append("]");
+
+ return (sb.toString());
+ }
+
+ /**
+ * Return the set of child locality groups for this instance.
+ */
+ public Set getChildren()
+ {
+ return (children);
+ }
+
+ /**
+ * Return the array of CPU IDs which belong to this locality
+ * group.
+ */
+ public int[] getCPUIDs()
+ {
+ return (cpu_ids);
+ }
+
+ /**
+ * Return the locality group ID.
+ */
+ long getID()
+ {
+ return (id);
+ }
+
+ /**
+ * Return the latency of the supplied group with respect to
+ * this group.
+ *
+ * @param other is another locality group belonging to the
+ * same LocalityDomain.
+ */
+ public int getLatency(LocalityGroup other)
+ {
+ return (jl_latency(id, other.getID()));
+ }
+
+ /**
+ * Return the number of Latency Groups to which these cpus
+ * belong which are not part of this group.
+ *
+ * @param cpus List of cpus to be examined.
+ *
+ * @throws PoolsException if there is an error accessing the
+ * cpu details.
+ */
+ public int countForeignGroups(List cpus) throws PoolsException
+ {
+ Set groups = new HashSet();
+ Iterator cpuIt = cpus.iterator();
+
+ while (cpuIt.hasNext()) {
+ Component comp = (Component) cpuIt.next();
+ int id = (int) comp.getLongProperty("cpu.sys_id");
+ for (int i = 0; i < cpu_ids.length; i++) {
+ if (cpu_ids[i] == id) {
+ LocalityGroup other = domain.
+ getGroup(id);
+ if (other != this &&
+ groups.contains(other) == false)
+ groups.add(other);
+ }
+ }
+ }
+ return (groups.size());
+ }
+
+ public Set contains(List cpus) throws PoolsException
+ {
+ Set contained = new HashSet();
+ Iterator cpuIt = cpus.iterator();
+ int set_cpus[] = getCPUIDs();
+
+ while (cpuIt.hasNext()) {
+ Component comp = (Component) cpuIt.next();
+ for (int i = 0; i < set_cpus.length; i++) {
+ if (set_cpus[i] == (int)comp.getLongProperty(
+ "cpu.sys_id")) {
+ contained.add(comp);
+ break;
+ }
+ }
+ }
+ return (contained);
+ }
+
+ /**
+ * Return an array containing the child locality group IDs.
+ */
+ private native long[] jl_children();
+
+ /**
+ * Return an array of CPU IDs within this locality group.
+ */
+ private native int[] jl_cpus();
+
+ /**
+ * Return the latency between the two supplied lgrp IDs.
+ *
+ * @param id1 is the first id.
+ * @param id2 is the second id.
+ */
+ private native int jl_latency(long id1, long id2);
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/Makefile
new file mode 100644
index 0000000000..65adde7df1
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/locality/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = LocalityDomain.java \
+ LocalityGroup.java
+
+all install: $(SOURCE:.java=.class)
+
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/package.html
new file mode 100644
index 0000000000..74fa4be14c
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/locality/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for manipulating Solaris Locality Groups.
+
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2003/034/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+ <li><a href="http://lgrp.eng/">Memory Hierarchy Aware Solaris Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Facility.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Facility.java
new file mode 100644
index 0000000000..0056164d17
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Facility.java
@@ -0,0 +1,261 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* ident "%Z%%M% %I% %E% SMI" */
+
+package com.sun.solaris.service.logging;
+
+/**
+ * <code>syslog(3C)</code> facility levels defined in
+ * <code>sys/syslog.h</code>.
+ */
+public class Facility {
+ /**
+ * LOG_KERN from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_KERN = 0 << 3;
+
+ /**
+ * LOG_USER from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_USER = 1 << 3;
+
+ /**
+ * LOG_MAIL from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_MAIL = 2 << 3;
+
+ /**
+ * LOG_DAEMON from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_DAEMON = 3 << 3;
+
+ /**
+ * LOG_AUTH from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_AUTH = 4 << 3;
+
+ /**
+ * LOG_SYSLOG from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_SYSLOG = 5 << 3;
+
+ /**
+ * LOG_LPR from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LPR = 6 << 3;
+
+ /**
+ * LOG_NEWS from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_NEWS = 7 << 3;
+
+ /**
+ * LOG_UUCP from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_UUCP = 8 << 3;
+
+ /**
+ * LOG_CRON from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_CRON = 15 << 3;
+
+ /**
+ * LOG_LOCAL0 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL0 = 16 << 3;
+
+ /**
+ * LOG_LOCAL1 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL1 = 17 << 3;
+
+ /**
+ * LOG_LOCAL2 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL2 = 18 << 3;
+
+ /**
+ * LOG_LOCAL3 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL3 = 19 << 3;
+
+ /**
+ * LOG_LOCAL4 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL4 = 20 << 3;
+
+ /**
+ * LOG_LOCAL5 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL5 = 21 << 3;
+
+ /**
+ * LOG_LOCAL6 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL6 = 22 << 3;
+
+ /**
+ * LOG_LOCAL7 from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_LOCAL7 = 23 << 3;
+
+ /**
+ * LOG_KERN <code>syslog(3C)</code> facility
+ */
+ public static final Facility KERN = new Facility(LOG_KERN, "KERN");
+
+ /**
+ * LOG_USER <code>syslog(3C)</code> facility
+ */
+ public static final Facility USER = new Facility(LOG_USER, "USER");
+
+ /**
+ * LOG_MAIL <code>syslog(3C)</code> facility
+ */
+ public static final Facility MAIL = new Facility(LOG_MAIL, "MAIL");
+
+ /**
+ * LOG_DAEMON <code>syslog(3C)</code> facility
+ */
+ public static final Facility DAEMON = new Facility(LOG_DAEMON,
+ "DAEMON");
+
+ /**
+ * LOG_AUTH <code>syslog(3C)</code> facility
+ */
+ public static final Facility AUTH = new Facility(LOG_AUTH, "AUTH");
+
+ /**
+ * LOG_SYSLOG <code>syslog(3C)</code> facility
+ */
+ public static final Facility SYSLOG = new Facility(LOG_SYSLOG,
+ "SYSLOG");
+
+ /**
+ * LOG_LPR <code>syslog(3C)</code> facility
+ */
+ public static final Facility LPR = new Facility(LOG_LPR, "LPR");
+
+ /**
+ * LOG_NEWS <code>syslog(3C)</code> facility
+ */
+ public static final Facility NEWS = new Facility(LOG_NEWS, "NEWS");
+
+ /**
+ * LOG_UUCP <code>syslog(3C)</code> facility
+ */
+ public static final Facility UUCP = new Facility(LOG_UUCP, "UUCP");
+
+ /**
+ * LOG_CRON <code>syslog(3C)</code> facility
+ */
+ public static final Facility CRON = new Facility(LOG_CRON, "CRON");
+
+ /**
+ * LOG_LOCAL0 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL0 = new Facility(LOG_LOCAL0,
+ "LOCAL0");
+
+ /**
+ * LOG_LOCAL1 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL1 = new Facility(LOG_LOCAL1,
+ "LOCAL1");
+
+ /**
+ * LOG_LOCAL2 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL2 = new Facility(LOG_LOCAL2,
+ "LOCAL2");
+
+ /**
+ * LOG_LOCAL3 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL3 = new Facility(LOG_LOCAL3,
+ "LOCAL3");
+
+ /**
+ * LOG_LOCAL4 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL4 = new Facility(LOG_LOCAL4,
+ "LOCAL4");
+
+ /**
+ * LOG_LOCAL5 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL5 = new Facility(LOG_LOCAL5,
+ "LOCAL5");
+
+ /**
+ * LOG_LOCAL6 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL6 = new Facility(LOG_LOCAL6,
+ "LOCAL6");
+
+ /**
+ * LOG_LOCAL7 <code>syslog(3C)</code> facility
+ */
+ public static final Facility LOCAL7 = new Facility(LOG_LOCAL7,
+ "LOCAL7");
+
+ /**
+ * Native facility of this instance.
+ */
+ private int facility;
+
+ /**
+ * Name of this facility.
+ */
+ private String string;
+
+ private Facility(int facility, String string)
+ {
+ this.facility = facility;
+ this.string = string;
+ }
+
+ /**
+ * Returns the native <code>syslog(3C)</code> facility.
+ */
+ public int getNative()
+ {
+ return (facility);
+ }
+
+ public boolean equals(Object o)
+ {
+ Facility f = (Facility)o;
+
+ return (getNative() == f.getNative());
+ }
+
+ public String toString()
+ {
+ return (string);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Makefile
new file mode 100644
index 0000000000..1d4f8519b5
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/logging/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = Facility.java \
+ Severity.java \
+ SyslogHandler.java \
+ SysloglikeFormatter.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Severity.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Severity.java
new file mode 100644
index 0000000000..ecd5d8d14c
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/Severity.java
@@ -0,0 +1,254 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* ident "%Z%%M% %I% %E% SMI" */
+
+package com.sun.solaris.service.logging;
+
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * <code>syslog(3C)</code> severity levels defined in
+ * <code>sys/syslog.h</code>.
+ */
+public final class Severity extends Level {
+ /**
+ * LOG_EMERG from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_EMERG = 0;
+
+ /**
+ * LOG_ALERT from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_ALERT = 1;
+
+ /**
+ * LOG_CRIT from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_CRIT = 2;
+
+ /**
+ * LOG_ERR from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_ERR = 3;
+
+ /**
+ * LOG_WARNING from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_WARNING = 4;
+
+ /**
+ * LOG_NOTICE from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_NOTICE = 5;
+
+ /**
+ * LOG_INFO from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_INFO = 6;
+
+ /**
+ * LOG_DEBUG from <code>sys/syslog.h</code>
+ */
+ private static final int LOG_DEBUG = 7;
+
+ /**
+ * Maps static instances by name.
+ */
+ private static final HashMap severityMap = new HashMap();
+
+ /**
+ * LOG_EMERG
+ */
+ public static final Severity EMERG = new Severity(LOG_EMERG,
+ Level.SEVERE.intValue() - 1, "EMERG");
+
+ /**
+ * LOG_ALERT
+ */
+ public static final Severity ALERT = new Severity(LOG_ALERT,
+ Level.SEVERE.intValue() - 2, "ALERT");
+
+ /**
+ * LOG_CRIT
+ */
+ public static final Severity CRIT = new Severity(LOG_CRIT,
+ Level.SEVERE.intValue() - 3, "CRIT");
+
+ /**
+ * LOG_ERR
+ */
+ public static final Severity ERR = new Severity(LOG_ERR,
+ Level.SEVERE.intValue() - 4, "ERR");
+
+ /**
+ * LOG_WARNING
+ */
+ public static final Severity WARNING = new Severity(LOG_WARNING,
+ Level.WARNING.intValue() - 1, "WARNING");
+
+ /**
+ * LOG_NOTICE
+ */
+ public static final Severity NOTICE = new Severity(LOG_NOTICE,
+ Level.INFO.intValue() - 1, "NOTICE");
+
+ /**
+ * LOG_INFO
+ */
+ public static final Severity INFO = new Severity(LOG_INFO,
+ Level.INFO.intValue() - 2, "INFO");
+
+ /**
+ * LOG_DEBUG
+ */
+ public static final Severity DEBUG = new Severity(LOG_DEBUG,
+ Level.FINE.intValue() - 1, "DEBUG");
+
+ /**
+ * Add aliases.
+ */
+ static {
+ severityMap.put("WARN", Severity.WARNING);
+ severityMap.put("ERROR", Severity.ERR);
+ }
+
+ /**
+ * Disallowed overidden constant Level
+ */
+ private static final Level SEVERE = null;
+
+ /**
+ * Disallowed overidden constant Level
+ */
+ private static final Level CONFIG = null;
+
+ /**
+ * Disallowed overidden constant Level
+ */
+ private static final Level FINE = null;
+
+ /**
+ * Disallowed overidden constant Level
+ */
+ private static final Level FINER = null;
+
+ /**
+ * Disallowed overidden constant Level
+ */
+ private static final Level FINEST = null;
+
+ /**
+ * See getNative().
+ */
+ private int severity;
+
+ /**
+ * Constructs a Severity with the given native severity, Java
+ * logging level, and name.
+ */
+ private Severity(int severity, int level, String name)
+ {
+ super(name, level);
+ this.severity = severity;
+
+ Object displaced = severityMap.put(name, this);
+ assert (displaced == null);
+ }
+
+ /**
+ * Returns the Severity closest in meaning to the given Level.
+ * This is meant to be used by SyslogHandler to determine a
+ * proper Severity for Records which only specify a Level.
+ *
+ * <ul>
+ * <li>Level.SEVERE or higher becomes Severity.ERR
+ * <li>Level.WARNING becomes Severity.WARNING
+ * <li>Level.INFO becomes Severity.INFO
+ * <li>Level.FINE becomes Severity.DEBUG
+ * </ul>
+ *
+ * If the level is below Level.FINE, i.e. the level is too low
+ * for syslog, then null is returned.
+ */
+ public static Severity severityForLevel(Level l)
+ {
+ if (l instanceof Severity)
+ return (Severity)l;
+ else {
+ if (l.intValue() >= Level.SEVERE.intValue())
+ return (ERR);
+ if (l.intValue() >= Level.WARNING.intValue())
+ return (WARNING);
+ if (l.intValue() >= Level.INFO.intValue())
+ return (INFO);
+ if (l.intValue() >= Level.CONFIG.intValue())
+ return (INFO);
+ if (l.intValue() >= Level.FINE.intValue())
+ return (DEBUG);
+ return (null);
+ }
+ }
+
+ /**
+ * Returns the native <code>syslog(3C)</code> severity.
+ */
+ public int getNative()
+ {
+ return (severity);
+ }
+
+ /**
+ * Returns the Severity object with the given name, interpreted
+ * case-insensitively.
+ *
+ * @throws IllegalArgumentException if the name isn't of a known
+ * severity.
+ */
+ public static Level parse(String name)
+ {
+ Severity severity = (Severity)severityMap.get(
+ name.toUpperCase());
+
+ if (severity == null)
+ throw new IllegalArgumentException();
+ else
+ return (severity);
+ }
+
+ /**
+ * Returns the Severity object with the given name, interpreted
+ * case-insensitively.
+ *
+ * @throws IllegalArgumentException if the name isn't of a known
+ * severity.
+ */
+ public static Severity getSeverityWithName(String name)
+ {
+ return ((Severity)parse(name));
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SyslogHandler.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SyslogHandler.java
new file mode 100644
index 0000000000..9764b2b5bb
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SyslogHandler.java
@@ -0,0 +1,267 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* ident "%Z%%M% %I% %E% SMI" */
+
+package com.sun.solaris.service.logging;
+
+import java.text.*;
+import java.util.*;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+
+import com.sun.solaris.service.exception.SuccinctStackTraceFormatter;
+
+/**
+ * This handler outputs LogRecords with <code>syslog(3C)</code> to the
+ * given facility with a severity translated by Level with a fixed
+ * table. Formatters are not used.
+ *
+ * Multiple SyslogHandlers may not be in concurrent use in one virtual
+ * machine.
+ */
+public final class SyslogHandler extends Handler {
+ /**
+ * <code>syslog(3C)</code> ident string, prepended to every
+ * message.
+ */
+ private String ident;
+
+ /**
+ * <code>syslog</code> facility to be logged to.
+ */
+ private Facility facility;
+
+ /**
+ * Records the instance of this singleton.
+ */
+ private static SyslogHandler instance = null;
+
+ /**
+ * Flag whether stack traces should be output when a record's
+ * <code>thrown</code> field is set. They will be formatted in
+ * a single line by <code>SuccinctStackTraceFormatter</code>,
+ * which does not include the Throwable's description, since
+ * it's presumably described by the log message). Default
+ * <code>true</code>.
+ */
+ private static boolean useStackTraces = true;
+
+ /**
+ * Default logging option value. Sets no options. (Corresponds
+ * to the <code>logopt</code> argument to openlog(3c).)
+ */
+ private static final int DEF_LOGOPT = 0;
+
+ /**
+ * Flag to set whether log records should indicate the record's
+ * logger. (default false)
+ */
+ private boolean useLoggerName = false;
+
+ /**
+ * Flag to set whether log records should indicate the last
+ * component of the record's logger name, if useLoggerName isn't
+ * set. (default true)
+ */
+ private boolean useShortLoggerName = true;
+
+ static {
+ System.loadLibrary("jsyslog");
+ }
+
+ private SyslogHandler(String ident, Facility facility)
+ {
+ if (ident == null || facility == null)
+ throw new IllegalArgumentException();
+
+ this.ident = ident;
+ this.facility = facility;
+
+ openlog(ident, DEF_LOGOPT, facility.getNative());
+ instance = this;
+ }
+
+ /**
+ * Return this virtual machine's instance of SyslogHandler,
+ * creating one which logs with the given identity to the given
+ * facility if necessary, unless an instance with a different
+ * identity or facility is already open, in which case an
+ * IllegalArgumentException is thrown.
+ *
+ * @throws IllegalArgumentException if the requested identity or
+ * facility differs from a previously-created instance.
+ */
+ public static SyslogHandler getInstance(String ident,
+ Facility facility)
+ {
+ if (instance != null) {
+ if (!instance.ident.equals(ident) ||
+ !instance.facility.equals(facility))
+ throw new IllegalArgumentException();
+ else
+ return (instance);
+ } else
+ return (instance = new SyslogHandler(ident, facility));
+ }
+
+ public void finalize()
+ {
+ try {
+ close();
+ } catch (Exception e) {
+ // superclass-defined exceptions do not apply
+ }
+ }
+
+ public String toString()
+ {
+ return ("SyslogHandler(" + ident + ", " + facility.toString() +
+ ")");
+ }
+
+ /**
+ * Calls <code>syslog(3C)</code>.
+ */
+ private static native void syslog(int severity, String message);
+
+ /**
+ * Calls <code>openlog(3C)</code>.
+ */
+ private static native void openlog(String ident, int logopt,
+ int facility);
+
+ /**
+ * Calls <code>closelog(3C)</code>.
+ */
+ private static native void closelog();
+
+ /**
+ * Publishes the given record with its associated Severity (or
+ * infers its severity with Severity.severityForLevel(), if
+ * another type of Level is used), if the result is non-null.
+ */
+ public void publish(LogRecord record)
+ {
+ Severity severity;
+
+ if (record.getLevel() instanceof Severity)
+ severity = (Severity)record.getLevel();
+ else
+ severity = Severity.severityForLevel(record
+ .getLevel());
+
+ if (getLevel().intValue() > severity.intValue())
+ return;
+
+ /*
+ * If the severity is null, the message isn't meant to
+ * be sent to syslog.
+ */
+ if (severity == null)
+ return;
+
+ StringBuffer message = new StringBuffer();
+ String loggerName = record.getLoggerName();
+ if (useLoggerName) {
+ if (loggerName != null) {
+ message.append("(");
+ message.append(record.getLoggerName());
+ message.append(") ");
+ }
+ } else if (useShortLoggerName) {
+ if (loggerName != null) {
+ message.append("(");
+ int lastDot = loggerName.lastIndexOf('.');
+ if (lastDot >= 0)
+ loggerName = loggerName.substring(
+ lastDot + 1);
+ message.append(loggerName);
+ message.append(") ");
+ }
+ }
+
+ message.append(record.getMessage());
+
+ /*
+ * If the Severity is null, it's not meant to be logged
+ * via syslog.
+ */
+ if (record.getThrown() != null && useStackTraces == true) {
+ /*
+ * Format the stack trace as one line and tack
+ * it onto the message.
+ */
+ message.append(" ");
+ message.append(SuccinctStackTraceFormatter
+ .formatWithDescription(record.getThrown(),
+ "with tracing information: ").toString());
+ }
+ syslog(severity.getNative(), message.toString());
+ }
+
+ public void flush()
+ {
+ }
+
+ public void close() throws SecurityException
+ {
+ if (instance != null) {
+ closelog();
+ instance = null;
+ }
+ }
+
+ /**
+ * Formatters may not be used with SyslogHandler.
+ *
+ * @throws IllegalArgumentException if the use of one is
+ * attempted.
+ */
+ public void setFormatter(Formatter formatter)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Returns the <code>syslog(3C)</code> ident string, which is
+ * prepended to every message.
+ */
+ public String getIdent()
+ {
+ return (ident);
+ }
+
+ /**
+ * Returns the <code>syslog</code> facility to be logged to.
+ */
+ public Facility getFacility()
+ {
+ return (facility);
+ }
+
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SysloglikeFormatter.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SysloglikeFormatter.java
new file mode 100644
index 0000000000..27d9236e49
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/SysloglikeFormatter.java
@@ -0,0 +1,172 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* ident "%Z%%M% %I% %E% SMI" */
+
+package com.sun.solaris.service.logging;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.*;
+import java.util.*;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+import com.sun.solaris.service.exception.SuccinctStackTraceFormatter;
+
+/**
+ * Formats a LogRecord in a human-readable, <code>syslog</code>-like
+ * format, and is intended for use with non-syslog handlers, such as
+ * FileHandler.
+ *
+ * Multi-line messages are automatically indented by four spaces to make
+ * subsequent lines easier to differentiate from new records.
+ */
+public class SysloglikeFormatter extends Formatter {
+ /**
+ * The date set for each published Record.
+ */
+ private Date date = new Date();
+
+ /**
+ * Format string for published dates.
+ */
+ private final static String dateFormat =
+ "MMM d kk:mm:ss";
+
+ /**
+ * For published dates, the formatter.
+ */
+ private DateFormat dateFormatter;
+
+ /**
+ * For published dates, the argument to date formatter.
+ */
+ private Object args[] = { date };
+
+ /**
+ * Line separator string.
+ */
+ private String lineSeparator = (String)java.security.AccessController
+ .doPrivileged(new sun.security.action.GetPropertyAction(
+ "line.separator"));
+
+ /**
+ * Flag to set whether log records should indicate the name of
+ * the class generating the record, if possible. (default
+ * false)
+ */
+ private boolean useClassName = false;
+
+ /**
+ * Flag to set whether log records should indicate the record's
+ * logger, if useClassName isn't set and the class name was
+ * available. (default false)
+ */
+ private boolean useLoggerName = false;
+
+ /**
+ * Flag to set whether log records should indicate the last
+ * component of the record's logger name, if useLoggerName isn't
+ * set. (default true)
+ */
+ private boolean useShortLoggerName = true;
+
+ /**
+ * Flag to set whether log records should indicate the method
+ * used to invoke the logger, if available. (default false)
+ */
+ private boolean useMethodName = false;
+
+ /**
+ * Flag to set whether each record should be split into two
+ * lines such that the severity and message are on a line by
+ * themselves. (default false)
+ */
+ private boolean useTwoLineStyle = false;
+
+ /**
+ * Format the given LogRecord.
+ * @param record the log record to be formatted.
+ * @return a formatted log record.
+ */
+ public synchronized String format(LogRecord record)
+ {
+ StringBuffer sb = new StringBuffer();
+
+ date.setTime(record.getMillis());
+ StringBuffer text = new StringBuffer();
+ if (dateFormatter == null)
+ dateFormatter = new SimpleDateFormat(dateFormat);
+ sb.append(dateFormatter.format(date));
+
+ if (record.getSourceClassName() != null && useClassName) {
+ sb.append(" ");
+ sb.append(record.getSourceClassName());
+ } else if (useLoggerName) {
+ if (record.getLoggerName() != null) {
+ sb.append(" ");
+ sb.append(record.getLoggerName());
+ }
+ } else if (useShortLoggerName) {
+ String loggerName = record.getLoggerName();
+
+ if (loggerName != null) {
+ sb.append(" ");
+ int lastDot = loggerName.lastIndexOf('.');
+ if (lastDot >= 0)
+ loggerName = loggerName.substring(
+ lastDot + 1);
+ sb.append(loggerName);
+ }
+ }
+
+ if (record.getSourceMethodName() != null && useMethodName) {
+ sb.append(" ");
+ sb.append(record.getSourceMethodName());
+ }
+ if (useTwoLineStyle)
+ sb.append(lineSeparator);
+ else
+ sb.append(" ");
+
+ String message = formatMessage(record);
+ message = message.replaceAll("\n", lineSeparator + " ");
+
+ sb.append(record.getLevel()).toString();
+ sb.append(": ");
+ sb.append(message);
+ if (record.getThrown() != null) {
+ sb.append(" ");
+ sb.append(SuccinctStackTraceFormatter
+ .formatWithDescription(record.getThrown(),
+ "with tracing information: ").toString());
+ }
+ sb.append(lineSeparator);
+
+ return sb.toString();
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/package.html
new file mode 100644
index 0000000000..4224cf5b45
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/logging/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Extends the logging API for use with syslog(3C).
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2002/287/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation,
+please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/dynamic-resource-pools/">Dynamic Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Component.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Component.java
new file mode 100644
index 0000000000..ff762d83ed
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Component.java
@@ -0,0 +1,186 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+/**
+ * The <code>Component</code> class represents a configuration
+ * resource component.
+ */
+public class Component extends Element
+{
+ /**
+ * The type of the component.
+ */
+ private final String type;
+
+ /**
+ * The system id of the component.
+ */
+ private final long sys_id;
+
+ /**
+ * The key of the component.
+ */
+ private final String key;
+
+ /**
+ * Constructor
+ *
+ * @param conf The configuration to which this component belongs
+ * @param comp The pointer to the native component
+ * @throws PoolsException If accessing the proxy fails.
+ */
+ Component(Configuration conf, long comp) throws PoolsException
+ {
+ _conf = conf;
+ Value val = getProperty("type", comp);
+ type = val.getString();
+ val.close();
+ val = getProperty(type + ".sys_id", comp);
+ sys_id = val.getLong();
+ val.close();
+ key = type + "." + sys_id;
+ }
+
+ /**
+ * Return the pointer to the component represented by this object.
+ *
+ * @return conf the pointer to the component represented by this object
+ * @throws PoolsException If the component cannot be located.
+ */
+ long getComponent() throws PoolsException
+ {
+ return (_conf.checkComponent(type, sys_id));
+ }
+
+ /**
+ * Returns a descriptive string which describes the component.
+ *
+ * @param deep Whether the information should contain information about
+ * all contained elements.
+ * @throws PoolsException If the component cannot be located.
+ * @return a descriptive string which describes the component.
+ */
+ public String getInformation(int deep) throws PoolsException
+ {
+ return (PoolInternal.pool_component_info(_conf.getConf(),
+ getComponent(), deep));
+ }
+
+ /**
+ * Returns a string representation of this component.
+ *
+ * @return a string representation of this component.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(type);
+ buf.append(" ");
+ buf.append(sys_id);
+ return (buf.toString());
+ }
+
+ /**
+ * Indicates whether some other Component is "equal to this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof Component))
+ return (false);
+ Component other = (Component) o;
+ if (type.compareTo(other.getType()) != 0 ||
+ sys_id != other.getSysId())
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (type.hashCode() + (int) sys_id);
+ }
+
+ /**
+ * Return the pointer to this component as an element.
+ *
+ * @return The pointer to the native component which this object wraps.
+ * @throws PoolsExecption If there is an error converting the native
+ * component pointer to a native elem pointer.
+ */
+ protected long getElem() throws PoolsException
+ {
+ long elem;
+
+ if ((elem = PoolInternal.pool_component_to_elem(_conf.getConf(),
+ getComponent())) == 0)
+ throw new PoolsException();
+ return (elem);
+ }
+
+ /**
+ * Return the type of the component
+ */
+ String getType()
+ {
+ return (type);
+ }
+
+ /**
+ * Return the system id of the component.
+ */
+ long getSysId()
+ {
+ return (sys_id);
+ }
+
+ /**
+ * Return the key of the component.
+ */
+ String getKey()
+ {
+ return (key);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Configuration.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Configuration.java
new file mode 100644
index 0000000000..ade169e78e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Configuration.java
@@ -0,0 +1,689 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * The <code>Configuration</code> class represents a pools configuration.
+ */
+public class Configuration extends Element
+{
+ /**
+ * Indicates whether the configuration represents a usable
+ * configuration.
+ */
+ private boolean _valid = false;
+
+ /**
+ * A reference to the native libpool object represented by
+ * this instance.
+ */
+ private long _this;
+
+ /**
+ * The name of this instance.
+ */
+ private String name;
+
+ /**
+ * The cache of elements known to this configuration.
+ */
+ private Map elements;
+
+ /**
+ * The key of the configuration.
+ */
+ private String key;
+
+ /**
+ * Constructor
+ * @param location The location of the configuration.
+ * @param perms The OR'd permissions used when opening this
+ * configuration.
+ * @exception PoolsException The error message generated by
+ * libpool.
+ */
+ public Configuration(String location, int perms) throws PoolsException
+ {
+ if (((_this = PoolInternal.pool_conf_alloc())) == 0)
+ throw new PoolsException();
+ _conf = this;
+ open(location, perms);
+ elements = new HashMap();
+ }
+
+ /**
+ * Reclaim the memory allocated for this configuration by the C
+ * proxy.
+ *
+ * @throws Throwable If freeing this configuration fails.
+ */
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ close();
+ if (_this != 0) {
+ PoolInternal.pool_conf_free(_this);
+ _this = 0;
+ }
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Returns a pointer to the native configuration, wrapped by this
+ * instance.
+ *
+ * @return the configuration pointer.
+ */
+ final long getConf()
+ {
+ return (_this);
+ }
+
+ /**
+ * Opens the configuration at the supplied location and with the
+ * supplied permissions.
+ *
+ * @throws PoolsException if there is an error opening the
+ * configuration.
+ */
+ public void open(String location, int perms) throws PoolsException
+ {
+ if (_valid == false) {
+ if (PoolInternal.pool_conf_open(getConf(), location,
+ perms) != PoolInternal.PO_SUCCESS) {
+ throw new PoolsException();
+ }
+ _valid = true;
+ name = getStringProperty("system.name");
+ key = "system." + name;
+ }
+ }
+
+ /**
+ * Closes the configuration.
+ *
+ */
+ public void close()
+ {
+ if (_valid == true) {
+ elements.clear();
+ PoolInternal.pool_conf_close(getConf());
+ name = key = null;
+ }
+ _valid = false;
+ }
+
+ /**
+ * Returns the location of the configuration.
+ *
+ * @return the location of the configuration.
+ */
+ public String getLocation()
+ {
+ return (PoolInternal.pool_conf_location(getConf()));
+ }
+
+ /**
+ * Returns the status of the configuration.
+ *
+ * @return the status of the configuration.
+ */
+ public int status()
+ {
+ return (PoolInternal.pool_conf_status(getConf()));
+ }
+
+ /**
+ * Remove the configuration.
+ *
+ * @throws PoolsExecption If the removal fails.
+ */
+ public void remove() throws PoolsException
+ {
+ if (PoolInternal.pool_conf_remove(getConf()) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Rollback the configuration, undoing any changes which have been
+ * made since the last commit or (if there are no commits) since the
+ * configuration was opened.
+ *
+ * @throws PoolsExecption If the rollback fails.
+ */
+ public void rollback() throws PoolsException
+ {
+ if (PoolInternal.pool_conf_rollback(getConf()) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Commit the configuration, making any changes since the configuration
+ * was last committed (or opened if there have been no prior commits)
+ * permanent.
+ *
+ * @throws PoolsExecption If the commit fails.
+ */
+ public void commit(int active) throws PoolsException
+ {
+ if (PoolInternal.pool_conf_commit(getConf(), active) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Export the configuration, storing the current state of the
+ * configuration at the supplied location in the supplied format.
+ *
+ * @param location The location of the export.
+ * @param format The format of the export.
+ * @throws PoolsExecption If the export fails.
+ */
+ public void export(String location, int format) throws PoolsException
+ {
+ if (PoolInternal.pool_conf_export(getConf(), location, format)
+ != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Validate the configuration, ensuring that the current state of the
+ * configuration satisfies the supplied validation level.
+ *
+ * @param level The desired level of validation.
+ * @throws PoolsExecption If the validation fails.
+ */
+ public void validate(int level) throws PoolsException
+ {
+ if (PoolInternal.pool_conf_validate(getConf(), level)
+ != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Update the configuration, ensuring that the current state of the
+ * configuration reflects that of the kernel.
+ *
+ * @throws PoolsExecption If the update fails.
+ * @return a bitmap of the changed types.
+ */
+ public int update() throws PoolsException
+ {
+ return (PoolInternal.pool_conf_update(getConf()));
+ }
+
+ /**
+ * Create a pool with the supplied name.
+ *
+ * @param name The name of the PoolInternal.
+ * @throws PoolsExecption If the pool creation fails.
+ * @return a pool with the supplied name.
+ */
+ public Pool createPool(String name) throws PoolsException
+ {
+ long aPool;
+
+ if ((aPool = PoolInternal.pool_create(getConf(), name)) == 0) {
+ throw new PoolsException();
+ }
+ Pool p = new Pool(this, aPool);
+ elements.put(p.getKey(), p);
+ return (p);
+ }
+
+ /**
+ * Destroy the supplied PoolInternal.
+ *
+ * @param aPool The pool to be destroyed.
+ * @throws PoolsException If the pool cannot be located.
+ */
+ public void destroyPool(Pool aPool) throws PoolsException
+ {
+ elements.remove(aPool.getKey());
+ PoolInternal.pool_destroy(getConf(), aPool.getPool());
+ }
+
+ /**
+ * Get the pool with the supplied name.
+ *
+ * @param name The name of the pool to be found.
+ * @throws PoolsExecption If the pool cannot be located.
+ * @return a pool with the supplied name.
+ */
+ public Pool getPool(String name) throws PoolsException
+ {
+ long aPool;
+
+ if ((aPool = PoolInternal.pool_get_pool(getConf(), name)) ==
+ 0) {
+ throw new PoolsException();
+ }
+ if (elements.containsKey("PoolInternal." + name))
+ return ((Pool) elements.get("PoolInternal." + name));
+ else {
+ Pool p = new Pool(this, aPool);
+ elements.put(p.getKey(), p);
+ return (p);
+ }
+ }
+
+ /**
+ * Get the proxy for the pool with the supplied name.
+ *
+ * @param name The name of the pool to be found.
+ * @throws PoolsExecption If the pool cannot be located.
+ * @return the proxy for the pool with the supplied name.
+ */
+ long checkPool(String name) throws PoolsException
+ {
+ long aPool;
+
+ if ((aPool = PoolInternal.pool_get_pool(getConf(), name)) ==
+ 0) {
+ throw new PoolsException();
+ }
+ return (aPool);
+ }
+
+ /**
+ * Get a list of pools which match the supplied selection criteria
+ * in values.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of pools which match the supplied criteria
+ */
+ public List getPools(List values) throws PoolsException
+ {
+ List pools;
+
+ if ((pools = PoolInternal.pool_query_pools(getConf(), values))
+ == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ ArrayList aList = new ArrayList(pools.size());
+ for (int i = 0; i < pools.size(); i++)
+ aList.add(new Pool(this,
+ ((Long)pools.get(i)).longValue()));
+ return (aList);
+ }
+
+ /**
+ * Create a resource with the supplied type and name.
+ *
+ * @param type The type of the resource.
+ * @param name The name of the resource.
+ * @throws PoolsExecption If the resource creation fails.
+ * @return a resource of the supplied type and name.
+ */
+ public Resource createResource(String type, String name)
+ throws PoolsException
+ {
+ long aResource;
+
+ if ((aResource = PoolInternal.pool_resource_create(getConf(),
+ type, name)) == 0) {
+ throw new PoolsException();
+ }
+ Resource res = new Resource(this, aResource);
+ elements.put(res.getKey(), res);
+ return (res);
+ }
+
+ /**
+ * Destroy the supplied resource.
+ *
+ * @param res The resource to be destroyed.
+ * @throws PoolsException If the resource cannot be located.
+ */
+ public void destroyResource(Resource res) throws PoolsException
+ {
+ elements.remove(res.getKey());
+ PoolInternal.pool_resource_destroy(getConf(),
+ res.getResource());
+ }
+
+ /**
+ * Get the resource with the supplied name.
+ *
+ * @param type The type of the resource to be found.
+ * @param name The name of the resource to be found.
+ * @throws PoolsExecption If the resource cannot be located.
+ * @return a resource with the supplied name.
+ */
+ public Resource getResource(String type, String name)
+ throws PoolsException
+ {
+ long res;
+
+ if ((res = PoolInternal.pool_get_resource(getConf(), type,
+ name)) == 0) {
+ throw new PoolsException();
+ }
+ if (elements.containsKey(type + "." + name))
+ return ((Resource) elements.get(type + "." + name));
+ else {
+ Resource r = new Resource(this, res);
+ elements.put(r.getKey(), r);
+ return (r);
+ }
+ }
+
+ /**
+ * Get the proxy for the resource with the supplied type and
+ * name.
+ *
+ * @param type The type of the resource to be found.
+ * @param name The name of the resource to be found.
+ * @throws PoolsExecption If the resource cannot be located.
+ * @return the proxy for the resource with the supplied name.
+ */
+ long checkResource(String type, String name) throws PoolsException
+ {
+ long res;
+
+ if ((res = PoolInternal.pool_get_resource(getConf(), type,
+ name)) == 0) {
+ throw new PoolsException();
+ }
+ return (res);
+ }
+
+ /**
+ * Get a list of resources which match the supplied selection criteria
+ * in values.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of resources which match the supplied criteria
+ */
+ public List getResources(List values) throws PoolsException
+ {
+ List resources;
+
+ if ((resources = PoolInternal.pool_query_resources(getConf(),
+ values)) == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ ArrayList aList = new ArrayList(resources.size());
+ for (int i = 0; i < resources.size(); i++)
+ aList.add(new Resource(this,
+ ((Long)resources.get(i)).longValue()));
+ return (aList);
+ }
+
+ /**
+ * Get the component with the supplied name.
+ *
+ * @param type The type of the component to be found.
+ * @param sys_id The sys_id of the component to be found.
+ * @throws PoolsExecption If the component cannot be located.
+ * @return a component with the supplied name.
+ */
+ public Component getComponent(String type, long sys_id)
+ throws PoolsException
+ {
+ List props = new ArrayList();
+ Value ptype = new Value("type", type);
+ Value psys_id = new Value(type + ".sys_id", sys_id);
+
+ props.add(ptype);
+ props.add(psys_id);
+ List comps = getComponents(props);
+ ptype.close();
+ psys_id.close();
+ if (comps.size() != 1)
+ throw new PoolsException();
+ return ((Component) comps.get(0));
+ }
+
+ /**
+ * Get the component proxy with the supplied type and sys_id.
+ *
+ * @param type The type of the component to be found.
+ * @param sys_id The sys_id of the component to be found.
+ * @throws PoolsExecption If the component cannot be located.
+ * @return a component with the supplied name.
+ */
+ long checkComponent(String type, long sys_id)
+ throws PoolsException
+ {
+ List props = new ArrayList();
+ Value ptype = new Value("type", type);
+ Value psys_id = new Value(type + ".sys_id", sys_id);
+
+ props.add(ptype);
+ props.add(psys_id);
+ List comps = checkComponents(props);
+ ptype.close();
+ psys_id.close();
+ if (comps.size() != 1)
+ throw new PoolsException();
+ return (((Long)comps.get(0)).longValue());
+ }
+
+ /**
+ * Get a list of components which match the supplied selection criteria
+ * in values.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of components which match the supplied criteria
+ */
+ public List getComponents(List values) throws PoolsException
+ {
+ List components;
+
+ if ((components = PoolInternal.pool_query_components(getConf(),
+ values)) == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ ArrayList aList = new ArrayList(components.size());
+ for (int i = 0; i < components.size(); i++) {
+ /*
+ * Extract type information
+ */
+ Value typeVal = new Value(name);
+
+ if (PoolInternal.pool_get_property(getConf(),
+ ((Long)components.get(i)).longValue(), "type",
+ typeVal.getValue()) == PoolInternal.POC_INVAL)
+ throw new PoolsException();
+ if (typeVal == null)
+ throw new PoolsException();
+ String type = typeVal.getString();
+ typeVal.close();
+
+ Value idValue = new Value(name);
+
+ if (PoolInternal.pool_get_property(getConf(),
+ ((Long)components.get(i)).longValue(),
+ type + ".sys_id", idValue.getValue()) ==
+ PoolInternal.POC_INVAL)
+ throw new PoolsException();
+ if (idValue == null)
+ throw new PoolsException();
+ long sys_id = idValue.getLong();
+ idValue.close();
+
+ if (elements.containsKey(type + "." + sys_id))
+ aList.add((Component)elements.get(type + "." +
+ sys_id));
+ else
+ aList.add(new Component(this, ((Long)components.
+ get(i)).longValue()));
+ }
+ return (aList);
+
+ }
+
+ /**
+ * Get a list of component proxies which match the supplied
+ * selection criteria in values.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of component proxies which match the
+ * supplied criteria
+ */
+ List checkComponents(List values) throws PoolsException
+ {
+ List components;
+
+ if ((components = PoolInternal.pool_query_components(getConf(),
+ values)) == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ return (components);
+ }
+ /**
+ * Returns a descriptive string which describes the configuration.
+ *
+ * @param deep Whether the information should contain information about
+ * all contained elements.
+ * @return a descriptive string which describes the configuration.
+ */
+ public String getInformation(int deep)
+ {
+ return (PoolInternal.pool_conf_info(_conf.getConf(), deep));
+ }
+
+ /**
+ * Returns a string representation of this configuration.
+ *
+ * @return a string representation of this configuration.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("system: ");
+ buf.append(name);
+ return (buf.toString());
+ }
+
+ /**
+ * Indicates whether some other Configuration is "equal to this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof Configuration))
+ return (false);
+ Configuration other = (Configuration) o;
+ if (name.compareTo(other.getName()) != 0)
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ /**
+ * Return the pointer to this configuration as an element.
+ *
+ * @return The pointer to the native configuration which this object
+ * wraps.
+ * @throws PoolsExecption If there is an error converting the native
+ * configuration pointer to a native elem pointer.
+ */
+ protected long getElem() throws PoolsException
+ {
+ long elem;
+
+ if ((elem = PoolInternal.pool_conf_to_elem(getConf())) == 0)
+ throw new PoolsException();
+ return (elem);
+ }
+
+ /**
+ * Return the anme of the configuration.
+ */
+ String getName()
+ {
+ return (name);
+ }
+
+ /**
+ * Return the key of the configuration.
+ */
+ String getKey()
+ {
+ return (key);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Element.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Element.java
new file mode 100644
index 0000000000..8736fd6c8e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Element.java
@@ -0,0 +1,287 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The <code>Element</code> class represents a pools configuration
+ * element. The class is an abstract, base class for concrete
+ * implementation elements, such as pool and resource.
+ */
+public abstract class Element implements Property, PropertyWalk
+{
+ /**
+ * The configuration to which this element belongs.
+ */
+ protected Configuration _conf;
+
+ /**
+ * Returns a string representation of this element.
+ *
+ * @return a string representation of this element.
+ */
+ public String toString()
+ {
+ try {
+ return (getInformation(1));
+ } catch (PoolsException pe) {
+ return (pe.toString());
+ }
+ }
+
+ /**
+ * Returns a descriptive string which describes the element.
+ *
+ * @param deep Whether the information should contain information about
+ * all contained elements.
+ * @throws PoolsException If the element cannot be located.
+ * @return a descriptive string which describes the element.
+ */
+ public abstract String getInformation(int deep) throws PoolsException;
+
+ /**
+ * Get the property with the supplied name.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsExecption If there is an error accessing the property.
+ * @return a value containing the property details.
+ */
+ private Value getProperty(String name) throws PoolsException
+ {
+ Value value = new Value(name);
+
+ if (PoolInternal.pool_get_property(_conf.getConf(), getElem(),
+ name, value.getValue()) == PoolInternal.POC_INVAL)
+ throw new PoolsException();
+ return (value);
+ }
+
+ /**
+ * Get the property with the supplied name using the supplied
+ * proxy.
+ *
+ * @param name The name of the property to be retrieved.
+ * @param proxy The proxy item used to retrieve the property.
+ * @throws PoolsExecption If there is an error accessing the property.
+ * @return a value containing the property details.
+ */
+ protected Value getProperty(String name, long proxy)
+ throws PoolsException
+ {
+ Value value = new Value(name);
+
+ if (PoolInternal.pool_get_property(_conf.getConf(), proxy, name,
+ value.getValue()) == PoolInternal.POC_INVAL)
+ throw new PoolsException();
+ return (value);
+ }
+
+ /**
+ * Put the supplied value as an element property with the supplied
+ * name.
+ *
+ * @param name The name of the property to be updated.
+ * @param value The value of the property to be updated.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public void putProperty(String name, Value value) throws PoolsException
+ {
+ if (PoolInternal.pool_put_property(_conf.getConf(), getElem(),
+ name, value.getValue()) != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Remove the element property with the supplied name.
+ *
+ * @param name The name of the property to be removed.
+ * @throws PoolsExecption If there is an error removing the property.
+ */
+ public void rmProperty(String name) throws PoolsException
+ {
+ if (PoolInternal.pool_rm_property(_conf.getConf(), getElem(),
+ name) != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a String property.
+ *
+ * If the type of the property does not match, i.e. it's not a
+ * String, or the element does not have such a property then a
+ * PoolsException is thrown.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsException If getting the String property fails.
+ */
+ public String getStringProperty(String name) throws PoolsException
+ {
+ Value val = getProperty(name);
+
+ if (val != null) {
+ String ret = val.getString();
+ val.close();
+ return (ret);
+ }
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a long property.
+ *
+ * If the type of the property does not match, i.e. it's not a
+ * long, or the element does not have such a property then a
+ * PoolsException is thrown.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsException If getting the long property fails.
+ */
+ public long getLongProperty(String name) throws PoolsException
+ {
+ Value val = getProperty(name);
+
+ if (val != null) {
+ long ret = val.getLong();
+ val.close();
+ return (ret);
+ }
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a double property.
+ *
+ * If the type of the property does not match, i.e. it's not a
+ * double, or the element does not have such a property then a
+ * PoolsException is thrown.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsException If getting the double property fails.
+ */
+ public double getDoubleProperty(String name) throws PoolsException
+ {
+ Value val = getProperty(name);
+
+ if (val != null) {
+ double ret = val.getDouble();
+ val.close();
+ return (ret);
+ }
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a boolean property.
+ *
+ * If the type of the property does not match, i.e. it's not a
+ * boolean, or the element does not have such a property then
+ * a PoolsException is thrown.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsException If getting the boolean property fails.
+ */
+ public boolean getBoolProperty(String name) throws PoolsException
+ {
+ Value val = getProperty(name);
+
+ if (val != null) {
+ boolean ret = val.getBool();
+ val.close();
+ return (ret);
+ }
+ throw new PoolsException();
+ }
+
+ /**
+ * Walk all properties of the invoking object.
+ *
+ * @param elem The element to whom the property belongs.
+ * @param val The value representing the current element.
+ * @param user User supplied data, provided when the walk is invoked.
+ * @throws PoolsExecption If there is an error walking the property.
+ * @return 0 to continue the walk, anything else to terminate it.
+ */
+ public int walk(Element elem, Value val, Object user)
+ throws PoolsException
+ {
+ System.out.println("Property name: " + val.getName() +
+ ", value: "+val.toString());
+ val.close();
+ return (0);
+ }
+
+ /**
+ * Return the pointer to this subtype as an element.
+ *
+ * @return The pointer to the native subtype which this object wraps.
+ * @throws PoolsExecption If there is an error converting the native
+ * subtype pointer to a native elem pointer.
+ */
+ protected abstract long getElem() throws PoolsException;
+
+ /**
+ * Walk all the properties of this element.
+ *
+ * @param handler The object which will receive the callbacks.
+ * @param user Data supplied by the user for use in the callback.
+ * @return 0 for a successful walk, else 1.
+ * @throws PoolsExecption If there is an error during the walk.
+ */
+ public int walkProperties(PropertyWalk handler, Object user)
+ throws PoolsException
+ {
+ return (walkProps(_conf.getConf(), getElem(), handler, user));
+ }
+
+ /**
+ * Walk the properties of the supplied element using the
+ * supplied handler.
+ *
+ * @param conf native reference to the configuration in which
+ * the element belongs.
+ * @param elem native reference to the element whose
+ * properties are to be walked.
+ * @param handler a method to be invoked with each property of
+ * the elem.
+ * @param user a user parameter which is passed to handler on
+ * each invocation.
+ * @throws PoolsException if there is an error accessing the
+ * element properties.
+ */
+ private native int walkProps(long conf, long elem,
+ PropertyWalk handler, Object user) throws PoolsException;
+
+ /**
+ * Return the key of the element.
+ */
+ abstract String getKey();
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/HRTime.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/HRTime.java
new file mode 100644
index 0000000000..0cab0c6f71
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/HRTime.java
@@ -0,0 +1,107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.math.BigInteger;
+import java.lang.Comparable;
+
+/**
+ * hrtime_t-like (see gethrtime(3C)) uptime-based time value (i.e., resilient
+ * to changes to the host's clock) for comparison of timestamps of sampled
+ * data.
+ */
+public class HRTime implements Comparable {
+ /**
+ * The native <code>hrtime_t</code> value.
+ */
+ private UnsignedInt64 value;
+
+ /**
+ * Constructor.
+ */
+ public HRTime()
+ {
+ this.value = timestamp();
+ }
+
+ /**
+ * Constructs a new HRTime with the value of the given
+ * UnsignedInt64.
+ *
+ * @param value The timestamp to be used.
+ */
+ public HRTime(UnsignedInt64 value)
+ {
+ this.value = value;
+ }
+
+ /**
+ * Computes the difference between this time and another, older,
+ * time.
+ *
+ * @param older the time from which to compute the delta.
+ * @throws IllegalArgumentException if the given time is not
+ * earlier than this one.
+ */
+ public HRTime deltaFrom(HRTime older)
+ {
+ if (older.compareTo(value) > 0)
+ throw(new IllegalArgumentException());
+ else
+ return (new HRTime(new UnsignedInt64(value
+ .subtract(older.getValue()))));
+ }
+
+ /**
+ * Returns this HRTime's value.
+ */
+ public UnsignedInt64 getValue()
+ {
+ return (value);
+ }
+
+ /**
+ * Return a string representation of this instance.
+ */
+ public String toString()
+ {
+ return (value.toString());
+ }
+
+ public int compareTo(Object o) {
+ HRTime other = (HRTime) o;
+
+ return (value.compareTo(other.getValue()));
+ }
+
+ /**
+ * Return the current timestamp.
+ */
+ private native UnsignedInt64 timestamp();
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Makefile
new file mode 100644
index 0000000000..ab5fdcf0e1
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Makefile
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/pools/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+
+SOURCE = PoolInternal.java \
+ Component.java \
+ Configuration.java \
+ Element.java \
+ HRTime.java \
+ Property.java \
+ PropertyWalk.java \
+ Pool.java \
+ PoolsException.java \
+ Resource.java \
+ UnsignedInt64.java \
+ Value.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Pool.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Pool.java
new file mode 100644
index 0000000000..f22f4b311f
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Pool.java
@@ -0,0 +1,227 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The <code>Pool</code> class represents a Resource Pool.
+ */
+public class Pool extends Element {
+
+ /**
+ * The name of this instance.
+ */
+ private final String name;
+ /**
+ * The key of the pool.
+ */
+ private final String key;
+
+ /**
+ * Constructor
+ * @param conf The configuration to which this pool belongs.
+ * @param pool The pointer to the native pool which this object wraps.
+ * @throws PoolsException If accessing the proxy fails.
+ */
+ Pool(Configuration conf, long pool) throws PoolsException
+ {
+ _conf = conf;
+ Value val = getProperty("pool.name", pool);
+ name = val.getString();
+ val.close();
+ key = "pool." + name;
+ }
+
+ /**
+ * Returns a pointer to the native pool represented by this
+ * pool object.
+ *
+ * @throws PoolsException If the pool cannot be located.
+ * @return a pointer to the native pool represented by this
+ * pool object.
+ */
+ long getPool() throws PoolsException
+ {
+ return (_conf.checkPool(name));
+ }
+
+ /**
+ * Associate this pool with the supplied resource.
+ *
+ * @param res A resource in the same configuration as this pool.
+ * @throws PoolsException If there is an error whilst associating the
+ * resource with the pool.
+ */
+ public void associate(Resource res) throws PoolsException
+ {
+ if (PoolInternal.pool_associate(_conf.getConf(), getPool(),
+ res.getResource()) != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Dissociate this pool from the supplied resource.
+ *
+ * @param res A resource in the same configuration as this pool.
+ * @throws PoolsException If there is an error whilst dissociating the
+ * resource from the pool.
+ */
+ public void dissociate(Resource res) throws PoolsException
+ {
+ if (PoolInternal.pool_dissociate(_conf.getConf(), getPool(),
+ res.getResource()) != PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a list of resources which match the supplied selection criteria
+ * in values. Only resources which are associated with this pool are
+ * searched.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of resources which match the supplied criteria
+ */
+ public List getResources(List values) throws PoolsException
+ {
+ List resources;
+
+ if ((resources = PoolInternal.pool_query_pool_resources(
+ _conf.getConf(), getPool(), values)) == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ ArrayList aList = new ArrayList(resources.size());
+ for (int i = 0; i < resources.size(); i++)
+ aList.add(new Resource(_conf,
+ ((Long)resources.get(i)).longValue()));
+ return (aList);
+ }
+
+ /**
+ * Returns a descriptive string which describes the pool.
+ *
+ * @param deep Whether the information should contain information about
+ * all contained elements.
+ * @throws PoolsException If the pool cannot be located.
+ * @return a descriptive string which describes the pool.
+ */
+ public String getInformation(int deep) throws PoolsException
+ {
+ return (PoolInternal.pool_info(_conf.getConf(), getPool(),
+ deep));
+ }
+
+ /**
+ * Returns a string representation of this pool.
+ *
+ * @return a string representation of this pool.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("pool: ");
+ buf.append(name);
+ return (buf.toString());
+ }
+
+ /**
+ * Indicates whether some other Pool is "equal to this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof Pool))
+ return (false);
+ Pool other = (Pool) o;
+ if (name.compareTo(other.getName()) != 0)
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (name.hashCode());
+ }
+
+ /**
+ * Return the pointer to this pool as an element.
+ *
+ * @return The pointer to the native pool which this object wraps.
+ * @throws PoolsExecption If there is an error converting the native
+ * pool pointer to a native elem pointer.
+ */
+ protected long getElem() throws PoolsException
+ {
+ long elem;
+
+ if ((elem = PoolInternal.pool_to_elem(_conf.getConf(),
+ getPool())) == 0)
+ throw new PoolsException();
+ return (elem);
+ }
+
+ /**
+ * Return the name of the pool.
+ */
+ String getName()
+ {
+ return (name);
+ }
+
+ /**
+ * Return the key of the pool.
+ */
+ String getKey()
+ {
+ return (key);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolInternal.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolInternal.java
new file mode 100644
index 0000000000..d230414070
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolInternal.java
@@ -0,0 +1,207 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.pools;
+
+/**
+ * A thin layer over the libpool(3LIB) interface so that Java can be
+ * used to manipulate resource pools. For more information on this
+ * facility refer to the manpage and the developer documentation.
+ *
+ * Most of the functionality in this class is not intended to be
+ * exposed to users of the package. The other classes in the package
+ * provide appropriate Java abstractions for using this functionality.
+ *
+ * Refer to the package documentation and the documentation of the
+ * other publicly visible classes for more details.
+ */
+public class PoolInternal {
+ static {
+ System.loadLibrary("jpool");
+ PoolInternal.init();
+ }
+
+ final static native void init();
+ final static native long pool_version(long ver);
+ final static native int get_POX_NATIVE();
+ final static native int get_POX_TEXT();
+ final static native int get_POC_INVAL();
+ final static native int get_POC_UINT();
+ final static native int get_POC_INT();
+ final static native int get_POC_DOUBLE();
+ final static native int get_POC_BOOL();
+ final static native int get_POC_STRING();
+ final static native int get_POV_NONE();
+ final static native int get_POV_LOOSE();
+ final static native int get_POV_STRICT();
+ final static native int get_POV_RUNTIME();
+ final static native int get_POF_INVALID();
+ final static native int get_POF_VALID();
+ final static native int get_POF_DESTROY();
+ public final static native int pool_error();
+ public final static native String pool_strerror(int error);
+ public final static native String pool_strerror_sys();
+ public final static native int pool_resource_type_list(long types,
+ long numtypes);
+ public final static native int pool_get_status(long state);
+ public final static native int pool_set_status(int state);
+ final static native long pool_conf_alloc();
+ final static native void pool_conf_free(long conf);
+ final static native int pool_conf_status(long conf);
+ final static native int pool_conf_close(long conf);
+ final static native int pool_conf_remove(long conf);
+ final static native int pool_conf_open(long conf, String location,
+ int oflags);
+ final static native int pool_conf_rollback(long conf);
+ final static native int pool_conf_commit(long conf, int active);
+ final static native int pool_conf_export(long conf, String location,
+ int fmt);
+ final static native int pool_conf_validate(long conf, int level);
+ final static native int pool_conf_update(long conf);
+ final static native long pool_get_pool(long conf, String name);
+ final static native java.util.List pool_query_pools(long conf,
+ java.util.List props);
+ final static native long pool_get_resource(long conf, String type,
+ String name);
+ final static native java.util.List pool_query_resources(long conf,
+ java.util.List props);
+ final static native java.util.List pool_query_components(long conf,
+ java.util.List props);
+ final static native String pool_conf_location(long conf);
+ final static native String pool_conf_info(long conf, int deep);
+ final static native long pool_resource_create(long conf,
+ String type, String name);
+ final static native int pool_resource_destroy(long conf, long res);
+ final static native int pool_resource_transfer(long conf,
+ long src, long tgt, long size);
+ final static native int pool_resource_xtransfer(long conf,
+ long src, long tgt, java.util.List components);
+ final static native java.util.List pool_query_resource_components(
+ long conf, long res, java.util.List props);
+ final static native String pool_resource_info(long conf, long res,
+ int deep);
+ final static native long pool_create(long conf, String name);
+ final static native int pool_destroy(long conf, long pool);
+ final static native int pool_associate(long conf, long pool,
+ long res);
+ final static native int pool_dissociate(long conf, long pool,
+ long res);
+ final static native String pool_info(long conf, long pool, int deep);
+ final static native java.util.List pool_query_pool_resources(
+ long conf, long pool, java.util.List props);
+ final static native long pool_get_owning_resource(long conf,
+ long comp);
+ final static native String pool_component_info(long conf,
+ long comp, int deep);
+ final static native int pool_get_property(long conf, long elem,
+ String name, long val);
+ final static native int pool_put_property(long conf, long elem,
+ String name, long val);
+ final static native int pool_rm_property(long conf, long elem,
+ String name);
+ final static native int pool_walk_properties(long conf, long elem,
+ long user, long callback);
+ final static native long pool_conf_to_elem(long conf);
+ final static native long pool_to_elem(long conf, long pool);
+ final static native long pool_resource_to_elem(long conf, long res);
+ final static native long pool_component_to_elem(long conf, long comp);
+ final static native int pool_value_get_uint64(long pv, long result);
+ final static native int pool_value_get_int64(long pv, long result);
+ final static native int pool_value_get_double(long pv, long result);
+ final static native int pool_value_get_bool(long pv, long result);
+ final static native int pool_value_get_string(long pv, long result);
+ final static native int pool_value_get_type(long pv);
+ final static native void pool_value_set_uint64(long pv, long val);
+ final static native void pool_value_set_int64(long pv, long val);
+ final static native void pool_value_set_double(long pv, double val);
+ final static native void pool_value_set_bool(long pv, short val);
+ final static native int pool_value_set_string(long pv, String val);
+ final static native String pool_value_get_name(long pv);
+ final static native int pool_value_set_name(long pv, String val);
+ final static native long pool_value_alloc();
+ final static native void pool_value_free(long pv);
+ public final static native String pool_static_location();
+ public final static native String pool_dynamic_location();
+ public final static native int pool_set_binding(String name,
+ int idtype, int id);
+ public final static native String pool_get_binding(int pid);
+ public final static native String pool_get_resource_binding(
+ String type, int pid);
+ final static native int pool_walk_pools(long conf, long user,
+ long callback);
+ final static native int pool_walk_resources(long conf, long pool,
+ long user, long callback);
+ final static native int pool_walk_components(long conf, long res,
+ long user, long callback);
+ /*
+ * enums and constants
+ */
+ public final static int POOL_VER_CURRENT = 1;
+ public final static int POOL_VER_NONE = 0;
+ public final static int PO_TRUE = 1;
+ public final static int PO_FALSE = 0;
+ public final static int PO_SUCCESS = 0;
+ public final static int PO_FAIL = -1;
+ public final static int POE_OK = 0;
+ public final static int POE_BAD_PROP_TYPE = 1;
+ public final static int POE_INVALID_CONF = 2;
+ public final static int POE_NOTSUP = 3;
+ public final static int POE_INVALID_SEARCH = 4;
+ public final static int POE_BADPARAM = 5;
+ public final static int POE_PUTPROP = 6;
+ public final static int POE_DATASTORE = 7;
+ public final static int POE_SYSTEM = 8;
+ public final static int POE_ACCESS = 9;
+ public final static int PO_RDONLY = 0x0;
+ public final static int PO_RDWR = 0x1;
+ public final static int PO_CREAT = 0x2;
+ public final static int PO_DISCO = 0x4;
+ public final static int PO_UPDATE = 0x8;
+ public final static String POA_IMPORTANCE = "importance based";
+ public final static String POA_SURPLUS_TO_DEFAULT =
+ "surplus to default";
+ public final static int POU_SYSTEM = 0x1;
+ public final static int POU_POOL = 0x2;
+ public final static int POU_PSET = 0x4;
+ public final static int POU_CPU = 0x8;
+ public final static int POX_NATIVE = get_POX_NATIVE();
+ public final static int POX_TEXT = get_POX_TEXT();
+ public final static int POC_INVAL = get_POC_INVAL();
+ public final static int POC_UINT = get_POC_UINT();
+ public final static int POC_INT = get_POC_INT();
+ public final static int POC_DOUBLE = get_POC_DOUBLE();
+ public final static int POC_BOOL = get_POC_BOOL();
+ public final static int POC_STRING = get_POC_STRING();
+ public final static int POV_NONE = get_POV_NONE();
+ public final static int POV_LOOSE = get_POV_LOOSE();
+ public final static int POV_STRICT = get_POV_STRICT();
+ public final static int POV_RUNTIME = get_POV_RUNTIME();
+ public final static int POF_INVALID = get_POF_INVALID();
+ public final static int POF_VALID = get_POF_VALID();
+ public final static int POF_DESTROY = get_POF_DESTROY();
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolsException.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolsException.java
new file mode 100644
index 0000000000..fa49e3952d
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PoolsException.java
@@ -0,0 +1,677 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.pools;
+
+/**
+ * The <code>PoolsException</code> class represents a pools error. It
+ * is used to report any errors in native code. See
+ * <code>errno(3C)</code> for information on the system (POE_SYSTEM)
+ * error codes.
+ */
+public class PoolsException extends Exception {
+ /**
+ * EPERM.
+ */
+ public static final int EPERM = 1;
+
+ /**
+ * ENOENT.
+ */
+ public static final int ENOENT = 2;
+
+ /**
+ * ESRCH.
+ */
+ public static final int ESRCH = 3;
+
+ /**
+ * EINTR.
+ */
+ public static final int EINTR = 4;
+
+ /**
+ * EIO.
+ */
+ public static final int EIO = 5;
+
+ /**
+ * ENXIO.
+ */
+ public static final int ENXIO = 6;
+
+ /**
+ * E2BIG.
+ */
+ public static final int E2BIG = 7;
+
+ /**
+ * ENOEXEC.
+ */
+ public static final int ENOEXEC = 8;
+
+ /**
+ * EBADF.
+ */
+ public static final int EBADF = 9;
+
+ /**
+ * ECHILD.
+ */
+ public static final int ECHILD = 10;
+
+ /**
+ * EAGAIN.
+ */
+ public static final int EAGAIN = 11;
+
+ /**
+ * ENOMEM.
+ */
+ public static final int ENOMEM = 12;
+
+ /**
+ * EACCES.
+ */
+ public static final int EACCES = 13;
+
+ /**
+ * EFAULT.
+ */
+ public static final int EFAULT = 14;
+
+ /**
+ * ENOTBLK.
+ */
+ public static final int ENOTBLK = 15;
+
+ /**
+ * EBUSY.
+ */
+ public static final int EBUSY = 16;
+
+ /**
+ * EEXIST.
+ */
+ public static final int EEXIST = 17;
+
+ /**
+ * EXDEV.
+ */
+ public static final int EXDEV = 18;
+
+ /**
+ * ENODEV.
+ */
+ public static final int ENODEV = 19;
+
+ /**
+ * ENOTDIR.
+ */
+ public static final int ENOTDIR = 20;
+
+ /**
+ * EISDIR.
+ */
+ public static final int EISDIR = 21;
+
+ /**
+ * EINVAL.
+ */
+ public static final int EINVAL = 22;
+
+ /**
+ * ENFILE.
+ */
+ public static final int ENFILE = 23;
+
+ /**
+ * EMFILE.
+ */
+ public static final int EMFILE = 24;
+
+ /**
+ * ENOTTY.
+ */
+ public static final int ENOTTY = 25;
+
+ /**
+ * ETXTBSY.
+ */
+ public static final int ETXTBSY = 26;
+
+ /**
+ * EFBIG.
+ */
+ public static final int EFBIG = 27;
+
+ /**
+ * ENOSPC.
+ */
+ public static final int ENOSPC = 28;
+
+ /**
+ * ESPIPE.
+ */
+ public static final int ESPIPE = 29;
+
+ /**
+ * EROFS.
+ */
+ public static final int EROFS = 30;
+
+ /**
+ * EMLINK.
+ */
+ public static final int EMLINK = 31;
+
+ /**
+ * EPIPE.
+ */
+ public static final int EPIPE = 32;
+
+ /**
+ * EDOM.
+ */
+ public static final int EDOM = 33;
+
+ /**
+ * ERANGE.
+ */
+ public static final int ERANGE = 34;
+
+ /**
+ * ENOMSG.
+ */
+ public static final int ENOMSG = 35;
+
+ /**
+ * EIDRM.
+ */
+ public static final int EIDRM = 36;
+
+ /**
+ * ECHRNG.
+ */
+ public static final int ECHRNG = 37;
+
+ /**
+ * EL2NSYNC.
+ */
+ public static final int EL2NSYNC = 38;
+
+ /**
+ * EL3HLT.
+ */
+ public static final int EL3HLT = 39;
+
+ /**
+ * EL3RST.
+ */
+ public static final int EL3RST = 40;
+
+ /**
+ * ELNRNG.
+ */
+ public static final int ELNRNG = 41;
+
+ /**
+ * EUNATCH.
+ */
+ public static final int EUNATCH = 42;
+
+ /**
+ * ENOCSI.
+ */
+ public static final int ENOCSI = 43;
+
+ /**
+ * EL2HLT.
+ */
+ public static final int EL2HLT = 44;
+
+ /**
+ * EDEADLK.
+ */
+ public static final int EDEADLK = 45;
+
+ /**
+ * ENOLCK.
+ */
+ public static final int ENOLCK = 46;
+
+ /**
+ * ECANCELED.
+ */
+ public static final int ECANCELED = 47;
+
+ /**
+ * ENOTSUP.
+ */
+ public static final int ENOTSUP = 48;
+
+ /**
+ * EDQUOT.
+ */
+ public static final int EDQUOT = 49;
+
+ /**
+ * EBADE.
+ */
+ public static final int EBADE = 50;
+
+ /**
+ * EBADR.
+ */
+ public static final int EBADR = 51;
+
+ /**
+ * EXFULL.
+ */
+ public static final int EXFULL = 52;
+
+ /**
+ * ENOANO.
+ */
+ public static final int ENOANO = 53;
+
+ /**
+ * EBADRQC.
+ */
+ public static final int EBADRQC = 54;
+
+ /**
+ * EBADSLT.
+ */
+ public static final int EBADSLT = 55;
+
+ /**
+ * EDEADLOCK.
+ */
+ public static final int EDEADLOCK = 56;
+
+ /**
+ * EBFONT.
+ */
+ public static final int EBFONT = 57;
+
+ /**
+ * EOWNERDEAD.
+ */
+ public static final int EOWNERDEAD = 58;
+
+ /**
+ * ENOTRECOVERABLE.
+ */
+ public static final int ENOTRECOVERABLE = 59;
+
+ /**
+ * ENOSTR.
+ */
+ public static final int ENOSTR = 60;
+
+ /**
+ * ENODATA.
+ */
+ public static final int ENODATA = 61;
+
+ /**
+ * ETIME.
+ */
+ public static final int ETIME = 62;
+
+ /**
+ * ENOSR.
+ */
+ public static final int ENOSR = 63;
+
+ /**
+ * ENONET.
+ */
+ public static final int ENONET = 64;
+
+ /**
+ * ENOPKG.
+ */
+ public static final int ENOPKG = 65;
+
+ /**
+ * EREMOTE.
+ */
+ public static final int EREMOTE = 66;
+
+ /**
+ * ENOLINK.
+ */
+ public static final int ENOLINK = 67;
+
+ /**
+ * EADV.
+ */
+ public static final int EADV = 68;
+
+ /**
+ * ESRMNT.
+ */
+ public static final int ESRMNT = 69;
+
+ /**
+ * ECOMM.
+ */
+ public static final int ECOMM = 70;
+
+ /**
+ * EPROTO.
+ */
+ public static final int EPROTO = 71;
+
+ /**
+ * ELOCKUNMAPPED.
+ */
+ public static final int ELOCKUNMAPPED = 72;
+
+ /**
+ * ENOTACTIVE.
+ */
+ public static final int ENOTACTIVE = 73;
+
+ /**
+ * EMULTIHOP.
+ */
+ public static final int EMULTIHOP = 74;
+
+ /**
+ * EBADMSG.
+ */
+ public static final int EBADMSG = 77;
+
+ /**
+ * ENAMETOOLONG.
+ */
+ public static final int ENAMETOOLONG = 78;
+
+ /**
+ * EOVERFLOW.
+ */
+ public static final int EOVERFLOW = 79;
+
+ /**
+ * ENOTUNIQ.
+ */
+ public static final int ENOTUNIQ = 80;
+
+ /**
+ * EBADFD.
+ */
+ public static final int EBADFD = 81;
+
+ /**
+ * EREMCHG.
+ */
+ public static final int EREMCHG = 82;
+
+ /**
+ * ELIBACC.
+ */
+ public static final int ELIBACC = 83;
+
+ /**
+ * ELIBBAD.
+ */
+ public static final int ELIBBAD = 84;
+
+ /**
+ * ELIBSCN.
+ */
+ public static final int ELIBSCN = 85;
+
+ /**
+ * ELIBMAX.
+ */
+ public static final int ELIBMAX = 86;
+
+ /**
+ * ELIBEXEC.
+ */
+ public static final int ELIBEXEC = 87;
+
+ /**
+ * EILSEQ.
+ */
+ public static final int EILSEQ = 88;
+
+ /**
+ * ENOSYS.
+ */
+ public static final int ENOSYS = 89;
+
+ /**
+ * ELOOP.
+ */
+ public static final int ELOOP = 90;
+
+ /**
+ * ERESTART.
+ */
+ public static final int ERESTART = 91;
+
+ /**
+ * ESTRPIPE.
+ */
+ public static final int ESTRPIPE = 92;
+
+ /**
+ * ENOTEMPTY.
+ */
+ public static final int ENOTEMPTY = 93;
+
+ /**
+ * EUSERS.
+ */
+ public static final int EUSERS = 94;
+
+ /**
+ * ENOTSOCK.
+ */
+ public static final int ENOTSOCK = 95;
+
+ /**
+ * EDESTADDRREQ.
+ */
+ public static final int EDESTADDRREQ = 96;
+
+ /**
+ * EMSGSIZE.
+ */
+ public static final int EMSGSIZE = 97;
+
+ /**
+ * EPROTOTYPE.
+ */
+ public static final int EPROTOTYPE = 98;
+
+ /**
+ * ENOPROTOOPT.
+ */
+ public static final int ENOPROTOOPT = 99;
+
+ /**
+ * EPROTONOSUPPORT.
+ */
+ public static final int EPROTONOSUPPORT = 120;
+
+ /**
+ * ESOCKTNOSUPPORT.
+ */
+ public static final int ESOCKTNOSUPPORT = 121;
+
+ /**
+ * EOPNOTSUPP.
+ */
+ public static final int EOPNOTSUPP = 122;
+
+ /**
+ * EPFNOSUPPORT.
+ */
+ public static final int EPFNOSUPPORT = 123;
+
+ /**
+ * EAFNOSUPPORT.
+ */
+ public static final int EAFNOSUPPORT = 124;
+
+ /**
+ * EADDRINUSE.
+ */
+ public static final int EADDRINUSE = 125;
+
+ /**
+ * EADDRNOTAVAIL.
+ */
+ public static final int EADDRNOTAVAIL = 126;
+
+ /**
+ * ENETDOWN.
+ */
+ public static final int ENETDOWN = 127;
+
+ /**
+ * ENETUNREACH.
+ */
+ public static final int ENETUNREACH = 128;
+
+ /**
+ * ENETRESET.
+ */
+ public static final int ENETRESET = 129;
+
+ /**
+ * ECONNABORTED.
+ */
+ public static final int ECONNABORTED = 130;
+
+ /**
+ * ECONNRESET.
+ */
+ public static final int ECONNRESET = 131;
+
+ /**
+ * ENOBUFS.
+ */
+ public static final int ENOBUFS = 132;
+
+ /**
+ * EISCONN.
+ */
+ public static final int EISCONN = 133;
+
+ /**
+ * ENOTCONN.
+ */
+ public static final int ENOTCONN = 134;
+
+ /**
+ * ESHUTDOWN.
+ */
+ public static final int ESHUTDOWN = 143;
+
+ /**
+ * ETOOMANYREFS.
+ */
+ public static final int ETOOMANYREFS = 144;
+
+ /**
+ * ETIMEDOUT.
+ */
+ public static final int ETIMEDOUT = 145;
+
+ /**
+ * ECONNREFUSED.
+ */
+ public static final int ECONNREFUSED = 146;
+
+ /**
+ * EHOSTDOWN.
+ */
+ public static final int EHOSTDOWN = 147;
+
+ /**
+ * EHOSTUNREACH.
+ */
+ public static final int EHOSTUNREACH = 148;
+
+ /**
+ * EALREADY.
+ */
+ public static final int EALREADY = 149;
+
+ /**
+ * EINPROGRESS.
+ */
+ public static final int EINPROGRESS = 150;
+
+ /**
+ * ESTALE.
+ */
+ public static final int ESTALE = 151;
+
+ private final int errorCode = PoolInternal.pool_error();
+
+ /**
+ * Constructor.
+ */
+ public PoolsException()
+ {
+ super(description(PoolInternal.pool_error()));
+ }
+
+ private static String description(int errorCode)
+ {
+ StringBuffer sb = new StringBuffer(PoolInternal.pool_strerror(
+ errorCode));
+ if (errorCode == PoolInternal.POE_SYSTEM)
+ sb.append(": " + PoolInternal.pool_strerror_sys());
+ return (sb.toString());
+ }
+
+ /**
+ * Returns the native pool error code.
+ *
+ * @return the native pool error code.
+ */
+ public int getCode()
+ {
+ return (errorCode);
+ }
+
+ /**
+ * Returns <code>errno</code>, if the pool error is
+ * <code>POE_SYSTEM</code>.
+ */
+ public native int getErrno();
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Property.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Property.java
new file mode 100644
index 0000000000..cf03d5835e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Property.java
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+/**
+ * The <code>Property</code> interface specifies the contract between
+ * a pools configuration element and it's properties. This interface
+ * must be implemented by all pools configuration elements to ensure that
+ * properties can be manipulated.
+ */
+
+public interface Property {
+ /**
+ * Get a property with the supplied name.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public boolean getBoolProperty(String name) throws PoolsException;
+
+ /**
+ * Get a property with the supplied name.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public double getDoubleProperty(String name) throws PoolsException;
+
+ /**
+ * Get a property with the supplied name.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public long getLongProperty(String name) throws PoolsException;
+
+ /**
+ * Get a property with the supplied name.
+ *
+ * @param name The name of the property to be retrieved.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public String getStringProperty(String name) throws PoolsException;
+
+ /**
+ * Put the supplied value as a property with the supplied name.
+ *
+ * @param name The name of the property to be updated.
+ * @param value The value of the property to be updated.
+ * @throws PoolsExecption If there is an error accessing the property.
+ */
+ public void putProperty(String name, Value value) throws PoolsException;
+
+ /**
+ * Remove the property with the supplied name.
+ *
+ * @param name The name of the property to be removed.
+ * @throws PoolsExecption If there is an error removing the property.
+ */
+ public void rmProperty(String name) throws PoolsException;
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PropertyWalk.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PropertyWalk.java
new file mode 100644
index 0000000000..82f29845e0
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/PropertyWalk.java
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The <code>PropertyWalk</code> interface specifies the contract
+ * between a pools configuration element and clients which are
+ * interested in enumerating the properties of the element.
+ */
+
+public interface PropertyWalk {
+ /**
+ * Walk all properties of the invoking object, calling the
+ *
+ * @param elem The element to whom the property belongs.
+ * @param val The value representing the current element.
+ * @param user User supplied data, provided when the walk is invoked.
+ * @throws PoolsExecption If there is an error walking the property.
+ * @return 0 to continue the walk, anything else to terminate it.
+ */
+ public int walk(Element elem, Value val, Object user)
+ throws PoolsException;
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Resource.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Resource.java
new file mode 100644
index 0000000000..babe05c015
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Resource.java
@@ -0,0 +1,251 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The <code>Resource</code> class represents a resource.
+ */
+public class Resource extends Element
+{
+ /**
+ * The type of the resource.
+ */
+ private final String type;
+ /**
+ * The system id of the resource.
+ */
+ private final String name;
+ /**
+ * The key of the resource.
+ */
+ private final String key;
+
+ /**
+ * Constructor
+ * @param conf The configuration to which this pool belongs.
+ * @param resource The pointer to the native resource which
+ * this object wraps.
+ * @throws PoolsException If accessing the proxy fails.
+ */
+ Resource(Configuration conf, long resource) throws PoolsException
+ {
+ _conf = conf;
+ Value val = getProperty("type", resource);
+ type = val.getString();
+ val.close();
+ val = getProperty(type + ".name", resource);
+ name = val.getString();
+ val.close();
+ key = type + "." + name;
+ }
+
+ /**
+ * Returns a pointer to the native resouce represented by this resource
+ * object.
+ *
+ * @throws PoolsException If the pool cannot be located.
+ * @return a pointer to the native resource represented by this
+ * resource object.
+ */
+ long getResource() throws PoolsException
+ {
+ return (_conf.checkResource(type, name));
+ }
+
+ /**
+ * Transfer the requested quantity of resource from the donor to this
+ * resource.
+ *
+ * @param donor A donating resource.
+ * @param qty Amount of resource to be donated.
+ * @throws PoolsException If there is an error whilst donating the
+ * resource.
+ */
+ public void transfer(Resource donor, long qty) throws PoolsException
+ {
+ if (PoolInternal.pool_resource_transfer(_conf.getConf(),
+ donor.getResource(), getResource(), qty) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Transfer the specified resource components from the donor to this
+ * resource.
+ *
+ * @param donor A donating resource.
+ * @param components A list of resource components to be donated.
+ * @throws PoolsException If there is an error whilst donating the
+ * resource components.
+ */
+ public void transfer(Resource donor, List components)
+ throws PoolsException
+ {
+ if (PoolInternal.pool_resource_xtransfer(_conf.getConf(),
+ donor.getResource(), getResource(), components) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Get a list of components which match the supplied selection
+ * criteria in values. Only components which are controlled by
+ * this resource are searched.
+ *
+ * @param values A list of values to be used to qualify the search.
+ * @throws PoolsExecption If there is an error executing the query.
+ * @return a list of components which match the supplied criteria
+ */
+ public List getComponents(List values) throws PoolsException
+ {
+ List components;
+
+ if ((components = PoolInternal.pool_query_resource_components(
+ _conf.getConf(), getResource(), values)) == null) {
+ if (PoolInternal.pool_error() == 0 ||
+ PoolInternal.pool_error() ==
+ PoolInternal.POE_INVALID_SEARCH)
+ return new ArrayList();
+ else
+ throw new PoolsException();
+ }
+ ArrayList aList = new ArrayList(components.size());
+ for (int i = 0; i < components.size(); i++)
+ aList.add(new Component(_conf,
+ ((Long)components.get(i)).longValue()));
+ return (aList);
+ }
+
+ /**
+ * Returns a descriptive string which describes the resource.
+ *
+ * @param deep Whether the information should contain information about
+ * all contained elements.
+ * @throws PoolsException If the resource cannot be located.
+ * @return a descriptive string which describes the resource.
+ */
+ public String getInformation(int deep) throws PoolsException
+ {
+ return (PoolInternal.pool_resource_info(_conf.getConf(),
+ getResource(), deep));
+ }
+
+ /**
+ * Returns a string representation of this resource.
+ *
+ * @return a string representation of this resource.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(type);
+ buf.append(" ");
+ buf.append(name);
+ return (buf.toString());
+ }
+
+ /**
+ * Indicates whether some other Resource is "equal to this one.
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the
+ * o argument; <code>false</code> otherwise.
+ * @see #hashCode()
+ */
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return (true);
+ if (!(o instanceof Resource))
+ return (false);
+ Resource other = (Resource) o;
+ if (type.compareTo(other.getType()) != 0 ||
+ name.compareTo(other.getName()) != 0)
+ return (false);
+ return (true);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hashtables such as those provided by
+ * <code>java.util.Hashtable</code>.
+ *
+ * @return a hash code value for this object.
+ * @see #equals(java.lang.Object)
+ * @see java.util.Hashtable
+ */
+ public int hashCode()
+ {
+ return (type.hashCode() + name.hashCode());
+ }
+
+ /**
+ * Return the pointer to this resource as an element.
+ *
+ * @return The pointer to the native resource which this object wraps.
+ * @throws PoolsExecption If there is an error converting the native
+ * resource pointer to a native elem pointer.
+ */
+ protected long getElem() throws PoolsException
+ {
+ long elem;
+
+ if ((elem = PoolInternal.pool_resource_to_elem(_conf.getConf(),
+ getResource())) == 0)
+ throw new PoolsException();
+ return (elem);
+ }
+
+ /**
+ * Return the type of the resource
+ */
+ String getType()
+ {
+ return (type);
+ }
+
+ /**
+ * Return the name of the resource.
+ */
+ String getName()
+ {
+ return (name);
+ }
+
+ /**
+ * Return the key of the resource.
+ */
+ String getKey()
+ {
+ return (key);
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/UnsignedInt64.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/UnsignedInt64.java
new file mode 100644
index 0000000000..bcf367854f
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/UnsignedInt64.java
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.pools;
+
+import java.math.BigInteger;
+
+public class UnsignedInt64 extends BigInteger {
+ /**
+ * The minimum value is 0.
+ */
+ public final static BigInteger MIN_VALUE = new BigInteger("0");
+
+ /**
+ * The maximum value is 18446744073709551615.
+ */
+ public final static BigInteger MAX_VALUE = new BigInteger(
+ "18446744073709551615");
+
+ /**
+ * Constructs a UnsignedInt64 with the same value as the given
+ * string, interpreted in base 10.
+ *
+ * @throws NumberFormatException if the given value is outside
+ * the representable range.
+ */
+ public UnsignedInt64(String string) throws NumberFormatException
+ {
+ super(string);
+ validate(this);
+ }
+
+ /**
+ * Constructs a UnsignedInt64 with the same value as the given
+ * string, interpreted in the given base.
+ *
+ * @throws NumberFormatException if the given value is outside
+ * the representable range.
+ */
+ public UnsignedInt64(String string, int radix)
+ throws NumberFormatException
+ {
+ super(string, radix);
+ validate(this);
+ }
+
+ /**
+ * Constructs a UnsignedInt64 with the same value as the given
+ * byte array, interpreted as a two's-complement number in
+ * big-endian byte order (the most significant byte has the
+ * lowest index).
+ *
+ * @throws NumberFormatException if the given value is outside
+ * the representable range.
+ */
+ public UnsignedInt64(byte[] bytes) throws NumberFormatException
+ {
+ super(bytes);
+ validate(this);
+ }
+
+ /**
+ * Constructs an UnsignedInt64 with the same value as the given
+ * BigInteger.
+ *
+ * @throws NumberFormatException if the given value is outside
+ * the representable range.
+ */
+ public UnsignedInt64(BigInteger value) throws NumberFormatException
+ {
+ super(value.toByteArray());
+ validate(this);
+ }
+
+ /**
+ * Check that the supplied parameter is a valid value for an
+ * UnsignedInt64.
+ *
+ * @param v A BigInteger to be checked if it's value is legal
+ * as an UnsignedInt64.
+ * @throws NumberFormatException if the given value is outside
+ * the representable range.
+ */
+ private void validate(BigInteger v)
+ {
+ if (v.compareTo(MIN_VALUE) < 0 || v.compareTo(MAX_VALUE) > 0)
+ throw(new NumberFormatException());
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Value.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Value.java
new file mode 100644
index 0000000000..938cdd9446
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/Value.java
@@ -0,0 +1,380 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ *ident "%Z%%M% %I% %E% SMI"
+ *
+ */
+
+package com.sun.solaris.service.pools;
+
+/**
+ * The <code>Value</code> class represents a pools value.
+ */
+public class Value {
+
+ private long _this;
+
+ /**
+ * Constructor. Only for use from native code.
+ * @param pointer A pointer to a C value.
+ */
+ private Value(long pointer)
+ {
+ _this = pointer;
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name) throws PoolsException
+ {
+ if ((_this = PoolInternal.pool_value_alloc()) == 0)
+ throw new PoolsException();
+ setName(name);
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @param value The value of the value.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name, long value) throws PoolsException
+ {
+ this(name);
+ setValue(value);
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @param value The value of the value.
+ * @param s Indicates if the value is signed or not.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name, long value, boolean s) throws PoolsException
+ {
+ this(name);
+ setValue(value, s);
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @param value The value of the value.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name, String value) throws PoolsException
+ {
+ this(name);
+ setValue(value);
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @param value The value of the value.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name, boolean value) throws PoolsException
+ {
+ this(name);
+ setValue(value);
+ }
+
+ /**
+ * Constructor
+ * @param name The name of the value.
+ * @param value The value of the value.
+ * @throws PoolsException If there is an error whilst
+ * allocating the value.
+ */
+ public Value(String name, double value) throws PoolsException
+ {
+ this(name);
+ setValue(value);
+ }
+
+ /**
+ * Explicitly reclaim the memory allocated for this value by
+ * the C proxy.
+ */
+ public void close()
+ {
+ if (_this != 0) {
+ PoolInternal.pool_value_free(_this);
+ _this = 0;
+ }
+ }
+
+ /**
+ * Reclaim the memory allocated for this value by the C
+ * proxy.
+ *
+ * @throws Throwable If freeing this configuration fails.
+ */
+ protected void finalize() throws Throwable
+ {
+ try
+ {
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Name this value.
+ *
+ * @param name The name to set for this value.
+ */
+ public void setName(String name)
+ {
+ PoolInternal.pool_value_set_name(_this, name);
+ }
+
+ /**
+ * Set this value to take the supplied signed long value.
+ *
+ * @param value The value to which this value should be set.
+ */
+ public void setValue(long value)
+ {
+ PoolInternal.pool_value_set_int64(_this, value);
+ }
+
+ /**
+ * Set this value to take the supplied long value.
+ *
+ * @param value The value to which this value should be set.
+ * @param s Is the value signed or unsigned.
+ */
+ public void setValue(long value, boolean s)
+ {
+ if (s)
+ setValue(value);
+ PoolInternal.pool_value_set_uint64(_this, value);
+ }
+
+ /**
+ * Set this value to take the supplied string value.
+ *
+ * @param value The value to which this value should be set.
+ * @throws PoolsExecption If the setting of the value fails.
+ */
+ public void setValue(String value) throws PoolsException
+ {
+ if (PoolInternal.pool_value_set_string(_this, value) !=
+ PoolInternal.PO_SUCCESS)
+ throw new PoolsException();
+ }
+
+ /**
+ * Set this value to take the supplied boolean value.
+ *
+ * @param value The value to which this value should be set.
+ */
+ public void setValue(boolean value)
+ {
+ if (value == true)
+ PoolInternal.pool_value_set_bool(_this, (short)1);
+ else
+ PoolInternal.pool_value_set_bool(_this, (short)0);
+ }
+
+ /**
+ * Set this value to take the supplied double value.
+ *
+ * @param value The value to which this value should be set.
+ */
+ public void setValue(double value)
+ {
+ PoolInternal.pool_value_set_double(_this, value);
+ }
+
+ /**
+ * Returns the name of the value.
+ *
+ * @return the name of the value.
+ */
+ public String getName()
+ {
+ return (PoolInternal.pool_value_get_name(_this));
+ }
+
+ /**
+ * Returns the pointer to the native value represented by this
+ * object.
+ *
+ * @return the pointer to the native value represented by this
+ * object.
+ */
+ public long getValue()
+ {
+ return (_this);
+ }
+
+ /**
+ * Returns the type of this object.
+ *
+ * @return the type of this object.
+ */
+ public int getType()
+ {
+ return (PoolInternal.pool_value_get_type(_this));
+ }
+
+ /**
+ * Returns a string representation of this value.
+ *
+ * @return a string representation of this value.
+ */
+ public String toString()
+ {
+ int type = PoolInternal.pool_value_get_type(_this);
+
+ try {
+ if (type == PoolInternal.POC_INT ||
+ type == PoolInternal.POC_UINT)
+ return (String.valueOf(getLong()));
+ if (type == PoolInternal.POC_STRING)
+ return getString();
+ if (type == PoolInternal.POC_BOOL)
+ return (String.valueOf(getBool()));
+ if (type == PoolInternal.POC_DOUBLE)
+ return (String.valueOf(getDouble()));
+ }
+ catch (PoolsException pe) {
+ return pe.toString();
+ }
+ return ""; /* Stop the compiler complaining */
+ }
+
+ /**
+ * Returns the value as a UnsignedInt64.
+ *
+ * @return the value as a UnsignedInt64.
+ * @throws PoolsException if the value is not an
+ * UnsignedInt64.
+ */
+ public final UnsignedInt64 getUnsignedInt64() throws PoolsException
+ {
+ return (getUnsignedInt64Value(_this));
+ }
+
+ /**
+ * Returns the value as a long.
+ *
+ * @return the value as a long.
+ * @throws PoolsException if the value is not a long.
+ */
+ public final long getLong() throws PoolsException
+ {
+ return (getLongValue(_this));
+ }
+
+ /**
+ * Returns the value as a String.
+ *
+ * @return the value as a String.
+ * @throws PoolsException if the value is not a String.
+ */
+ public final String getString() throws PoolsException
+ {
+ return (getStringValue(_this));
+ }
+
+ /**
+ * Returns the value as a boolean.
+ *
+ * @return the value as a boolean.
+ * @throws PoolsException if the value is not a boolean.
+ */
+ public final boolean getBool() throws PoolsException
+ {
+ return (getBoolValue(_this));
+ }
+
+ /**
+ * Returns the value as a double.
+ *
+ * @return the value as a double.
+ * @throws PoolsException if the value is not a double.
+ */
+ public final double getDouble() throws PoolsException
+ {
+ return (getDoubleValue(_this));
+ }
+
+ /**
+ * Returns the value as a UnsignedInt64.
+ *
+ * @param pointer the native value to be accessed.
+ * @return the value as a UnsignedInt64.
+ */
+ private final static native UnsignedInt64 getUnsignedInt64Value(
+ long pointer);
+
+ /**
+ * Returns the value as a long.
+ *
+ * @param pointer the native value to be accessed.
+ * @return the value as a long.
+ */
+ private final static native long getLongValue(long pointer);
+
+ /**
+ * Returns the value as a String.
+ *
+ * @param pointer the native value to be accessed.
+ * @return the value as a String.
+ */
+ private final static native String getStringValue(long pointer);
+
+ /**
+ * Returns the value as a boolean.
+ *
+ * @param pointer the native value to be accessed.
+ * @return the value as a boolean.
+ */
+ private final static native boolean getBoolValue(long pointer);
+
+ /**
+ * Returns the value as a double.
+ *
+ * @param pointer the native value to be accessed.
+ * @return the value as a double.
+ */
+ private final static native double getDoubleValue(long pointer);
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/package.html
new file mode 100644
index 0000000000..78951272b4
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/pools/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for manipulating Solaris Resource Pools.
+
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2000/136/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/administrative-support-processor-sets/">Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/Makefile b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/Makefile
new file mode 100644
index 0000000000..6515004cd9
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/Makefile
@@ -0,0 +1,48 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/com/sun/solaris/service/logging/Makefile
+
+include $(SRC)/cmd/Makefile.cmd
+
+CLASSPATH = $(SRC)/cmd/pools/poold
+JAVAFLAGS += -source 1.4
+
+SOURCE = RecurringEventTimer.java \
+ SimpleRecurringEventTimer.java
+
+all install: $(SOURCE:.java=.class)
+
+# Since more than one class file can be generated from a java source
+# file, any failure causes all class files to be removed.
+
+.FAILED: clean
+
+clean:
+ $(RM) *class
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/RecurringEventTimer.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/RecurringEventTimer.java
new file mode 100644
index 0000000000..4bfb7650d6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/RecurringEventTimer.java
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.timer;
+
+/**
+ * An interface for for a timer for handling a recurring event at a
+ * uniform period.
+ */
+public interface RecurringEventTimer
+{
+ public void waitUntilNextFiring() throws InterruptedException;
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/SimpleRecurringEventTimer.java b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/SimpleRecurringEventTimer.java
new file mode 100644
index 0000000000..558b6acf28
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/SimpleRecurringEventTimer.java
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * ident "%Z%%M% %I% %E% SMI"
+ */
+
+package com.sun.solaris.service.timer;
+
+/**
+ * A recurring event timer. Like all Java time consumers, which rely on
+ * wall time, adjustments to the time of day will adversely affect the
+ * accuracy of the period.
+ */
+public class SimpleRecurringEventTimer implements RecurringEventTimer
+{
+ /**
+ * Next time the event is to occur.
+ */
+ private long nextFiring;
+
+ /**
+ * Period between recurrences of the event, in milliseconds.
+ */
+ private long period;
+
+ /**
+ * Multiplier to convert seconds to milliseconds.
+ */
+ public static final int SEC = 1000;
+
+ /**
+ * Establishes a timer which will fire every 'period'
+ * milliseconds starting from now.
+ */
+ public SimpleRecurringEventTimer(long period)
+ {
+ this.period = period;
+ nextFiring = System.currentTimeMillis() + period;
+ }
+
+ /**
+ * Cause the current thread to wait until at least the time of
+ * the next event, as near as possible, unless interrupted.
+ *
+ * @throws InterruptedException if the thread is interrupted
+ * while waiting for the next firing. Subsequent calls to this
+ * method will wait for the same firing.
+ */
+ public void waitUntilNextFiring() throws InterruptedException
+ {
+ long delta;
+
+ while ((delta = nextFiring - System.currentTimeMillis()) > 0)
+ Thread.sleep(delta);
+
+ nextFiring += period;
+ }
+}
diff --git a/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/package.html b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/package.html
new file mode 100644
index 0000000000..59a925dc49
--- /dev/null
+++ b/usr/src/cmd/pools/poold/com/sun/solaris/service/timer/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License, Version 1.0 only
+ (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
+ ident "%Z%%M% %I% %E% SMI"
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes implementing timers suitable for use by a daemon.
+
+<h2>Package Specification</h2>
+
+<ul>
+ <li><a href="http://sac.eng.sun.com/arc/PSARC/2002/287/">PSARC Case Directory</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation,
+please see:
+<ul>
+ <li><a href="http://taxman.eng/projects/dynamic-resource-pools/">Dynamic Resource Pools Project Page</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/usr/src/cmd/pools/poold/libjkstat/Makefile b/usr/src/cmd/pools/poold/libjkstat/Makefile
new file mode 100644
index 0000000000..0e23e77ff5
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/Makefile
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/Makefile
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = spec .WAIT $(MACH)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+JNI_CLASSES = \
+ com.sun.solaris.service.kstat.Kstat \
+ com.sun.solaris.service.kstat.KstatCtl
+
+JNI_GENERATED_HEADERS = \
+ jkstat.h
+
+CLEANFILES += $(JNI_GENERATED_HEADERS)
+
+all install lint: $(JNI_GENERATED_HEADERS) .WAIT $(SUBDIRS)
+
+clean clobber: $(SUBDIRS)
+
+$(JNI_GENERATED_HEADERS): $(SRC)/cmd/pools/poold/JPool.jar
+ $(JAVAH) -classpath $? -o $@ $(JNI_CLASSES)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
+include $(SRC)/Makefile.msg.targ
diff --git a/usr/src/cmd/pools/poold/libjkstat/Makefile.com b/usr/src/cmd/pools/poold/libjkstat/Makefile.com
new file mode 100644
index 0000000000..a8871f0bc3
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/Makefile.com
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/Makefile.com
+#
+
+LIBRARY = libjkstat.a
+VERS = .1
+
+OBJECTS = jkstat.o
+
+include $(SRC)/lib/Makefile.lib
+
+INCS = -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+LIBS = $(DYNLIB)
+LDLIBS += -lkstat
+ROOTLIBDIR = $(ROOT)/usr/lib/pool
+SRCDIR = $(SRC)/cmd/pools/poold/libjkstat
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 $(INCS)
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/libjkstat/i386/Makefile b/usr/src/cmd/pools/poold/libjkstat/i386/Makefile
new file mode 100644
index 0000000000..0f84e63530
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/i386/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/i386/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/i386
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjkstat/jkstat.c b/usr/src/cmd/pools/poold/libjkstat/jkstat.c
new file mode 100644
index 0000000000..fb627ada48
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/jkstat.c
@@ -0,0 +1,421 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stddef.h>
+#include <kstat.h>
+
+#include "jkstat.h"
+
+/*
+ * Class descriptors
+ */
+#define DOUBLE_CLASS_DESC "java/lang/Double"
+#define LONG_CLASS_DESC "java/lang/Long"
+#define UI64_CLASS_DESC "com/sun/solaris/service/pools/UnsignedInt64"
+#define HRTIME_CLASS_DESC "com/sun/solaris/service/pools/HRTime"
+#define KSTAT_CLASS_DESC "com/sun/solaris/service/kstat/Kstat"
+#define KSTATCTL_CLASS_DESC "com/sun/solaris/service/kstat/KstatCtl"
+#define KSTAT_READ_EX_CLASS_DESC \
+ "com/sun/solaris/service/kstat/KstatReadException"
+#define KSTAT_TNS_EX_CLASS_DESC \
+ "com/sun/solaris/service/kstat/KstatTypeNotSupportedException"
+#define THROWABLE_CLASS_DESC "java/lang/Throwable"
+
+#define CLASS_FIELD_DESC(class_desc) "L" class_desc ";"
+
+/*
+ * Cached class, method, and field IDs.
+ */
+static jclass doubleclass;
+static jclass hrtimeclass;
+static jclass kstatclass;
+static jclass kstatctlclass;
+static jclass longclass;
+static jclass ui64class;
+static jfieldID kstat_kctl_fieldid;
+static jfieldID kstat_ksp_fieldid;
+static jfieldID kstatctl_kctl_fieldid;
+static jmethodID doublecons_mid;
+static jmethodID hrtimecons_mid;
+static jmethodID kstatcons_mid;
+static jmethodID longcons_mid;
+static jmethodID ui64cons_mid;
+
+static jobject
+makeUnsignedInt64(JNIEnv *env, uint64_t value)
+{
+ jobject valueObj;
+ jobject byteArray;
+ jbyte *bytes;
+ int i;
+
+ if (!(byteArray = (*env)->NewByteArray(env, 9)))
+ return (NULL); /* OutOfMemoryError thrown */
+ if (!(bytes = (*env)->GetByteArrayElements(env, byteArray, NULL)))
+ return (NULL); /* OutOfMemoryError thrown */
+
+ /*
+ * Interpret the uint64_t as a 9-byte big-endian signed quantity
+ * suitable for constructing an UnsignedInt64 or BigInteger.
+ */
+ for (i = 8; i >= 1; i--) {
+ bytes[i] = value & 0xff;
+ value >>= 8;
+ }
+ bytes[0] = 0;
+ (*env)->ReleaseByteArrayElements(env, byteArray, bytes, 0);
+
+ if (!(valueObj = (*env)->NewObject(env, ui64class, ui64cons_mid,
+ byteArray)))
+ return (NULL); /* exception thrown */
+
+ return (valueObj);
+}
+
+/*
+ * Return a Long object with the given value.
+ */
+static jobject
+makeLong(JNIEnv *env, jlong value)
+{
+ jobject valueObj;
+
+ if (!(valueObj = (*env)->NewObject(env, longclass, longcons_mid,
+ value)))
+ return (NULL); /* exception thrown */
+
+ return (valueObj);
+}
+
+/*
+ * Return a Double object with the given value.
+ */
+static jobject
+makeDouble(JNIEnv *env, jdouble value)
+{
+ jobject valueObj;
+
+ if (!(valueObj = (*env)->NewObject(env, doubleclass, doublecons_mid,
+ value)))
+ return (NULL); /* exception thrown */
+
+ return (valueObj);
+}
+
+/*
+ * Returns the kctl_t * from kstat_open(3kstat).
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_kstat_KstatCtl_open(JNIEnv *env, jobject obj)
+{
+ return ((jlong)(uintptr_t)kstat_open());
+}
+
+/*
+ * Invokes kstat_close(3kstat).
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_kstat_KstatCtl_close(JNIEnv *env, jobject obj,
+ jlong kctl)
+{
+ if (kctl)
+ return (kstat_close((kstat_ctl_t *)kctl));
+ else
+ return (0);
+}
+
+/*
+ * Invoke kstat_read(3kstat) for the given Kstat object.
+ */
+JNIEXPORT void JNICALL Java_com_sun_solaris_service_kstat_Kstat_read(
+ JNIEnv *env, jobject obj)
+{
+ kstat_ctl_t *kctl = ((kstat_ctl_t *)(*env)->GetLongField(env, obj,
+ kstat_kctl_fieldid));
+ kstat_t *ksp = ((kstat_t *)(*env)->GetLongField(env, obj,
+ kstat_ksp_fieldid));
+ kid_t kid;
+
+ if (!ksp || !kctl)
+ return; /* exception thronw */
+
+ kid = kstat_read((kstat_ctl_t *)kctl, (kstat_t *)ksp, NULL);
+ if (kid == -1) {
+ jclass e;
+ if (!(e = (*env)->FindClass(env, KSTAT_READ_EX_CLASS_DESC)))
+ return; /* exception thrown */
+
+ (*env)->Throw(env, (*env)->NewObject(env, e,
+ (*env)->GetStaticMethodID(env, e, "<init>",
+ "()" CLASS_FIELD_DESC(THROWABLE_CLASS_DESC))));
+ }
+}
+
+/*
+ * Return a Kstat object corresponding to the result of
+ * kstat_lookup(3kstat).
+ */
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_kstat_KstatCtl_lookup(JNIEnv *env, jobject obj,
+ jstring moduleObj, jint instance, jstring nameObj)
+{
+ const char *module = NULL;
+ const char *name = NULL;
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ jobject kstatObject = NULL;
+
+ if (moduleObj == NULL || nameObj == NULL)
+ return (NULL);
+
+ if (!(module = (*env)->GetStringUTFChars(env, moduleObj, NULL)))
+ goto done; /* exception thrown */
+ if (!(name = (*env)->GetStringUTFChars(env, nameObj, NULL)))
+ goto done; /* exception thrown */
+
+ kctl = (kstat_ctl_t *)(*env)->GetLongField(env, obj,
+ kstatctl_kctl_fieldid);
+ ksp = kstat_lookup(kctl, (char *)module, instance, (char *)name);
+ if (ksp)
+ kstatObject = (*env)->NewObject(env, kstatclass, kstatcons_mid,
+ (jlong)(uintptr_t)kctl, (jlong)(uintptr_t)ksp);
+
+done:
+ if (name)
+ (*env)->ReleaseStringUTFChars(env, nameObj, name);
+ if (module)
+ (*env)->ReleaseStringUTFChars(env, moduleObj, module);
+
+ return (kstatObject);
+}
+
+/*
+ * Returns the named value -- the value of the named kstat, or field in
+ * a raw kstat, as applicable, and available. Returns <i>null</i> if no
+ * such named kstat or field is available.
+ *
+ * Throws KstatTypeNotSupportedException if the raw kstat is not
+ * understood. (Presently, none are.)
+ */
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_kstat_Kstat_getValue(JNIEnv *env, jobject obj,
+ jstring nameObj)
+{
+ kstat_t *ksp = ((kstat_t *)(*env)->GetLongField(env, obj,
+ kstat_ksp_fieldid));
+ jobject valueObj = NULL;
+ kstat_named_t *ksnp;
+ const char *name;
+ jclass exceptionClass;
+
+ if (!nameObj)
+ return (NULL);
+
+ if (!(name = (*env)->GetStringUTFChars(env, nameObj, NULL)))
+ return (NULL); /* exception thrown */
+
+ if (!(exceptionClass = (*env)->FindClass(env,
+ KSTAT_TNS_EX_CLASS_DESC))) {
+ (*env)->ReleaseStringUTFChars(env, nameObj, name);
+ return (NULL); /* exception thrown */
+ }
+
+ switch (ksp->ks_type) {
+ case KSTAT_TYPE_NAMED:
+ ksnp = kstat_data_lookup(ksp, (char *)name);
+ if (ksnp == NULL)
+ break;
+ switch (ksnp->data_type) {
+ case KSTAT_DATA_CHAR:
+ valueObj = makeLong(env, ksnp->value.c[0]);
+ break;
+ case KSTAT_DATA_INT32:
+ valueObj = makeLong(env, ksnp->value.i32);
+ break;
+ case KSTAT_DATA_UINT32:
+ valueObj = makeLong(env, ksnp->value.ui32);
+ break;
+ case KSTAT_DATA_INT64:
+ valueObj = makeLong(env, ksnp->value.i64);
+ break;
+ case KSTAT_DATA_UINT64:
+ valueObj = makeUnsignedInt64(env, ksnp->value.ui64);
+ break;
+ case KSTAT_DATA_STRING:
+ valueObj = (*env)->NewStringUTF(env,
+ KSTAT_NAMED_STR_PTR(ksnp));
+ break;
+ case KSTAT_DATA_FLOAT:
+ valueObj = makeDouble(env, ksnp->value.f);
+ break;
+ case KSTAT_DATA_DOUBLE:
+ valueObj = makeDouble(env, ksnp->value.d);
+ break;
+ default:
+ goto fail;
+ }
+ break;
+ default:
+ goto fail;
+ }
+
+ (*env)->ReleaseStringUTFChars(env, nameObj, name);
+ return (valueObj);
+
+fail:
+ (*env)->ReleaseStringUTFChars(env, nameObj, name);
+ (*env)->Throw(env, (*env)->NewObject(env, exceptionClass,
+ (*env)->GetStaticMethodID(env, exceptionClass, "<init>",
+ "()" CLASS_FIELD_DESC(THROWABLE_CLASS_DESC))));
+
+ return (valueObj);
+}
+
+/*
+ * Given a Kstat object, return, as an HRTime object, its kstat_t's
+ * field at the given offset.
+ */
+static jobject
+ksobj_get_hrtime(JNIEnv *env, jobject obj, offset_t ksfieldoff)
+{
+ kstat_t *ksp = ((kstat_t *)(*env)->GetLongField(env, obj,
+ kstat_ksp_fieldid));
+
+ if (!ksp)
+ return (NULL); /* exception thrown */
+
+ return ((*env)->NewObject(env, hrtimeclass, hrtimecons_mid,
+ makeUnsignedInt64(env, *((hrtime_t *)ksp + ksfieldoff *
+ sizeof (hrtime_t)))));
+}
+
+/*
+ * Given a Kstat object, return as an HRTime object its ks_snaptime
+ * field.
+ */
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_kstat_Kstat_getSnapTime(JNIEnv *env, jobject obj)
+{
+ return (ksobj_get_hrtime(env, obj, offsetof(kstat_t, ks_snaptime)));
+}
+
+/*
+ * Given a Kstat object, return as an HRTime object its ks_crtime
+ * field.
+ */
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_kstat_Kstat_getCreationTime(JNIEnv *env,
+ jobject obj)
+{
+ return (ksobj_get_hrtime(env, obj, offsetof(kstat_t, ks_crtime)));
+}
+
+/*
+ * Invoke kstat_chain_update(3kstat) for the kstat chain corresponding
+ * to the given KstatCtl object.
+ */
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_kstat_KstatCtl_chainUpdate(JNIEnv *env,
+ jobject obj)
+{
+ kstat_ctl_t *kctl;
+
+ kctl = (kstat_ctl_t *)(*env)->GetLongField(env, obj,
+ kstatctl_kctl_fieldid);
+
+ (void) kstat_chain_update(kctl);
+}
+
+/*
+ * Cache class, method, and field IDs.
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_kstat_KstatCtl_init(JNIEnv *env, jclass clazz)
+{
+ jclass doubleclass_lref;
+ jclass hrtimeclass_lref;
+ jclass kstatclass_lref;
+ jclass kstatctlclass_lref;
+ jclass longclass_lref;
+ jclass ui64class_lref;
+
+ if (!(doubleclass_lref = (*env)->FindClass(env, DOUBLE_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(doubleclass = (*env)->NewGlobalRef(env, doubleclass_lref)))
+ return; /* exception thrown */
+ if (!(doublecons_mid = (*env)->GetMethodID(env, doubleclass, "<init>",
+ "(D)V")))
+ return; /* exception thrown */
+
+ if (!(hrtimeclass_lref = (*env)->FindClass(env, HRTIME_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(hrtimeclass = (*env)->NewGlobalRef(env, hrtimeclass_lref)))
+ return; /* exception thrown */
+ if (!(hrtimecons_mid = (*env)->GetMethodID(env, hrtimeclass, "<init>",
+ "(" CLASS_FIELD_DESC(UI64_CLASS_DESC) ")V")))
+ return; /* exception thrown */
+
+ if (!(kstatclass_lref = (*env)->FindClass(env, KSTAT_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(kstatclass = (*env)->NewGlobalRef(env, kstatclass_lref)))
+ return; /* exception thrown */
+ if (!(kstatcons_mid = (*env)->GetMethodID(env, kstatclass, "<init>",
+ "(JJ)V")))
+ return; /* exception thrown */
+ if (!(kstat_kctl_fieldid = (*env)->GetFieldID(env, kstatclass, "kctl",
+ "J")))
+ return; /* exception thrown */
+ if (!(kstat_ksp_fieldid = (*env)->GetFieldID(env, kstatclass, "ksp",
+ "J")))
+ return; /* exception thrown */
+
+ if (!(kstatctlclass_lref = (*env)->FindClass(env, KSTATCTL_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(kstatctlclass = (*env)->NewGlobalRef(env, kstatctlclass_lref)))
+ return; /* exception thrown */
+ if (!(kstatctl_kctl_fieldid = (*env)->GetFieldID(env, kstatctlclass,
+ "kctl", "J")))
+ return; /* exception thrown */
+
+ if (!(longclass_lref = (*env)->FindClass(env, LONG_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(longclass = (*env)->NewGlobalRef(env, longclass_lref)))
+ return; /* exception thrown */
+ if (!(longcons_mid = (*env)->GetMethodID(env, longclass, "<init>",
+ "(J)V")))
+ return; /* exception thrown */
+
+ if (!(ui64class_lref = (*env)->FindClass(env, UI64_CLASS_DESC)))
+ return; /* exception thrown */
+ if (!(ui64class = (*env)->NewGlobalRef(env, ui64class_lref)))
+ return; /* exception thrown */
+ ui64cons_mid = (*env)->GetMethodID(env, ui64class, "<init>", "([B)V");
+}
diff --git a/usr/src/cmd/pools/poold/libjkstat/sparc/Makefile b/usr/src/cmd/pools/poold/libjkstat/sparc/Makefile
new file mode 100644
index 0000000000..1350b66bcf
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/sparc/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/sparc/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/sparc
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/Makefile b/usr/src/cmd/pools/poold/libjkstat/spec/Makefile
new file mode 100644
index 0000000000..24a6d4bf52
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/Makefile
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/Makefile.targ b/usr/src/cmd/pools/poold/libjkstat/spec/Makefile.targ
new file mode 100644
index 0000000000..0d7392118f
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/Makefile.targ
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/Makefile.targ
+#
+
+.KEEP_STATE:
+
+LIBRARY = libjkstat.a
+VERS = .1
+
+OBJECTS = jkstat.o
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/amd64/Makefile b/usr/src/cmd/pools/poold/libjkstat/spec/amd64/Makefile
new file mode 100644
index 0000000000..1add7fe765
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/amd64/Makefile
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/i386/Makefile b/usr/src/cmd/pools/poold/libjkstat/spec/i386/Makefile
new file mode 100644
index 0000000000..4bd5775646
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/i386/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/jkstat.spec b/usr/src/cmd/pools/poold/libjkstat/spec/jkstat.spec
new file mode 100644
index 0000000000..55571135de
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/jkstat.spec
@@ -0,0 +1,101 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/jkstat.spec
+
+function Java_com_sun_solaris_service_kstat_KstatCtl_chainUpdate
+include "../../jkstat.h"
+declaration void \
+ Java_com_sun_solaris_service_kstat_KstatCtl_chainUpdate \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_KstatCtl_close
+include "../../jkstat.h"
+declaration int \
+ Java_com_sun_solaris_service_kstat_KstatCtl_close \
+ (JNIEnv *env, jobject obj, jlong kctl)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_KstatCtl_init
+include "../../jkstat.h"
+declaration void \
+ Java_com_sun_solaris_service_kstat_KstatCtl_init \
+ (JNIEnv *env, jclass clazz)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_KstatCtl_lookup
+include "../../jkstat.h"
+declaration jobject \
+ Java_com_sun_solaris_service_kstat_KstatCtl_lookup \
+ (JNIEnv *env, jobject obj, jstring moduleObj, \
+ jint instance, jstring nameObj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_KstatCtl_open
+include "../../jkstat.h"
+declaration jlong \
+ Java_com_sun_solaris_service_kstat_KstatCtl_open \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_Kstat_getCreationTime
+include "../../jkstat.h"
+declaration jobject \
+ Java_com_sun_solaris_service_kstat_Kstat_getCreationTime \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_Kstat_getSnapTime
+include "../../jkstat.h"
+declaration jobject \
+ Java_com_sun_solaris_service_kstat_Kstat_getSnapTime \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_Kstat_getValue
+include "../../jkstat.h"
+declaration jobject \
+ Java_com_sun_solaris_service_kstat_Kstat_getValue \
+ (JNIEnv *env, jobject obj, jstring nameObj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_kstat_Kstat_read
+include "../../jkstat.h"
+declaration void \
+ Java_com_sun_solaris_service_kstat_Kstat_read \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/sparc/Makefile b/usr/src/cmd/pools/poold/libjkstat/spec/sparc/Makefile
new file mode 100644
index 0000000000..c755776ae9
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/sparc/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/sparc/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/sparcv9/Makefile b/usr/src/cmd/pools/poold/libjkstat/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..304c1d6ef3
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/sparcv9/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec/sparcv9/Makefile
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/cmd/pools/poold/libjkstat/spec/versions b/usr/src/cmd/pools/poold/libjkstat/spec/versions
new file mode 100644
index 0000000000..9455f211e2
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjkstat/spec/versions
@@ -0,0 +1,36 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjkstat/spec versions
+#
+
+i386 {
+ SUNWprivate_1.1;
+}
+
+sparc {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/cmd/pools/poold/libjlgrp/Makefile b/usr/src/cmd/pools/poold/libjlgrp/Makefile
new file mode 100644
index 0000000000..a7d93d5174
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/Makefile
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/Makefile
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = spec .WAIT $(MACH)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+JNI_CLASSES = \
+ com.sun.solaris.service.locality.LocalityDomain \
+ com.sun.solaris.service.locality.LocalityGroup
+
+JNI_GENERATED_HEADERS = \
+ jlgrp.h
+
+CLEANFILES += $(JNI_GENERATED_HEADERS)
+
+all install lint: $(JNI_GENERATED_HEADERS) .WAIT $(SUBDIRS)
+
+clean clobber: $(SUBDIRS)
+
+$(JNI_GENERATED_HEADERS): $(SRC)/cmd/pools/poold/JPool.jar
+ $(JAVAH) -classpath $? -o $@ $(JNI_CLASSES)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
+include $(SRC)/Makefile.msg.targ
diff --git a/usr/src/cmd/pools/poold/libjlgrp/Makefile.com b/usr/src/cmd/pools/poold/libjlgrp/Makefile.com
new file mode 100644
index 0000000000..68ef5bf483
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/Makefile.com
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/Makefile.com
+#
+
+LIBRARY = libjlgrp.a
+VERS = .1
+
+OBJECTS = jlgrp.o
+
+include $(SRC)/lib/Makefile.lib
+
+INCS = -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+MAPFILE = $(MAPDIR)/mapfile
+
+LIBS = $(DYNLIB)
+LDLIBS += -llgrp -lc
+ROOTLIBDIR = $(ROOT)/usr/lib/pool
+SRCDIR = $(SRC)/cmd/pools/poold/libjlgrp
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 $(INCS)
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/libjlgrp/i386/Makefile b/usr/src/cmd/pools/poold/libjlgrp/i386/Makefile
new file mode 100644
index 0000000000..76ad708f5c
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/i386/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/i386/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/i386
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/jlgrp.c b/usr/src/cmd/pools/poold/libjlgrp/jlgrp.c
new file mode 100644
index 0000000000..8ec78b7cf6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/jlgrp.c
@@ -0,0 +1,250 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include <stdlib.h>
+#include <sys/lgrp_user.h>
+
+#include "jlgrp.h"
+
+static lgrp_cookie_t getCookie(JNIEnv *, jclass, jobject);
+static void throwException(JNIEnv *, const char *, const char *);
+
+/*
+ * Return the output of the getCookie() method executed on the
+ * supplied instance.
+ */
+lgrp_cookie_t
+getCookie(JNIEnv *env, jclass clazz, jobject obj)
+{
+ jfieldID fid;
+
+ fid = (*env)->GetFieldID(env, clazz, "cookie", "J");
+ return ((lgrp_cookie_t)(*env)->GetLongField(env, obj, fid));
+}
+
+/*
+ * Throw an exception of the specified class with the specified message.
+ */
+void
+throwException(JNIEnv *env, const char *class, const char *msg)
+{
+ jclass clazz;
+
+ clazz = (*env)->FindClass(env, class);
+
+ (*env)->ThrowNew(env, clazz, msg);
+}
+
+/*
+ * Obtain an lgrp cookie for an lgrp snapshot which contains details
+ * about available resources that the operating system knows about.
+ *
+ * If the call fails, then throw an exception which indicates that the
+ * snapshot could not be obtained.
+ */
+/*ARGSUSED1*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init(JNIEnv *env,
+ jobject obj, jint view)
+{
+ lgrp_cookie_t cookie;
+
+ if ((cookie = lgrp_init(view)) == LGRP_COOKIE_NONE) {
+ throwException(env, "java/lang/Exception",
+ "Could not obtain latency group cookie");
+ }
+
+ return ((jlong)cookie);
+}
+
+/*
+ * Release the snapshot in use by this instance. It is assumed that
+ * the cookie is held in the "cookie" field of the invoking instance
+ */
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini(JNIEnv *env,
+ jobject obj)
+{
+ jclass clazz;
+
+ clazz = (*env)->GetObjectClass(env, obj);
+ return ((jint)lgrp_fini(getCookie(env, clazz, obj)));
+}
+
+/*
+ * Create a new LocalityGroup object which acts as a proxy for the
+ * root LocalityGroup.
+ */
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root(JNIEnv *env,
+ jobject obj)
+{
+ jclass clazz;
+ jmethodID mid;
+ jlong root;
+ jobject lgrp;
+
+ clazz = (*env)->GetObjectClass(env, obj);
+
+ root = (jlong) lgrp_root(getCookie(env, clazz, obj));
+
+ clazz = (*env)->FindClass(env, "com/sun/solaris/service/locality/"
+ "LocalityGroup");
+ mid = (*env)->GetMethodID(env, clazz, "<init>", "(Lcom/sun/solaris/"
+ "service/locality/LocalityDomain;JLcom/sun/solaris/service/"
+ "locality/LocalityGroup;)V");
+ lgrp = (*env)->NewObject(env, clazz, mid, obj, root, NULL);
+ return (lgrp);
+}
+
+/*
+ * Return a new array containing all of the child LocalityGroup ids
+ * for the supplied instance.
+ */
+JNIEXPORT jlongArray JNICALL
+Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children(JNIEnv *env,
+ jobject obj)
+{
+ jclass clazz;
+ jfieldID fid;
+ lgrp_cookie_t cookie;
+ jlong id;
+ jsize nchild0, nchild;
+ jlongArray children;
+ int i;
+ lgrp_id_t *native_child;
+ jlong *java_child;
+ jobject domain;
+
+ clazz = (*env)->GetObjectClass(env, obj);
+ fid = (*env)->GetFieldID(env, clazz, "domain",
+ "Lcom/sun/solaris/service/locality/LocalityDomain;");
+ domain = (*env)->GetObjectField(env, obj, fid);
+
+ cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
+ fid = (*env)->GetFieldID(env, clazz, "id", "J");
+ id = (*env)->GetLongField(env, obj, fid);
+retry:
+ nchild0 = (jsize)lgrp_children(cookie, (lgrp_id_t)id, NULL, 0);
+ children = (*env)->NewLongArray(env, nchild0);
+ if ((native_child = calloc(nchild0, sizeof (lgrp_id_t))) == NULL) {
+ throwException(env, "java/lang/Exception",
+ "Could not allocate memory for native_child array");
+ return (NULL);
+ }
+ nchild = lgrp_children(cookie, (lgrp_id_t)id, native_child, nchild0);
+ if (nchild != nchild0) {
+ free(native_child);
+ goto retry;
+ }
+
+ if ((java_child = calloc(nchild, sizeof (jlong))) == NULL) {
+ throwException(env, "java/lang/Exception",
+ "Could not allocate memory for java_child array");
+ free(native_child);
+ return (NULL);
+ }
+
+ for (i = 0; i < nchild; i++)
+ java_child[i] = (jlong) native_child[i];
+ (*env)->SetLongArrayRegion(env, children, 0, nchild, java_child);
+ free(native_child);
+ free(java_child);
+ return (children);
+}
+
+/*
+ * Return a new array containing all of the cpus contained directly
+ * within the LocalityGroup identified by the supplied instance.
+ */
+JNIEXPORT jintArray JNICALL
+Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus(JNIEnv *env,
+ jobject obj)
+{
+ jclass clazz;
+ jfieldID fid;
+ lgrp_cookie_t cookie;
+ jlong id;
+ jsize ncpus0, ncpus;
+ jintArray cpus;
+ int i;
+ processorid_t *native_cpus;
+ jint *java_cpus;
+ jobject domain;
+
+ clazz = (*env)->GetObjectClass(env, obj);
+ fid = (*env)->GetFieldID(env, clazz, "domain",
+ "Lcom/sun/solaris/service/locality/LocalityDomain;");
+ domain = (*env)->GetObjectField(env, obj, fid);
+
+ cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
+
+ fid = (*env)->GetFieldID(env, clazz, "id", "J");
+ id = (*env)->GetLongField(env, obj, fid);
+retry:
+ ncpus0 = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
+ NULL, 0, LGRP_CONTENT_DIRECT);
+ cpus = (*env)->NewIntArray(env, ncpus0);
+ if ((native_cpus = calloc(ncpus0, sizeof (processorid_t))) == NULL) {
+ throwException(env, "java/lang/Exception",
+ "Could not allocate memory for native_cpus array");
+ return (NULL);
+ }
+ ncpus = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
+ native_cpus, ncpus0, LGRP_CONTENT_DIRECT);
+ if (ncpus != ncpus0) {
+ free(native_cpus);
+ goto retry;
+ }
+
+ if ((java_cpus = calloc(ncpus, sizeof (jint))) == NULL) {
+ free(native_cpus);
+ throwException(env, "java/lang/Exception",
+ "Could not allocate memory for java_cpus array");
+ return (NULL);
+ }
+
+ for (i = 0; i < ncpus; i++)
+ java_cpus[i] = (jint)native_cpus[i];
+ (*env)->SetIntArrayRegion(env, cpus, 0, ncpus, java_cpus);
+ free(native_cpus);
+ free(java_cpus);
+ return (cpus);
+}
+
+/*
+ * Return the latency between two supplied latency group IDs.
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency(JNIEnv *env,
+ jobject obj, jlong from, jlong to)
+{
+ return ((jint) lgrp_latency((lgrp_id_t)from, (lgrp_id_t)to));
+}
diff --git a/usr/src/cmd/pools/poold/libjlgrp/sparc/Makefile b/usr/src/cmd/pools/poold/libjlgrp/sparc/Makefile
new file mode 100644
index 0000000000..8dbc2500a1
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/sparc/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/sparc/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/sparc
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile b/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile
new file mode 100644
index 0000000000..a5107dd9f9
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/Makefile
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile.targ b/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile.targ
new file mode 100644
index 0000000000..48cdd9a230
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/Makefile.targ
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/Makefile.targ
+#
+
+.KEEP_STATE:
+
+LIBRARY = libjlgrp.a
+VERS = .1
+
+OBJECTS = jlgrp.o
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/amd64/Makefile b/usr/src/cmd/pools/poold/libjlgrp/spec/amd64/Makefile
new file mode 100644
index 0000000000..e827ac53f6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/amd64/Makefile
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/i386/Makefile b/usr/src/cmd/pools/poold/libjlgrp/spec/i386/Makefile
new file mode 100644
index 0000000000..f9d884b09f
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/i386/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/jlgrp.spec b/usr/src/cmd/pools/poold/libjlgrp/spec/jlgrp.spec
new file mode 100644
index 0000000000..81bc8189a6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/jlgrp.spec
@@ -0,0 +1,76 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/jlgrp.spec
+
+function Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini
+include "../../jlgrp.h"
+declaration jint \
+ Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init
+include "../../jlgrp.h"
+declaration jlong \
+ Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init \
+ (JNIEnv *env, jobject obj, jint view)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root
+include "../../jlgrp.h"
+declaration jobject \
+ Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children
+include "../../jlgrp.h"
+declaration jlongArray \
+ Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus
+include "../../jlgrp.h"
+declaration jintArray \
+ Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency
+include "../../jlgrp.h"
+declaration jint \
+ Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency \
+ (JNIEnv *env, jobject obj, jlong from, jlong to)
+version SUNWprivate_1.1
+end
+
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/sparc/Makefile b/usr/src/cmd/pools/poold/libjlgrp/spec/sparc/Makefile
new file mode 100644
index 0000000000..ae86fd7d13
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/sparc/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/sparc/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/sparcv9/Makefile b/usr/src/cmd/pools/poold/libjlgrp/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..da5f498611
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/sparcv9/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec/sparcv9/Makefile
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/cmd/pools/poold/libjlgrp/spec/versions b/usr/src/cmd/pools/poold/libjlgrp/spec/versions
new file mode 100644
index 0000000000..2d7d033084
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjlgrp/spec/versions
@@ -0,0 +1,36 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjlgrp/spec versions
+#
+
+i386 {
+ SUNWprivate_1.1;
+}
+
+sparc {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/cmd/pools/poold/libjpool/Makefile b/usr/src/cmd/pools/poold/libjpool/Makefile
new file mode 100644
index 0000000000..198a9ef241
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/Makefile
@@ -0,0 +1,65 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/Makefile
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = spec .WAIT $(MACH)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+JNI_CLASSES = \
+ com.sun.solaris.service.pools.PoolInternal \
+ com.sun.solaris.service.pools.Element \
+ com.sun.solaris.service.pools.Value \
+ com.sun.solaris.service.pools.HRTime
+
+JNI_GENERATED_HEADERS = \
+ jpool.h
+
+CLEANFILES += $(JNI_GENERATED_HEADERS)
+
+all install lint: $(JNI_GENERATED_HEADERS) .WAIT $(SUBDIRS)
+
+clean clobber: $(SUBDIRS)
+
+$(JNI_GENERATED_HEADERS): $(SRC)/cmd/pools/poold/JPool.jar
+ $(JAVAH) -classpath $? -o $@ $(JNI_CLASSES)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
+include $(SRC)/Makefile.msg.targ
diff --git a/usr/src/cmd/pools/poold/libjpool/Makefile.com b/usr/src/cmd/pools/poold/libjpool/Makefile.com
new file mode 100644
index 0000000000..3de6d694a5
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/Makefile.com
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/Makefile.com
+#
+
+LIBRARY = libjpool.a
+VERS = .1
+
+OBJECTS = jpool.o
+
+include $(SRC)/lib/Makefile.lib
+
+INCS = -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+MAPFILE = $(MAPDIR)/mapfile
+
+LIBS = $(DYNLIB)
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lpool -lc
+ROOTLIBDIR = $(ROOT)/usr/lib/pool
+SRCDIR = $(SRC)/cmd/pools/poold/libjpool
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 $(INCS)
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/libjpool/i386/Makefile b/usr/src/cmd/pools/poold/libjpool/i386/Makefile
new file mode 100644
index 0000000000..5540c23533
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/i386/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/i386/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/i386
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjpool/jpool.c b/usr/src/cmd/pools/poold/libjpool/jpool.c
new file mode 100644
index 0000000000..c2144a9297
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/jpool.c
@@ -0,0 +1,1759 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <errno.h>
+#include <jni.h>
+#include <pool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/time.h>
+
+#include "jpool.h"
+
+struct pool_callback {
+ jobject pc_user;
+ jobject pc_handler;
+ jobject pc_elem;
+ JNIEnv *pc_env;
+};
+
+static void throwException(JNIEnv *, const char *, const char *);
+static void throw_pe(JNIEnv *);
+static jobject makeUnsignedInt64(JNIEnv *, uint64_t);
+static int pool_property_walker(pool_conf_t *, pool_elem_t *p, const char *,
+ pool_value_t *, void *);
+static jobject copyArray(JNIEnv *, void **);
+
+/*
+ * Cached class, method, and field IDs.
+ */
+static jclass ui64class;
+static jmethodID ui64cons_mid;
+
+/*
+ * Throw an exception of the specified class with the specified message.
+ */
+void
+throwException(JNIEnv *env, const char *class, const char *msg)
+{
+ jclass clazz;
+
+ clazz = (*env)->FindClass(env, class);
+
+ (*env)->ThrowNew(env, clazz, msg);
+}
+
+/*
+ * Throw a PoolsException.
+ */
+void
+throw_pe(JNIEnv *jenv)
+{
+ jclass clazz;
+ jmethodID mid;
+ jthrowable throwObj;
+
+ clazz = (*jenv)->FindClass(jenv,
+ "com/sun/solaris/service/pools/PoolsException");
+ mid = (*jenv)->GetMethodID(jenv, clazz, "<init>", "()V");
+ throwObj = (*jenv)->NewObject(jenv, clazz, mid);
+ (*jenv)->Throw(jenv, throwObj);
+}
+
+/*
+ * Return an instance of an UnsignedInt64 class which encapsulates the
+ * supplied value.
+ */
+jobject
+makeUnsignedInt64(JNIEnv *env, uint64_t value)
+{
+ jobject valueObj;
+ jobject byteArray;
+ jbyte *bytes;
+ int i;
+
+ if (!(byteArray = (*env)->NewByteArray(env, 9)))
+ return (NULL); /* OutOfMemoryError thrown */
+ if (!(bytes = (*env)->GetByteArrayElements(env, byteArray, NULL)))
+ return (NULL); /* OutOfMemoryError thrown */
+
+ /*
+ * Interpret the uint64_t as a 9-byte big-endian signed quantity
+ * suitable for constructing an UnsignedInt64 or BigInteger.
+ */
+ for (i = 8; i >= 1; i--) {
+ bytes[i] = value & 0xff;
+ value >>= 8;
+ }
+ bytes[0] = 0;
+ (*env)->ReleaseByteArrayElements(env, byteArray, bytes, 0);
+
+ if (!(valueObj = (*env)->NewObject(env, ui64class, ui64cons_mid,
+ byteArray)))
+ return (NULL); /* exception thrown */
+
+ return (valueObj);
+}
+
+/*
+ * Create an array list and then copy the native array into it
+ */
+jobject
+copyArray(JNIEnv *jenv, void **nativeArray)
+{
+ int i;
+ jobject jresult = NULL;
+
+ if (nativeArray != NULL) {
+ jclass ALclazz;
+ jmethodID ALinit, ALadd;
+ jclass Lclazz;
+ jmethodID Linit;
+
+ ALclazz = (*jenv)->FindClass(jenv,
+ "java/util/ArrayList");
+ ALinit = (*jenv)->GetMethodID(jenv,
+ ALclazz, "<init>", "()V");
+ ALadd = (*jenv)->GetMethodID(jenv,
+ ALclazz, "add", "(Ljava/lang/Object;)Z");
+ jresult = (*jenv)->NewObject(jenv, ALclazz, ALinit);
+ Lclazz = (*jenv)->FindClass(jenv, "java/lang/Long");
+ Linit = (*jenv)->GetMethodID(jenv,
+ Lclazz, "<init>", "(J)V");
+ for (i = 0; nativeArray[i] != NULL; i++) {
+ jobject L;
+ /* Build longs and add them */
+ L = (*jenv)->NewObject(jenv,
+ Lclazz, Linit, (jlong)(uintptr_t)nativeArray[i]);
+ (*jenv)->CallBooleanMethod(jenv,
+ jresult, ALadd, L);
+ }
+ free(nativeArray);
+ }
+ return (jresult);
+}
+
+/*
+ * pool_version(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1version(JNIEnv *jenv,
+ jclass jcls, jlong jver) {
+ return ((jlong)pool_version((uint_t)jver));
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1NATIVE(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POX_NATIVE);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1TEXT(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POX_TEXT);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INVAL(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_INVAL);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1UINT(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_UINT);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INT(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_INT);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1DOUBLE(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_DOUBLE);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1BOOL(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_BOOL);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1STRING(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POC_STRING);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1NONE(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POV_NONE);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1LOOSE(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POV_LOOSE);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1STRICT(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POV_STRICT);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1RUNTIME(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POV_RUNTIME);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1INVALID(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POF_INVALID);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1VALID(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POF_VALID);
+}
+
+/*
+ * native constant accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1DESTROY(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)POF_DESTROY);
+}
+
+/*
+ * pool_error(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1error(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)pool_error());
+}
+
+/*
+ * pool_strerror(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror(JNIEnv *jenv,
+ jclass jcls, jint jperr) {
+ jstring jresult = NULL;
+ char *result;
+
+ result = (char *)pool_strerror((int)jperr);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * strerror(3c) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror_1sys(JNIEnv *
+ jenv, jclass jcls) {
+ jstring jresult = NULL;
+ char *result;
+
+ result = (char *)strerror(errno);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * errno(3c) accessor
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolsException_getErrno(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jint)errno);
+}
+
+/*
+ * pool_resource_type_list(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1type_1list(
+ JNIEnv *jenv, jclass jcls, jlong jreslist, jlong jnumres) {
+ char **reslist = (char **)jreslist;
+ uint_t *numres = (uint_t *)jnumres;
+
+ return ((jint)pool_resource_type_list((char const **)reslist, numres));
+}
+
+/*
+ * pool_get_status(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1status(JNIEnv *jenv,
+ jclass jcls, jlong jstatep) {
+ return ((jint)pool_get_status((int *)jstatep));
+}
+
+/*
+ * pool_set_status(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1status(JNIEnv *jenv,
+ jclass jcls, jint jstate) {
+ return ((jint)pool_set_status((int)jstate));
+}
+
+/*
+ * pool_conf_alloc(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1alloc(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jlong)(uintptr_t)pool_conf_alloc());
+}
+
+/*
+ * pool_conf_free(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1free(JNIEnv *jenv,
+ jclass jcls, jlong jconf) {
+ pool_conf_free((pool_conf_t *)jconf);
+}
+
+/*
+ * pool_conf_status(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1status(JNIEnv *jenv,
+ jclass jcls, jlong jconf) {
+ return ((jint)pool_conf_status((pool_conf_t *)jconf));
+}
+
+/*
+ * pool_conf_close(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1close(JNIEnv *jenv,
+ jclass jcls, jlong jconf) {
+ return ((jint)pool_conf_close((pool_conf_t *)jconf));
+}
+
+/*
+ * pool_conf_remove(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1remove(JNIEnv *jenv,
+ jclass jcls, jlong jconf) {
+ return ((jint)pool_conf_remove((pool_conf_t *)jconf));
+}
+
+/*
+ * pool_conf_open(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1open(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jstring jlocation, jint jflags) {
+ const char *location;
+ int result;
+
+ location = (jlocation) ? (*jenv)->GetStringUTFChars(jenv,
+ jlocation, 0) : NULL;
+ result = (int)pool_conf_open((pool_conf_t *)jconf, location,
+ (int)jflags);
+
+ if (location)
+ (*jenv)->ReleaseStringUTFChars(jenv, jlocation, location);
+ return ((jint)result);
+}
+
+/*
+ * pool_conf_rollback(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1rollback(
+ JNIEnv *jenv, jclass jcls, jlong jconf) {
+ return ((jint)pool_conf_rollback((pool_conf_t *)jconf));
+}
+
+/*
+ * pool_conf_commit(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1commit(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jint jactive) {
+ return ((jint)pool_conf_commit((pool_conf_t *)jconf, (int)jactive));
+}
+
+/*
+ * pool_conf_export(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1export(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jstring jlocation, jint jformat) {
+ const char *location;
+ int result;
+
+ location = (jlocation) ? (*jenv)->GetStringUTFChars(jenv,
+ jlocation, 0) : NULL;
+ result = (int)pool_conf_export((pool_conf_t *)jconf,
+ location, (pool_export_format_t)jformat);
+
+ if (location)
+ (*jenv)->ReleaseStringUTFChars(jenv, jlocation, location);
+ return ((jint)result);
+}
+
+/*
+ * pool_conf_validate(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1validate(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jint jlevel) {
+ return ((jint)pool_conf_validate((pool_conf_t *)jconf,
+ (pool_valid_level_t)jlevel));
+}
+
+/*
+ * pool_conf_update(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1update(JNIEnv *jenv,
+ jclass jcls, jlong jconf) {
+ int changed;
+ int result;
+
+ result = pool_conf_update((pool_conf_t *)jconf, &changed);
+
+ if (result != PO_SUCCESS) {
+ throw_pe(jenv);
+ }
+
+ return ((jint)changed);
+}
+
+/*
+ * pool_get_pool(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1pool(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jstring jname) {
+ const char *name;
+ pool_t *result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) :
+ NULL;
+ result = (pool_t *)pool_get_pool((pool_conf_t *)jconf, name);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jlong)(uintptr_t)result);
+}
+
+/*
+ * pool_query_pools(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pools(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jobject jprops) {
+ pool_value_t **props;
+ pool_t **result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ jint size;
+ uint_t nelem;
+ int i;
+
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ props = NULL;
+ if (jprops != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jprops);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jprops, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+
+ Lget = (*jenv)->GetMethodID(jenv, Lclazz, "get",
+ "(I)Ljava/lang/Object;");
+ /*
+ * Allocate space for the props array
+ */
+
+ if ((props = calloc(size + 1, sizeof (pool_value_t *)))
+ == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate props array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jfieldID Vthis;
+ jlong this;
+
+ aVal = (*jenv)->CallObjectMethod(jenv, jprops,
+ Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv, aVal);
+ Vthis = (*jenv)->GetFieldID(jenv, Vclazz,
+ "_this", "J");
+ this = (*jenv)->GetLongField(jenv, aVal, Vthis);
+ props[i] = (pool_value_t *)this;
+ }
+ }
+ }
+ result = pool_query_pools((pool_conf_t *)jconf, &nelem,
+ props);
+ free(props);
+ return (copyArray(jenv, (void **)result));
+}
+
+/*
+ * pool_get_resource(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jstring jtype, jstring jname) {
+ const char *type;
+ const char *name;
+ pool_resource_t *result;
+
+ type = (jtype) ? (*jenv)->GetStringUTFChars(jenv, jtype, 0) :
+ NULL;
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) :
+ NULL;
+ result = pool_get_resource((pool_conf_t *)jconf, type, name);
+
+ if (type)
+ (*jenv)->ReleaseStringUTFChars(jenv, jtype, type);
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jlong)(uintptr_t)result);
+}
+
+/*
+ * pool_query_resources(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resources(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jobject jprops) {
+ pool_value_t **props;
+ pool_resource_t **result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ jint size;
+ uint_t nelem;
+ int i;
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ props = NULL;
+ if (jprops != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jprops);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jprops, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+
+ Lget = (*jenv)->GetMethodID(jenv, Lclazz, "get",
+ "(I)Ljava/lang/Object;");
+ /*
+ * Allocate space for the props array
+ */
+ if ((props = calloc(size + 1, sizeof (pool_value_t *)))
+ == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate props array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jfieldID Vthis;
+ jlong this;
+
+
+ aVal = (*jenv)->CallObjectMethod(jenv, jprops,
+ Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv, aVal);
+ Vthis = (*jenv)->GetFieldID(jenv, Vclazz,
+ "_this", "J");
+ this = (*jenv)->GetLongField(jenv, aVal, Vthis);
+ props[i] = (pool_value_t *)this;
+ }
+ }
+ }
+ result = pool_query_resources((pool_conf_t *)jconf, &nelem,
+ props);
+ free(props);
+ return (copyArray(jenv, (void *)result));
+}
+
+/*
+ * pool_query_components(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1components(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jobject jprops) {
+ pool_value_t **props;
+ pool_component_t **result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ jint size;
+ uint_t nelem;
+ int i;
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ props = NULL;
+ if (jprops != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jprops);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jprops, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+
+ Lget = (*jenv)->GetMethodID(jenv, Lclazz, "get",
+ "(I)Ljava/lang/Object;");
+ /*
+ * Allocate space for the props array
+ */
+
+ if ((props = calloc(size + 1, sizeof (pool_value_t *)))
+ == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate props array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jfieldID Vthis;
+ jlong this;
+
+ aVal = (*jenv)->CallObjectMethod(jenv, jprops,
+ Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv, aVal);
+ Vthis = (*jenv)->GetFieldID(jenv, Vclazz,
+ "_this", "J");
+ this = (*jenv)->GetLongField(jenv, aVal, Vthis);
+ props[i] = (pool_value_t *)this;
+ }
+ }
+ }
+ result = pool_query_components((pool_conf_t *)jconf, &nelem,
+ props);
+ free(props);
+ return (copyArray(jenv, (void **)result));
+}
+
+/*
+ * pool_conf_location(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1location(
+ JNIEnv *jenv, jclass jcls, jlong jconf) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_conf_location((pool_conf_t *)jconf);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * pool_conf_info(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1info(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jint jflags) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_conf_info((pool_conf_t *)jconf, (int)jflags);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ return (jresult);
+}
+
+/*
+ * pool_resource_create(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1create(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jstring jtype, jstring jname) {
+ const char *type;
+ const char *name;
+ pool_resource_t *result;
+
+ type = (jtype) ? (*jenv)->GetStringUTFChars(jenv, jtype, 0) :
+ NULL;
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) :
+ NULL;
+ result = pool_resource_create((pool_conf_t *)jconf, type, name);
+
+ if (type)
+ (*jenv)->ReleaseStringUTFChars(jenv, jtype, type);
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jlong)(uintptr_t)result);
+}
+
+/*
+ * pool_resource_destroy(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1destroy(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource) {
+ return ((jint)pool_resource_destroy((pool_conf_t *)jconf,
+ (pool_resource_t *)jresource));
+}
+
+/*
+ * pool_resource_transfer(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1transfer(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jsource, jlong jtarget,
+ jlong jsize) {
+ return (pool_resource_transfer((pool_conf_t *)jconf,
+ (pool_resource_t *)jsource, (pool_resource_t *)jtarget,
+ (uint64_t)jsize));
+}
+
+/*
+ * pool_resource_xtransfer(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1xtransfer(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jsource, jlong jtarget,
+ jobject jcomponents) {
+ pool_component_t **components;
+ int result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ jint size;
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ components = NULL;
+ if (jcomponents != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jcomponents);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jcomponents, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+ int i;
+
+ Lget = (*jenv)->GetMethodID(jenv,
+ Lclazz, "get", "(I)Ljava/lang/Object;");
+ /* Allocate space for the components array */
+
+ if ((components = calloc(size + 1,
+ sizeof (pool_component_t *))) == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate component array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jlong this;
+ jmethodID Vthis;
+
+ aVal = (*jenv)->CallObjectMethod(jenv,
+ jcomponents, Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv,
+ aVal);
+ Vthis = (*jenv)->GetMethodID(jenv,
+ Vclazz, "getComponent", "()J");
+ this = (*jenv)->CallLongMethod(jenv,
+ aVal, Vthis);
+ components[i] = (pool_component_t *)this;
+ }
+ }
+ }
+ result = (int)pool_resource_xtransfer((pool_conf_t *)jconf,
+ (pool_resource_t *)jsource, (pool_resource_t *)jtarget,
+ components);
+ free(components);
+
+ return ((jint)result);
+}
+
+/*
+ * pool_query_resource_components(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resource_\
+1components(JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource,
+ jobject jprops) {
+ pool_value_t **props;
+ pool_component_t **result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ uint_t nelem;
+ jint size;
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ props = NULL;
+ if (jprops != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jprops);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jprops, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+ int i;
+
+ Lget = (*jenv)->GetMethodID(jenv, Lclazz, "get",
+ "(I)Ljava/lang/Object;");
+ /*
+ * Allocate space for the props array
+ */
+ if ((props = calloc(size + 1, sizeof (pool_value_t *)))
+ == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate props array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jfieldID Vthis;
+ jlong this;
+
+ aVal = (*jenv)->CallObjectMethod(jenv, jprops,
+ Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv, aVal);
+ Vthis = (*jenv)->GetFieldID(jenv, Vclazz,
+ "_this", "J");
+ this = (*jenv)->GetLongField(jenv, aVal, Vthis);
+ props[i] = (pool_value_t *)this;
+ }
+ }
+ }
+ result = pool_query_resource_components((pool_conf_t *)jconf,
+ (pool_resource_t *)jresource, &nelem, props);
+ free(props);
+ return (copyArray(jenv, (void **)result));
+}
+
+/*
+ * pool_resource_info(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1info(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource, jint jflags) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = (char *)pool_resource_info((pool_conf_t *)jconf,
+ (pool_resource_t *)jresource, (int)jflags);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ return (jresult);
+}
+
+/*
+ * pool_create(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1create(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jstring jname) {
+ const char *name;
+ pool_t *result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) :
+ NULL;
+ result = pool_create((pool_conf_t *)jconf, name);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jlong)(uintptr_t)result);
+}
+
+/*
+ * pool_destroy(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1destroy(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jpool) {
+ return ((jint)pool_destroy((pool_conf_t *)jconf, (pool_t *)jpool));
+}
+
+/*
+ * pool_associate(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1associate(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jpool, jlong jresource) {
+ return ((jint)pool_associate((pool_conf_t *)jconf, (pool_t *)jpool,
+ (pool_resource_t *)jresource));
+}
+
+/*
+ * pool_dissociate(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1dissociate(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jpool, jlong jresource) {
+ return ((jint)pool_dissociate((pool_conf_t *)jconf, (pool_t *)jpool,
+ (pool_resource_t *)jresource));
+}
+
+/*
+ * pool_info(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1info(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jpool, jint jflags) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_info((pool_conf_t *)jconf,
+ (pool_t *)jpool, (int)jflags);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ return (jresult);
+}
+
+/*
+ * pool_query_pool_resources(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pool_1resources(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, jobject jprops) {
+ pool_value_t **props;
+ pool_resource_t **result;
+ jclass Lclazz;
+ jmethodID Lsize;
+ uint_t nelem;
+ jint size;
+
+ /*
+ * Initialize the target parameter for case when input is null
+ */
+ props = NULL;
+ if (jprops != NULL) {
+ Lclazz = (*jenv)->GetObjectClass(jenv, jprops);
+ Lsize = (*jenv)->GetMethodID(jenv, Lclazz, "size", "()I");
+ size = (*jenv)->CallIntMethod(jenv, jprops, Lsize);
+
+ if (size != 0) {
+ jmethodID Lget;
+ int i;
+
+ Lget = (*jenv)->GetMethodID(jenv,
+ Lclazz, "get", "(I)Ljava/lang/Object;");
+ /*
+ * Allocate space for the props array
+ */
+
+ if ((props = calloc(size + 1, sizeof (pool_value_t *)))
+ == NULL) {
+ throwException(jenv, "java/lang/Exception",
+ "Could not allocate props array");
+ return (NULL);
+ }
+ /*
+ * Copy in the array
+ */
+ for (i = 0; i < size; i++) {
+ jobject aVal;
+ jclass Vclazz;
+ jfieldID Vthis;
+ jlong this;
+
+ aVal = (*jenv)->CallObjectMethod(jenv, jprops,
+ Lget, (jint) i);
+ Vclazz = (*jenv)->GetObjectClass(jenv, aVal);
+ Vthis = (*jenv)->GetFieldID(jenv, Vclazz,
+ "_this", "J");
+ this = (*jenv)->GetLongField(jenv, aVal, Vthis);
+ props[i] = (pool_value_t *)this;
+ }
+ }
+ }
+ result = pool_query_pool_resources((pool_conf_t *)jconf,
+ (pool_t *)jpool, &nelem, props);
+ free(props);
+ return (copyArray(jenv, (void **)result));
+}
+
+/*
+ * pool_get_owning_resource(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1owning_1resource(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent) {
+ return ((jlong)(uintptr_t)pool_get_owning_resource((pool_conf_t *)jconf,
+ (pool_component_t *)jcomponent));
+}
+
+/*
+ * pool_component_info(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1info(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent, jint jflags) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_component_info((pool_conf_t *)jconf,
+ (pool_component_t *)jcomponent, (int)jflags);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ return (jresult);
+}
+
+/*
+ * pool_get_property(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1property(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, jstring jname,
+ jlong jproperty) {
+ const char *name;
+ int result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) :
+ NULL;
+ result = pool_get_property((pool_conf_t *)jconf,
+ (pool_elem_t *)jelem, name, (pool_value_t *)jproperty);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jint)result);
+}
+
+/*
+ * pool_put_property(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1put_1property(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, jstring jname,
+ jlong jvalue) {
+ const char *name;
+ int result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) : NULL;
+ result = (int)pool_put_property((pool_conf_t *)jconf,
+ (pool_elem_t *)jelem, name, (pool_value_t *)jvalue);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jint)result);
+}
+
+/*
+ * pool_rm_property(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1rm_1property(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jelem, jstring jname) {
+ const char *name;
+ int result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) : NULL;
+ result = pool_rm_property((pool_conf_t *)jconf, (pool_elem_t *)jelem,
+ name);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jint)result);
+}
+
+/*
+ * pool_walk_properties(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1properties(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, jlong jarg,
+ jlong jcallback) {
+ int result;
+
+ result = (int)pool_walk_properties((pool_conf_t *)jconf,
+ (pool_elem_t *)jelem, (void *)jarg,
+ (int (*)(pool_conf_t *, pool_elem_t *, char const *,
+ pool_value_t *, void *))jcallback);
+
+ return ((jint)result);
+}
+
+/*
+ * pool_conf_to_elem(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1to_1elem(
+ JNIEnv *jenv, jclass jcls, jlong jconf) {
+ return ((jlong)(uintptr_t)pool_conf_to_elem((pool_conf_t *)jconf));
+}
+
+/*
+ * pool_to_elem(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1to_1elem(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jpool) {
+ return ((jlong)(uintptr_t)pool_to_elem((pool_conf_t *)jconf,
+ (pool_t *)jpool));
+}
+
+/*
+ * pool_resource_to_elem(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1to_1elem(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource) {
+ return ((jlong)(uintptr_t)pool_resource_to_elem((pool_conf_t *)jconf,
+ (pool_resource_t *)jresource));
+}
+
+/*
+ * pool_component_to_elem(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1to_1elem(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent) {
+ return ((jlong)(uintptr_t)pool_component_to_elem((pool_conf_t *)jconf,
+ (pool_component_t *)jcomponent));
+}
+
+/*
+ * pool_value_get_type(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1type(
+ JNIEnv *jenv, jclass jcls, jlong jvalue) {
+ return ((jint)pool_value_get_type((pool_value_t *)jvalue));
+}
+
+/*
+ * pool_value_set_uint64(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1uint64(
+ JNIEnv *jenv, jclass jcls, jlong jvalue, jlong jui64) {
+ pool_value_set_uint64((pool_value_t *)jvalue, (uint64_t)jui64);
+}
+
+/*
+ * pool_value_set_int64(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1int64(
+ JNIEnv *jenv, jclass jcls, jlong jvalue, jlong ji64) {
+ pool_value_set_int64((pool_value_t *)jvalue, (int64_t)ji64);
+}
+
+/*
+ * pool_value_set_double(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1double(
+ JNIEnv *jenv, jclass jcls, jlong jvalue, jdouble jd) {
+ pool_value_set_double((pool_value_t *)jvalue, (double)jd);
+}
+
+/*
+ * pool_value_set_bool(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1bool(
+ JNIEnv *jenv, jclass jcls, jlong jvalue, jshort jb) {
+ pool_value_set_bool((pool_value_t *)jvalue, (uchar_t)jb);
+}
+
+/*
+ * pool_value_set_string(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1string(
+ JNIEnv * jenv, jclass jcls, jlong jvalue, jstring jstr) {
+ const char *str;
+ int result;
+
+ str = (jstr) ? (*jenv)->GetStringUTFChars(jenv, jstr, 0) : NULL;
+ result = pool_value_set_string((pool_value_t *)jvalue, str);
+
+ if (str)
+ (*jenv)->ReleaseStringUTFChars(jenv, jstr, str);
+ return ((jint)result);
+}
+
+/*
+ * pool_value_get_name(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1name(
+ JNIEnv *jenv, jclass jcls, jlong jvalue) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_value_get_name((pool_value_t *)jvalue);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * pool_value_set_name(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1name(
+ JNIEnv *jenv, jclass jcls, jlong jvalue, jstring jname) {
+ const char *name;
+ int result;
+
+ name = (jname) ? (*jenv)->GetStringUTFChars(jenv, jname, 0) : NULL;
+ result = pool_value_set_name((pool_value_t *)jvalue, name);
+
+ if (name)
+ (*jenv)->ReleaseStringUTFChars(jenv, jname, name);
+ return ((jint)result);
+}
+
+/*
+ * pool_value_alloc(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1alloc(JNIEnv *jenv,
+ jclass jcls) {
+ return ((jlong)(uintptr_t)pool_value_alloc());
+}
+
+/*
+ * pool_value_free(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1free(JNIEnv *jenv,
+ jclass jcls, jlong jvalue) {
+ pool_value_free((pool_value_t *)jvalue);
+}
+
+/*
+ * pool_static_location(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1static_1location(
+ JNIEnv *jenv, jclass jcls) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_static_location();
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * pool_dynamic_location(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1dynamic_1location(JNIEnv *
+ jenv, jclass jcls) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_dynamic_location();
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ return (jresult);
+}
+
+/*
+ * pool_set_binding(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1binding(JNIEnv *jenv,
+ jclass jcls, jstring jpool, jint jidtype, jint jpid) {
+ const char *pool;
+ int result;
+
+ pool = (jpool) ? (*jenv)->GetStringUTFChars(jenv, jpool, 0) : NULL;
+ result = (int)pool_set_binding(pool, (idtype_t)jidtype, (id_t)jpid);
+
+ if (pool)
+ (*jenv)->ReleaseStringUTFChars(jenv, jpool, pool);
+ return ((jint)result);
+}
+
+/*
+ * pool_get_binding(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1binding(JNIEnv *jenv,
+ jclass jcls, jint jpid) {
+ jstring jresult = NULL;
+ const char *result;
+
+ result = pool_get_binding((pid_t)jpid);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ return (jresult);
+}
+
+/*
+ * pool_get_resource_binding(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource_1binding(
+ JNIEnv *jenv, jclass jcls, jstring jtype, jint jpid) {
+ jstring jresult = NULL;
+ const char *type;
+ const char *result;
+
+ type = (jtype) ? (*jenv)->GetStringUTFChars(jenv, jtype, 0) : NULL;
+ result = pool_get_resource_binding(type, (pid_t)jpid);
+
+ if (result)
+ jresult = (*jenv)->NewStringUTF(jenv, result);
+ free((void *)result);
+ if (type)
+ (*jenv)->ReleaseStringUTFChars(jenv, jtype, type);
+ return (jresult);
+}
+
+/*
+ * pool_walk_pools(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1pools(JNIEnv *jenv,
+ jclass jcls, jlong jconf, jlong jarg, jlong jcallback) {
+ int result;
+
+ result = pool_walk_pools((pool_conf_t *)jconf, (void *)jarg,
+ (int (*)(pool_conf_t *, pool_t *, void *))jcallback);
+ return ((jint)result);
+}
+
+/*
+ * pool_walk_resources(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1resources(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, jlong jarg,
+ jlong jcallback) {
+ int result;
+
+ result = pool_walk_resources((pool_conf_t *)jconf, (pool_t *)jpool,
+ (void *)jarg,
+ (int (*)(pool_conf_t *, pool_resource_t *, void *))jcallback);
+ return ((jint)result);
+}
+
+/*
+ * pool_walk_components(3pool) wrapper
+ */
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1components(
+ JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource, jlong jarg,
+ jlong jcallback) {
+ int result;
+
+ result = pool_walk_components((pool_conf_t *)jconf,
+ (pool_resource_t *)jresource, (void *)jarg,
+ (int (*)(pool_conf_t *, pool_component_t *, void *))jcallback);
+ return ((jint)result);
+}
+
+/*ARGSUSED*/
+JNIEXPORT jint JNICALL
+Java_com_sun_solaris_service_pools_Element_walkProps(JNIEnv *env,
+ jobject obj, jlong conf, jlong elem, jobject handler, jobject userobj)
+{
+ struct pool_callback pc;
+
+ pc.pc_user = userobj;
+ pc.pc_handler = handler;
+ pc.pc_elem = obj;
+ pc.pc_env = env;
+ return (pool_walk_properties((pool_conf_t *)*(void**)&conf,
+ (pool_elem_t *)*(void**)&elem, (void *)&pc, pool_property_walker));
+}
+
+/*ARGSUSED*/
+static int
+pool_property_walker(pool_conf_t *conf, pool_elem_t *pe, const char *name,
+ pool_value_t *pv, void *user)
+{
+ jclass clazz, vclazz;
+ jmethodID mgetwalk, mvcon;
+ struct pool_callback *pc = (struct pool_callback *)user;
+ jobject valueObj;
+ pool_value_t *pv_new;
+ uint64_t uval;
+ int64_t ival;
+ double dval;
+ uchar_t bval;
+ const char *sval;
+
+ /*
+ * Since we intend to embed our value into a Java Value object
+ * and then reclaim the value when the object is garbage
+ * collected we must create a new pool value and then pass this
+ * to the constructor. We must not use the pool value which is
+ * passed to us.
+ */
+
+ if ((pv_new = pool_value_alloc()) == NULL)
+ return (PO_FAIL);
+ switch (pool_value_get_type(pv)) {
+ case POC_UINT:
+ (void) pool_value_get_uint64(pv, &uval);
+ (void) pool_value_set_uint64(pv_new, uval);
+ break;
+ case POC_INT:
+ (void) pool_value_get_int64(pv, &ival);
+ (void) pool_value_set_int64(pv_new, ival);
+ break;
+ case POC_DOUBLE:
+ (void) pool_value_get_double(pv, &dval);
+ (void) pool_value_set_double(pv_new, dval);
+ break;
+ case POC_BOOL:
+ (void) pool_value_get_bool(pv, &bval);
+ (void) pool_value_set_bool(pv_new, bval);
+ break;
+ case POC_STRING:
+ (void) pool_value_get_string(pv, &sval);
+ (void) pool_value_set_string(pv_new, sval);
+ break;
+ default:
+ pool_value_free(pv_new);
+ return (PO_FAIL);
+ }
+ if (pool_value_set_name(pv_new, name) != PO_SUCCESS ||
+ (vclazz = (*pc->pc_env)->FindClass(pc->pc_env,
+ "com/sun/solaris/service/pools/Value")) == NULL ||
+ (mvcon = (*pc->pc_env)->GetMethodID(pc->pc_env, vclazz,
+ "<init>", "(J)V")) == NULL ||
+ (valueObj = (*pc->pc_env)->NewObject(pc->pc_env, vclazz, mvcon,
+ pv_new)) == NULL ||
+ (clazz = (*pc->pc_env)->GetObjectClass(pc->pc_env, pc->pc_handler))
+ == NULL ||
+ (mgetwalk = (*pc->pc_env)->GetMethodID(pc->pc_env,
+ clazz, "walk",
+ "(Lcom/sun/solaris/service/pools/Element;Lcom/sun/solaris/"
+ "service/pools/Value;Ljava/lang/Object;)I")) == NULL)
+ return (PO_FAIL);
+ return ((*pc->pc_env)->CallIntMethod(pc->pc_env,
+ pc->pc_handler, mgetwalk, pc->pc_elem, valueObj, pc->pc_user));
+}
+
+/*ARGSUSED*/
+JNIEXPORT jlong JNICALL
+Java_com_sun_solaris_service_pools_Value_getLongValue(JNIEnv *jenv,
+ jclass class, jlong pointer)
+{
+ int64_t arg2;
+ int result;
+
+ result = pool_value_get_int64((pool_value_t *)pointer, &arg2);
+
+ if (result != PO_SUCCESS) { /* it could be a uint64 */
+ result = pool_value_get_uint64((pool_value_t *)pointer,
+ (uint64_t *)&arg2);
+ if (result != PO_SUCCESS) {
+ throw_pe(jenv);
+ }
+ /*
+ * Unfortunately, Java has no unsigned types, so we lose some
+ * precision by forcing the top bit clear
+ */
+ arg2 &= 0x7fffffffffffffff;
+ }
+ return ((jlong)arg2);
+}
+
+/*ARGSUSED*/
+JNIEXPORT jstring JNICALL
+Java_com_sun_solaris_service_pools_Value_getStringValue(JNIEnv *jenv,
+ jclass class, jlong pointer)
+{
+ const char *arg2;
+ int result;
+
+ result = pool_value_get_string((pool_value_t *)pointer, &arg2);
+ if (result != PO_SUCCESS)
+ throw_pe(jenv);
+ return ((*jenv)->NewStringUTF(jenv, arg2));
+}
+
+/*ARGSUSED*/
+JNIEXPORT jboolean JNICALL
+Java_com_sun_solaris_service_pools_Value_getBoolValue(JNIEnv *jenv,
+ jclass class, jlong pointer)
+{
+ uchar_t arg2;
+ int result;
+
+ result = pool_value_get_bool((pool_value_t *)pointer, &arg2);
+
+ if (result != PO_SUCCESS) {
+ throw_pe(jenv);
+ }
+ if (arg2 == PO_TRUE)
+ return (JNI_TRUE);
+ else
+ return (JNI_FALSE);
+}
+
+/*ARGSUSED*/
+JNIEXPORT jdouble JNICALL
+Java_com_sun_solaris_service_pools_Value_getDoubleValue(JNIEnv *jenv,
+ jclass class, jlong pointer)
+{
+ double arg2;
+ int result;
+
+ result = pool_value_get_double((pool_value_t *)pointer, &arg2);
+
+ if (result != PO_SUCCESS) {
+ throw_pe(jenv);
+ }
+ return ((jdouble)arg2);
+}
+
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_Value_getUnsignedInt64Value(JNIEnv *jenv,
+ jclass class, jlong pointer)
+{
+ uint64_t arg2;
+ int result;
+
+ result = pool_value_get_uint64((pool_value_t *)pointer, &arg2);
+
+ if (result != PO_SUCCESS) {
+ throw_pe(jenv);
+ }
+ return (makeUnsignedInt64(jenv, arg2));
+}
+
+/*ARGSUSED*/
+JNIEXPORT jobject JNICALL
+Java_com_sun_solaris_service_pools_HRTime_timestamp(JNIEnv *env, jobject obj)
+{
+ return (makeUnsignedInt64(env, gethrtime()));
+}
+
+/*
+ * Cache class, method, and field IDs.
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_pools_PoolInternal_init(JNIEnv *env, jclass clazz)
+{
+ jclass ui64class_lref;
+
+ if (!(ui64class_lref = (*env)->FindClass(env,
+ "com/sun/solaris/service/pools/UnsignedInt64")))
+ return; /* exception thrown */
+ if (!(ui64class = (*env)->NewGlobalRef(env, ui64class_lref)))
+ return; /* exception thrown */
+ ui64cons_mid = (*env)->GetMethodID(env, ui64class, "<init>", "([B)V");
+}
diff --git a/usr/src/cmd/pools/poold/libjpool/sparc/Makefile b/usr/src/cmd/pools/poold/libjpool/sparc/Makefile
new file mode 100644
index 0000000000..c362cddcde
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/sparc/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/sparc/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/sparc
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/Makefile b/usr/src/cmd/pools/poold/libjpool/spec/Makefile
new file mode 100644
index 0000000000..ac42336aea
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/Makefile
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/Makefile.targ b/usr/src/cmd/pools/poold/libjpool/spec/Makefile.targ
new file mode 100644
index 0000000000..1fecfd654a
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/Makefile.targ
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/Makefile.targ
+#
+
+.KEEP_STATE:
+
+LIBRARY = libjpool.a
+VERS = .1
+
+OBJECTS = jpool.o
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/amd64/Makefile b/usr/src/cmd/pools/poold/libjpool/spec/amd64/Makefile
new file mode 100644
index 0000000000..aa209263c6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/amd64/Makefile
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP64)
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/i386/Makefile b/usr/src/cmd/pools/poold/libjpool/spec/i386/Makefile
new file mode 100644
index 0000000000..616e85b404
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/i386/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/jpool.spec b/usr/src/cmd/pools/poold/libjpool/spec/jpool.spec
new file mode 100644
index 0000000000..faeabb575e
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/jpool.spec
@@ -0,0 +1,760 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# "../../jpool.h"
+
+function Java_com_sun_solaris_service_pools_Value_getUnsignedInt64Value
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_Value_getUnsignedInt64Value \
+ (JNIEnv *jenv, jclass class, jlong pointer)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1bool
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1bool \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue, jshort jb)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1type
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1type \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INVAL
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INVAL \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1info
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1info \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, \
+ jint jflags)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1rm_1property
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1rm_1property \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, \
+ jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1DESTROY
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1DESTROY \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1properties
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1properties \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, \
+ jlong jarg, jlong jcallback)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1INVALID
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1INVALID \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1NONE
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1NONE \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_Value_getDoubleValue
+include "../../jpool.h"
+declaration jdouble \
+ Java_com_sun_solaris_service_pools_Value_getDoubleValue \
+ (JNIEnv *jenv, jclass class, jlong pointer)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1to_1elem
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1to_1elem \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1static_1location
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1static_1location \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INT
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1INT \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1rollback
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1rollback \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1status
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1status \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_Value_getBoolValue
+include "../../jpool.h"
+declaration jboolean \
+ Java_com_sun_solaris_service_pools_Value_getBoolValue \
+ (JNIEnv *jenv, jclass class, jlong pointer)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1components
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1components \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource, \
+ jlong jarg, jlong jcallback)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1version
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1version \
+ (JNIEnv *jenv, jclass jcls, jlong jver)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1name
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1name \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue, jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1free
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1free \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1status
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1status \
+ (JNIEnv *jenv, jclass jcls, jint jstate)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1xtransfer
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1xtransfer \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jsource, \
+ jlong jtarget, jobject jcomponents)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1DOUBLE
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1DOUBLE \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1VALID
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POF_1VALID \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1alloc
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1alloc \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resources
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resources \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jobject jprops)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_Value_getLongValue
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_Value_getLongValue \
+ (JNIEnv *jenv, jclass class, jlong pointer)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror_1sys
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror_1sys \
+ (JNIEnv * jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1destroy
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1destroy \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1property
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1property \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, \
+ jstring jname, jlong jproperty)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1dynamic_1location
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1dynamic_1location \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1to_1elem
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1to_1elem \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1status
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1status \
+ (JNIEnv *jenv, jclass jcls, jlong jstatep)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1LOOSE
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1LOOSE \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_HRTime_timestamp
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_HRTime_timestamp \
+ (JNIEnv *env, jobject obj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1info
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1info \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource, \
+ jint jflags)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1alloc
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1alloc \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1STRING
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1STRING \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1create
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1create \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1owning_1resource
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1owning_1resource \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_init
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_init \
+ (JNIEnv *env, jclass clazz)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_Value_getStringValue
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_Value_getStringValue \
+ (JNIEnv *jenv, jclass class, jlong pointer)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1resources
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1resources \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, \
+ jlong jarg, jlong jcallback)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1binding
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1set_1binding \
+ (JNIEnv *jenv, jclass jcls, jstring jpool, jint jidtype, \
+ jint jpid)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1info
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1info \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jint jflags)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1NATIVE
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1NATIVE \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1validate
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1validate \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jint jlevel)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jtype, \
+ jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1dissociate
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1dissociate \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, \
+ jlong jresource)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolsException_getErrno
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolsException_getErrno \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1to_1elem
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1to_1elem \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pools
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pools \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jobject jprops)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resource_1components
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1resource_1components \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong resource, \
+ jobject jprops)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1TEXT
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POX_1TEXT \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1location
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1location \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1close
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1close \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1associate
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1associate \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, \
+ jlong jresource)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1put_1property
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1put_1property \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jelem, \
+ jstring jname, jlong jvalue)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource_1binding
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1resource_1binding \
+ (JNIEnv *jenv, jclass jcls, jstring jtype, jint jpid)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1int64
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1int64 \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue, jlong ji64)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1type_1list
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1type_1list \
+ (JNIEnv *jenv, jclass jcls, jlong jreslist, jlong jnumres)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1destroy
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1destroy \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1pool
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1pool \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1commit
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1commit \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jint jactive)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1uint64
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1uint64 \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue, jlong jui64)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1double
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1double \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue, jdouble jd)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1name
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1get_1name \
+ (JNIEnv *jenv, jclass jcls, jlong jvalue)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1UINT
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1UINT \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1remove
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1remove \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1STRICT
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1STRICT \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_Element_walkProps
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_Element_walkProps \
+ (JNIEnv *env, jobject obj, jlong conf, jlong elem, \
+ jobject handler, jobject userobj)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1open
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1open \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jlocation, \
+ jint jflags)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1free
+include "../../jpool.h"
+declaration void \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1free \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1error
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1error \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1transfer
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1transfer \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jsource, \
+ jlong jtarget, jlong jsize)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1to_1elem
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1to_1elem \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jresource)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1update
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1update \
+ (JNIEnv *jenv, jclass jcls, jlong jconf)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1pools
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1walk_1pools \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jarg, \
+ jlong jcallback)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1create
+include "../../jpool.h"
+declaration jlong \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1resource_1create \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jtype, \
+ jstring jname)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1RUNTIME
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POV_1RUNTIME \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1info
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1component_1info \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jcomponent, \
+ jint jflags)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1binding
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1get_1binding \
+ (JNIEnv *jenv, jclass jcls, jint jpid)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror
+include "../../jpool.h"
+declaration jstring \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1strerror \
+ (JNIEnv *jenv, jclass jcls, jint jperr)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1BOOL
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_get_1POC_1BOOL \
+ (JNIEnv *jenv, jclass jcls)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1string
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1value_1set_1string \
+ (JNIEnv * jenv, jclass jcls, jlong jvalue, jstring jstr)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pool_1resources
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1pool_1resources \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jlong jpool, jobject jprops)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1export
+include "../../jpool.h"
+declaration jint \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1conf_1export \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jstring jlocation, \
+ jint jformat)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1components
+include "../../jpool.h"
+declaration jobject \
+ Java_com_sun_solaris_service_pools_PoolInternal_pool_1query_1components \
+ (JNIEnv *jenv, jclass jcls, jlong jconf, jobject jprops)
+version SUNWprivate_1.1
+end
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/sparc/Makefile b/usr/src/cmd/pools/poold/libjpool/spec/sparc/Makefile
new file mode 100644
index 0000000000..00d0224208
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/sparc/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/sparc/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/sparcv9/Makefile b/usr/src/cmd/pools/poold/libjpool/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..d7de5d0445
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/sparcv9/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec/sparcv9/Makefile
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/cmd/pools/poold/libjpool/spec/versions b/usr/src/cmd/pools/poold/libjpool/spec/versions
new file mode 100644
index 0000000000..88bc34e512
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjpool/spec/versions
@@ -0,0 +1,36 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjpool/spec versions
+#
+
+i386 {
+ SUNWprivate_1.1;
+}
+
+sparc {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/cmd/pools/poold/libjsyslog/Makefile b/usr/src/cmd/pools/poold/libjsyslog/Makefile
new file mode 100644
index 0000000000..c668a01be3
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/Makefile
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/Makefile
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = spec .WAIT $(MACH)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+JNI_CLASSES = \
+ com.sun.solaris.service.logging.SyslogHandler
+
+JNI_GENERATED_HEADERS = \
+ jsyslog.h
+
+CLEANFILES += $(JNI_GENERATED_HEADERS)
+
+all install lint: $(JNI_GENERATED_HEADERS) .WAIT $(SUBDIRS)
+
+clean clobber: $(SUBDIRS)
+
+$(JNI_GENERATED_HEADERS): $(SRC)/cmd/pools/poold/JPool.jar
+ $(JAVAH) -classpath $? -o $@ $(JNI_CLASSES)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
+include $(SRC)/Makefile.msg.targ
diff --git a/usr/src/cmd/pools/poold/libjsyslog/Makefile.com b/usr/src/cmd/pools/poold/libjsyslog/Makefile.com
new file mode 100644
index 0000000000..eec6efccfa
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/Makefile.com
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/Makefile.com
+#
+
+LIBRARY = libjsyslog.a
+VERS = .1
+
+OBJECTS = jsyslog.o
+
+include $(SRC)/lib/Makefile.lib
+
+INCS = -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+MAPFILE = $(MAPDIR)/mapfile
+
+LIBS = $(DYNLIB)
+LDLIBS += -lc
+DYNFLAGS += -M$(MAPFILE)
+ROOTLIBDIR = $(ROOT)/usr/lib/pool
+SRCDIR = $(SRC)/cmd/pools/poold/libjsyslog
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 $(INCS)
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/cmd/pools/poold/libjsyslog/i386/Makefile b/usr/src/cmd/pools/poold/libjsyslog/i386/Makefile
new file mode 100644
index 0000000000..c47e40e1d6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/i386/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/i386/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/i386
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/jsyslog.c b/usr/src/cmd/pools/poold/libjsyslog/jsyslog.c
new file mode 100644
index 0000000000..5bd119e281
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/jsyslog.c
@@ -0,0 +1,113 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "jsyslog.h"
+
+#define ILL_ARG_EX_CLASS_DESC "java/lang/IllegalArgumentException"
+#define THROWABLE_CLASS_DESC "java/lang/Throwable"
+
+#define CLASS_FIELD_DESC(class_desc) "L" class_desc ";"
+
+/*
+ * syslog(3c) ident string
+ */
+static char jsyslog_ident[32];
+
+/*
+ * Log the given message with the given severity.
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_logging_SyslogHandler_syslog(JNIEnv *env,
+ jclass clazz, jint severity, jstring messageObj)
+{
+ const char *message;
+
+ if (messageObj == NULL) {
+ jclass exceptionClass;
+
+ if (!(exceptionClass = (*env)->FindClass(env,
+ ILL_ARG_EX_CLASS_DESC)))
+ return; /* exception thrown */
+ (*env)->Throw(env, (*env)->NewObject(env, exceptionClass,
+ (*env)->GetStaticMethodID(env, exceptionClass, "<init>",
+ "()" CLASS_FIELD_DESC(THROWABLE_CLASS_DESC))));
+ return;
+ }
+
+ if (!(message = (*env)->GetStringUTFChars(env, messageObj, NULL)))
+ return; /* exception thrown */
+ syslog(severity, "%s", message);
+ (*env)->ReleaseStringUTFChars(env, messageObj, message);
+}
+
+/*
+ * Invoke openlog(3c).
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_logging_SyslogHandler_openlog(JNIEnv *env,
+ jclass clazz, jstring identObj, jint logopt, jint facility)
+{
+ const char *ident;
+
+ if (identObj == NULL) {
+ jclass exceptionClass;
+
+ if (!(exceptionClass = (*env)->FindClass(env,
+ ILL_ARG_EX_CLASS_DESC)))
+ return; /* exception thrown */
+ (*env)->Throw(env, (*env)->NewObject(env, exceptionClass,
+ (*env)->GetStaticMethodID(env, exceptionClass, "<init>",
+ "()" CLASS_FIELD_DESC(THROWABLE_CLASS_DESC))));
+ return;
+ }
+
+ if (!(ident = (*env)->GetStringUTFChars(env, identObj, NULL)))
+ return; /* exception thrown */
+ (void) strlcpy(jsyslog_ident, ident, sizeof (jsyslog_ident));
+ openlog(jsyslog_ident, logopt, facility);
+
+ (*env)->ReleaseStringUTFChars(env, identObj, ident);
+}
+
+/*
+ * Invoke closelog(3c).
+ */
+/*ARGSUSED*/
+JNIEXPORT void JNICALL
+Java_com_sun_solaris_service_logging_SyslogHandler_closelog(JNIEnv *env,
+ jclass clazz)
+{
+ closelog();
+}
diff --git a/usr/src/cmd/pools/poold/libjsyslog/sparc/Makefile b/usr/src/cmd/pools/poold/libjsyslog/sparc/Makefile
new file mode 100644
index 0000000000..73c4c909f0
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/sparc/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/sparc/Makefile
+#
+
+
+include ../Makefile.com
+
+MAPDIR= ../spec/sparc
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile b/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile
new file mode 100644
index 0000000000..7f90194f7a
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/Makefile
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile.targ b/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile.targ
new file mode 100644
index 0000000000..902097f7f3
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/Makefile.targ
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/Makefile.targ
+#
+
+.KEEP_STATE:
+
+LIBRARY = libjsyslog.a
+VERS = .1
+
+OBJECTS = jsyslog.o
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/amd64/Makefile b/usr/src/cmd/pools/poold/libjsyslog/spec/amd64/Makefile
new file mode 100644
index 0000000000..834ae5533d
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/amd64/Makefile
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS64 += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP64)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/i386/Makefile b/usr/src/cmd/pools/poold/libjsyslog/spec/i386/Makefile
new file mode 100644
index 0000000000..d3a8371369
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/i386/Makefile
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/jsyslog.spec b/usr/src/cmd/pools/poold/libjsyslog/spec/jsyslog.spec
new file mode 100644
index 0000000000..090b4de9bd
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/jsyslog.spec
@@ -0,0 +1,53 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/jsyslog.spec
+
+function Java_com_sun_solaris_service_logging_SyslogHandler_closelog
+include "../../jsyslog.h"
+declaration void \
+ Java_com_sun_solaris_service_logging_SyslogHandler_closelog \
+ (JNIEnv *env, jclass clazz)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_logging_SyslogHandler_openlog
+include "../../jsyslog.h"
+declaration void \
+ Java_com_sun_solaris_service_logging_SyslogHandler_openlog \
+ (JNIEnv *env, jclass clazz, jstring identObj, jint logopt, \
+ jint facility)
+version SUNWprivate_1.1
+end
+
+function Java_com_sun_solaris_service_logging_SyslogHandler_syslog
+include "../../jsyslog.h"
+declaration void \
+ Java_com_sun_solaris_service_logging_SyslogHandler_syslog \
+ (JNIEnv *env, jclass clazz, jint severity, jstring messageObj)
+version SUNWprivate_1.1
+end
+
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/sparc/Makefile b/usr/src/cmd/pools/poold/libjsyslog/spec/sparc/Makefile
new file mode 100644
index 0000000000..57a87c60a4
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/sparc/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/sparc/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+CFLAGS += -I$(JAVA_ROOT)/include \
+ -I$(JAVA_ROOT)/include/solaris
+
+install: $(SPECMAP)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/sparcv9/Makefile b/usr/src/cmd/pools/poold/libjsyslog/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..754d9ca943
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/sparcv9/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec/sparcv9/Makefile
+
+DISABLE_APPTRACE= $(POUND_SIGN)
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
diff --git a/usr/src/cmd/pools/poold/libjsyslog/spec/versions b/usr/src/cmd/pools/poold/libjsyslog/spec/versions
new file mode 100644
index 0000000000..e1a5cf94b6
--- /dev/null
+++ b/usr/src/cmd/pools/poold/libjsyslog/spec/versions
@@ -0,0 +1,36 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poold/libjsyslog/spec versions
+#
+
+i386 {
+ SUNWprivate_1.1;
+}
+
+sparc {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/cmd/pools/poold/poold.c b/usr/src/cmd/pools/poold/poold.c
new file mode 100644
index 0000000000..0d12d5a832
--- /dev/null
+++ b/usr/src/cmd/pools/poold/poold.c
@@ -0,0 +1,680 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * poold - dynamically adjust pool configuration according to load.
+ */
+#include <errno.h>
+#include <jni.h>
+#include <libintl.h>
+#include <limits.h>
+#include <link.h>
+#include <locale.h>
+#include <poll.h>
+#include <pool.h>
+#include <priv.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include "utils.h"
+
+#define POOLD_DEF_CLASSPATH "/usr/lib/pool/JPool.jar"
+#define POOLD_DEF_LIBPATH "/usr/lib/pool"
+
+#if defined(sparc)
+#define PLAT "sparc"
+#else
+#if defined(i386)
+#define PLAT "i386"
+#else
+#error Unrecognized platform.
+#endif
+#endif
+
+#define PID_PROPERTY_NAME "system.poold.pid"
+
+#define CLASS_FIELD_DESC(class_desc) "L" class_desc ";"
+
+#define LEVEL_CLASS_DESC "java/util/logging/Level"
+#define POOLD_CLASS_DESC "com/sun/solaris/domain/pools/Poold"
+#define SEVERITY_CLASS_DESC "com/sun/solaris/service/logging/Severity"
+#define STRING_CLASS_DESC "java/lang/String"
+#define SYSTEM_CLASS_DESC "java/lang/System"
+#define LOGGER_CLASS_DESC "java/util/logging/Logger"
+
+extern char *optarg;
+
+static const char *pname;
+
+static enum {
+ LD_TERMINAL = 1,
+ LD_SYSLOG,
+ LD_JAVA
+} log_dest = LD_SYSLOG;
+
+typedef enum {
+ PGAS_GET_ONLY = 1,
+ PGAS_GET_AND_SET
+} pgas_mode_t;
+
+static const char PNAME_FMT[] = "%s: ";
+static const char ERRNO_FMT[] = ": %s";
+
+static JavaVM *jvm;
+static int lflag;
+
+static jmethodID log_mid;
+static jobject severity_err;
+static jobject severity_notice;
+static jobject base_log;
+static jclass poold_class;
+static jobject poold_instance;
+static int instance_running;
+static pthread_mutex_t instance_running_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static sigset_t hdl_set;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, gettext("Usage:\t%s [-l <level>]\n"), pname);
+
+ exit(E_USAGE);
+}
+
+static void
+pu_output(int severity, const char *fmt, va_list alist)
+{
+ int err = errno;
+ char line[255] = "";
+ jobject jseverity;
+ jobject jline;
+ JNIEnv *env;
+ int detach_required = 0;
+ if (pname != NULL && log_dest == LD_TERMINAL)
+ (void) snprintf(line, sizeof (line), gettext(PNAME_FMT), pname);
+
+ (void) vsnprintf(line + strlen(line), sizeof (line) - strlen(line),
+ fmt, alist);
+
+ if (line[strlen(line) - 1] != '\n')
+ (void) snprintf(line + strlen(line), sizeof (line) -
+ strlen(line), gettext(ERRNO_FMT), strerror(err));
+ else
+ line[strlen(line) - 1] = 0;
+
+ switch (log_dest) {
+ case LD_TERMINAL:
+ (void) fprintf(stderr, "%s\n", line);
+ (void) fflush(stderr);
+ break;
+ case LD_SYSLOG:
+ syslog(LOG_ERR, "%s", line);
+ break;
+ case LD_JAVA:
+ if (severity == LOG_ERR)
+ jseverity = severity_err;
+ else
+ jseverity = severity_notice;
+
+ if (jvm) {
+ (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
+ if (env == NULL) {
+ detach_required = 1;
+ (*jvm)->AttachCurrentThread(jvm,
+ (void **)&env, NULL);
+ }
+ if ((jline = (*env)->NewStringUTF(env, line)) != NULL)
+ (*env)->CallVoidMethod(env, base_log, log_mid,
+ jseverity, jline);
+ if (detach_required)
+ (*jvm)->DetachCurrentThread(jvm);
+ }
+ }
+}
+
+/*PRINTFLIKE1*/
+static void
+pu_notice(const char *fmt, ...)
+{
+ va_list alist;
+ va_start(alist, fmt);
+ pu_output(LOG_NOTICE, fmt, alist);
+ va_end(alist);
+}
+
+/*PRINTFLIKE1*/
+static void
+pu_die(const char *fmt, ...)
+{
+ va_list alist;
+ va_start(alist, fmt);
+ pu_output(LOG_ERR, fmt, alist);
+ va_end(alist);
+ exit(E_ERROR);
+}
+
+/*
+ * Update the "system.poold.pid" to reflect this instance of poold only
+ * if the property hasn't been set already to reflect an existing
+ * process, and mode is not set to PGAS_GET_ONLY. Returns the
+ * property's pre-existing value, or -1 otherwise.
+ */
+static pid_t
+poold_get_and_set_pid(pgas_mode_t mode)
+{
+ pool_conf_t *conf;
+ pool_elem_t *pe;
+ pool_value_t *val;
+ int64_t ival;
+
+ if (!(conf = pool_conf_alloc()))
+ return ((pid_t)-1);
+
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR) != 0) {
+ (void) pool_conf_free(conf);
+ return ((pid_t)-1);
+ }
+
+ pe = pool_conf_to_elem(conf);
+ if (!(val = pool_value_alloc())) {
+ (void) pool_conf_close(conf);
+ return ((pid_t)-1);
+ }
+
+ if (pool_get_property(conf, pe, PID_PROPERTY_NAME, val) == POC_INT) {
+ if (pool_value_get_int64(val, &ival) != 0) {
+ (void) pool_value_free(val);
+ (void) pool_conf_close(conf);
+ return ((pid_t)-1);
+ }
+ } else {
+ ival = (pid_t)-1;
+ }
+
+ if (mode == PGAS_GET_AND_SET) {
+ ival = getpid();
+ pool_value_set_int64(val, ival);
+ (void) pool_put_property(conf, pe, PID_PROPERTY_NAME, val);
+ (void) pool_conf_commit(conf, 0);
+ }
+
+ (void) pool_value_free(val);
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+
+ return ((pid_t)ival);
+}
+
+/*
+ * Reconfigure the JVM by simply updating a dummy property on the
+ * system element to force pool_conf_update() to detect a change.
+ */
+static void
+reconfigure()
+{
+ JNIEnv *env;
+ pool_conf_t *conf;
+ pool_elem_t *pe;
+ pool_value_t *val;
+ const char *err_desc;
+ int detach_required = 0;
+
+ if ((conf = pool_conf_alloc()) == NULL) {
+ err_desc = pool_strerror(pool_error());
+ goto destroy;
+ }
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR) != 0) {
+ err_desc = pool_strerror(pool_error());
+ pool_conf_free(conf);
+ goto destroy;
+ }
+
+ if ((val = pool_value_alloc()) == NULL) {
+ err_desc = pool_strerror(pool_error());
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+ goto destroy;
+ }
+ pe = pool_conf_to_elem(conf);
+ pool_value_set_bool(val, 1);
+ if (pool_put_property(conf, pe, "system.poold.sighup", val) !=
+ PO_SUCCESS) {
+ err_desc = pool_strerror(pool_error());
+ pool_value_free(val);
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+ goto destroy;
+ }
+ pool_value_free(val);
+ (void) pool_rm_property(conf, pe, "system.poold.sighup");
+ if (pool_conf_commit(conf, 0) != PO_SUCCESS) {
+ err_desc = pool_strerror(pool_error());
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+ goto destroy;
+ }
+ (void) pool_conf_close(conf);
+ pool_conf_free(conf);
+ return;
+destroy:
+ if (jvm) {
+ (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
+ if (env == NULL) {
+ detach_required = 1;
+ (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
+ }
+ if (lflag && (*env)->ExceptionOccurred(env))
+ (*env)->ExceptionDescribe(env);
+ if (detach_required)
+ (*jvm)->DetachCurrentThread(jvm);
+ (*jvm)->DestroyJavaVM(jvm);
+ }
+ pu_die(err_desc);
+}
+
+/*
+ * If SIGHUP is invoked, we should just re-initialize poold. Since
+ * there is no easy way to determine when it's safe to re-initialzie
+ * poold, simply update a dummy property on the system element to
+ * force pool_conf_update() to detect a change.
+ *
+ * Both SIGTERM and SIGINT are interpreted as instructions to
+ * shutdown.
+ */
+/*ARGSUSED*/
+static void *
+handle_sig(void *arg)
+{
+ for (;;) {
+ JNIEnv *env;
+ jmethodID poold_shutdown_mid;
+ int sig;
+ char buf[SIG2STR_MAX];
+ int detach_required = 0;
+
+ if ((sig = sigwait(&hdl_set)) < 0)
+ pu_die("unexpected error: %d\n", errno);
+ (void) sig2str(sig, buf);
+ switch (sig) {
+ case SIGHUP:
+ reconfigure();
+ break;
+ case SIGINT:
+ case SIGTERM:
+ (void) pthread_mutex_lock(&instance_running_lock);
+ if (instance_running) {
+ (void) pthread_mutex_unlock(
+ &instance_running_lock);
+ (*jvm)->GetEnv(jvm, (void **)&env,
+ JNI_VERSION_1_2);
+ if (env == NULL) {
+ detach_required = 1;
+ (*jvm)->AttachCurrentThread(jvm,
+ (void **)&env, NULL);
+ }
+ pu_notice("terminating due to signal: SIG%s\n",
+ buf);
+ if ((poold_shutdown_mid = (*env)->GetMethodID(
+ env, poold_class, "shutdown", "()V")) !=
+ NULL) {
+ (*env)->CallVoidMethod(env,
+ poold_instance,
+ poold_shutdown_mid);
+ } else {
+ (*env)->ExceptionDescribe(env);
+ pu_die("could not invoke"
+ " proper shutdown\n");
+ }
+ if (detach_required)
+ (*jvm)->DetachCurrentThread(jvm);
+ } else {
+ (void) pthread_mutex_unlock(
+ &instance_running_lock);
+ pu_die("terminated with signal: SIG%s\n", buf);
+ /*NOTREACHED*/
+ }
+ break;
+ default:
+ pu_die("unexpected signal: SIG%s\n", buf);
+ }
+ }
+ /*NOTREACHED*/
+ return (NULL);
+}
+
+static const char *
+pu_getpname(const char *arg0)
+{
+ char *p;
+
+ /*
+ * Guard against '/' at end of command invocation.
+ */
+ for (;;) {
+ p = strrchr(arg0, '/');
+ if (p == NULL) {
+ pname = arg0;
+ break;
+ } else {
+ if (*(p + 1) == '\0') {
+ *p = '\0';
+ continue;
+ }
+
+ pname = p + 1;
+ break;
+ }
+ }
+
+ return (pname);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ char log_severity[16] = "";
+ pid_t pid;
+ JavaVMInitArgs vm_args;
+ JavaVMOption vm_opts[5];
+ int nopts = 0;
+ const char *classpath;
+ const char *libpath;
+ size_t len;
+ const char *err_desc;
+ JNIEnv *env;
+ jmethodID poold_getinstancewcl_mid;
+ jmethodID poold_run_mid;
+ jobject log_severity_string = NULL;
+ jobject log_severity_obj = NULL;
+ jclass severity_class;
+ jmethodID severity_cons_mid;
+ jfieldID base_log_fid;
+ int explain_ex = 1;
+ JavaVM *jvm_tmp;
+ pthread_t hdl_thread;
+
+ pname = pu_getpname(argv[0]);
+ openlog(pname, 0, LOG_DAEMON);
+ (void) chdir("/");
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined with cc -D. */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't. */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "l:P")) != EOF) {
+ switch (c) {
+ case 'l': /* -l option */
+ lflag++;
+ (void) strlcpy(log_severity, optarg,
+ sizeof (log_severity));
+ log_dest = LD_TERMINAL;
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ }
+
+ /*
+ * Verify no other poold is running. This condition is checked
+ * again later, but should be checked now since it is more
+ * serious (i.e. should be reported before) than a lack of
+ * privileges.
+ */
+ if (((pid = poold_get_and_set_pid(PGAS_GET_ONLY)) != (pid_t)-1) &&
+ pid != getpid() && kill(pid, 0) == 0)
+ pu_die(gettext("poold is already active (process %ld)\n"), pid);
+
+ /*
+ * Check permission
+ */
+ if (!priv_ineffect(PRIV_SYS_RES_CONFIG))
+ pu_die(gettext(ERR_PRIVILEGE), PRIV_SYS_RES_CONFIG);
+
+ /*
+ * Establish the classpath and LD_LIBRARY_PATH for native
+ * methods, and get the interpreter going.
+ */
+ if ((classpath = getenv("POOLD_CLASSPATH")) == NULL) {
+ classpath = POOLD_DEF_CLASSPATH;
+ } else {
+ const char *cur = classpath;
+
+ /*
+ * Check the components to make sure they're absolute
+ * paths.
+ */
+ while (cur != NULL && *cur) {
+ if (*cur != '/')
+ pu_die(gettext(
+ "POOLD_CLASSPATH must contain absolute "
+ "components\n"));
+ cur = strchr(cur + 1, ':');
+ }
+ }
+ vm_opts[nopts].optionString = malloc(len = strlen(classpath) +
+ strlen("-Djava.class.path=") + 1);
+ (void) strlcpy(vm_opts[nopts].optionString, "-Djava.class.path=", len);
+ (void) strlcat(vm_opts[nopts++].optionString, classpath, len);
+
+ if ((libpath = getenv("POOLD_LD_LIBRARY_PATH")) == NULL)
+ libpath = POOLD_DEF_LIBPATH;
+ vm_opts[nopts].optionString = malloc(len = strlen(libpath) +
+ strlen("-Djava.library.path=") + 1);
+ (void) strlcpy(vm_opts[nopts].optionString, "-Djava.library.path=",
+ len);
+ (void) strlcat(vm_opts[nopts++].optionString, libpath, len);
+
+ vm_opts[nopts++].optionString = "-Xrs";
+ vm_opts[nopts++].optionString = "-enableassertions";
+
+ vm_args.options = vm_opts;
+ vm_args.nOptions = nopts;
+ vm_args.ignoreUnrecognized = JNI_FALSE;
+ vm_args.version = 0x00010002;
+
+ /*
+ * XXX - Forking after the VM is created is desirable to
+ * guarantee reporting of errors, but cannot be done (see
+ * 4919246).
+ *
+ * If invoked by libpool(3LIB), it's set the system.poold.pid
+ * property and forked already. If invoked directly and -l is
+ * specified, forking is not desired.
+ */
+ if (!lflag && pid != getpid())
+ switch (fork()) {
+ case 0:
+ (void) setsid();
+ (void) fclose(stdin);
+ (void) fclose(stdout);
+ (void) fclose(stderr);
+ break;
+ case -1:
+ pu_die(gettext("cannot fork"));
+ /*NOTREACHED*/
+ default:
+ return (E_PO_SUCCESS);
+ }
+
+ /*
+ * In order to avoid problems with arbitrary thread selection
+ * when handling asynchronous signals, dedicate a thread to
+ * look after these signals.
+ */
+ if (sigemptyset(&hdl_set) < 0 ||
+ sigaddset(&hdl_set, SIGHUP) < 0 ||
+ sigaddset(&hdl_set, SIGTERM) < 0 ||
+ sigaddset(&hdl_set, SIGINT) < 0 ||
+ pthread_sigmask(SIG_BLOCK, &hdl_set, NULL) ||
+ pthread_create(&hdl_thread, NULL, handle_sig, NULL))
+ pu_die(gettext("can't install signal handler"));
+
+ /*
+ * Use jvm_tmp when creating the jvm to prevent race
+ * conditions with signal handlers. As soon as the call
+ * returns, assign the global jvm to jvm_tmp.
+ */
+ if (JNI_CreateJavaVM(&jvm_tmp, (void **)&env, &vm_args) < 0)
+ pu_die(gettext("can't create Java VM"));
+ jvm = jvm_tmp;
+
+ /*
+ * Locate the Poold class and construct an instance. A side
+ * effect of this is that the poold instance's logHelper will be
+ * initialized, establishing loggers for logging errors from
+ * this point on. (Note, in the event of an unanticipated
+ * exception, poold will invoke die() itself.)
+ */
+ err_desc = gettext("JVM-related error initializing poold\n");
+ if ((poold_class = (*env)->FindClass(env, POOLD_CLASS_DESC)) == NULL)
+ goto destroy;
+ if ((poold_getinstancewcl_mid = (*env)->GetStaticMethodID(env,
+ poold_class, "getInstanceWithConsoleLogging", "("
+ CLASS_FIELD_DESC(SEVERITY_CLASS_DESC) ")"
+ CLASS_FIELD_DESC(POOLD_CLASS_DESC))) == NULL)
+ goto destroy;
+ if ((poold_run_mid = (*env)->GetMethodID(env, poold_class, "run",
+ "()V")) == NULL)
+ goto destroy;
+ if ((severity_class = (*env)->FindClass(env, SEVERITY_CLASS_DESC))
+ == NULL)
+ goto destroy;
+ if ((severity_cons_mid = (*env)->GetStaticMethodID(env, severity_class,
+ "getSeverityWithName", "(" CLASS_FIELD_DESC(STRING_CLASS_DESC) ")"
+ CLASS_FIELD_DESC(SEVERITY_CLASS_DESC))) == NULL)
+ goto destroy;
+
+ /*
+ * -l <level> was specified, indicating that messages are to be
+ * logged to the console only.
+ */
+ if (strlen(log_severity) > 0) {
+ if ((log_severity_string = (*env)->NewStringUTF(env,
+ log_severity)) == NULL)
+ goto destroy;
+ if ((log_severity_obj = (*env)->CallStaticObjectMethod(env,
+ severity_class, severity_cons_mid, log_severity_string)) ==
+ NULL) {
+ err_desc = gettext("invalid level specified\n");
+ explain_ex = 0;
+ goto destroy;
+ }
+ } else
+ log_severity_obj = NULL;
+
+ if ((poold_instance = (*env)->CallStaticObjectMethod(env, poold_class,
+ poold_getinstancewcl_mid, log_severity_obj)) == NULL)
+ goto destroy;
+
+ /*
+ * Grab a global reference to poold for use in our signal
+ * handlers.
+ */
+ poold_instance = (*env)->NewGlobalRef(env, poold_instance);
+
+ /*
+ * Ready LD_JAVA logging.
+ */
+ err_desc = gettext("cannot initialize logging\n");
+ if ((log_severity_string = (*env)->NewStringUTF(env, "err")) == NULL)
+ goto destroy;
+ if (!(severity_err = (*env)->CallStaticObjectMethod(env, severity_class,
+ severity_cons_mid, log_severity_string)))
+ goto destroy;
+ if (!(severity_err = (*env)->NewGlobalRef(env, severity_err)))
+ goto destroy;
+
+ if ((log_severity_string = (*env)->NewStringUTF(env, "notice")) == NULL)
+ goto destroy;
+ if (!(severity_notice = (*env)->CallStaticObjectMethod(env,
+ severity_class, severity_cons_mid, log_severity_string)))
+ goto destroy;
+ if (!(severity_notice = (*env)->NewGlobalRef(env, severity_notice)))
+ goto destroy;
+
+ if (!(base_log_fid = (*env)->GetStaticFieldID(env, poold_class,
+ "BASE_LOG", CLASS_FIELD_DESC(LOGGER_CLASS_DESC))))
+ goto destroy;
+ if (!(base_log = (*env)->GetStaticObjectField(env, poold_class,
+ base_log_fid)))
+ goto destroy;
+ if (!(base_log = (*env)->NewGlobalRef(env, base_log)))
+ goto destroy;
+ if (!(log_mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env,
+ base_log), "log", "(" CLASS_FIELD_DESC(LEVEL_CLASS_DESC)
+ CLASS_FIELD_DESC(STRING_CLASS_DESC) ")V")))
+ goto destroy;
+ log_dest = LD_JAVA;
+
+ /*
+ * Now we're ready to start poold. Store our pid in the pools
+ * configuration to mark that an instance of poold is active,
+ * then invoke Poold.run(), which does not normally return.
+ *
+ * Note that the ignoreUpdates variable in Poold is used to
+ * allow Poold to ignore the pools configuration update that
+ * this change triggers. If this code is ever modified to
+ * remove or modify this logic, then the Poold class must also
+ * be modified to keep the actions synchronized.
+ */
+
+ if (((pid = poold_get_and_set_pid(PGAS_GET_AND_SET)) != (pid_t)-1) &&
+ pid != getpid() && kill(pid, 0) == 0)
+ pu_die(gettext("poold is already active (process %ld)\n"), pid);
+
+ (void) pthread_mutex_lock(&instance_running_lock);
+ instance_running = 1;
+ (void) pthread_mutex_unlock(&instance_running_lock);
+ (*env)->CallVoidMethod(env, poold_instance, poold_run_mid);
+
+ if ((*env)->ExceptionOccurred(env))
+ goto destroy;
+
+ (*jvm)->DestroyJavaVM(jvm);
+ return (E_PO_SUCCESS);
+
+destroy:
+ if (lflag && explain_ex && (*env)->ExceptionOccurred(env))
+ (*env)->ExceptionDescribe(env);
+ (*jvm)->DestroyJavaVM(jvm);
+ pu_die(err_desc);
+}
diff --git a/usr/src/cmd/pools/poold/poold.properties b/usr/src/cmd/pools/poold/poold.properties
new file mode 100644
index 0000000000..2e56ce9d4a
--- /dev/null
+++ b/usr/src/cmd/pools/poold/poold.properties
@@ -0,0 +1,47 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# NOTICE: This file contains default settings for poold(1M). Do not
+# edit this file. Its format and contents are subject to change in
+# future releases of Solaris.
+
+# Objective Classes
+
+system.objectives= com.sun.solaris.domain.pools.WeightedLoadObjective
+pset.objectives= com.sun.solaris.domain.pools.LocalityObjective, com.sun.solaris.domain.pools.UtilizationObjective
+
+# poold-specific logging properties (replacing default logging.properties)
+.level= ALL
+
+# Set defaults for all logfiles (poold and API-generated) which are suitable
+# for management by logadm(1M).
+java.util.logging.FileHandler.limit = 0
+java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.append = true
+
+# Change defaults for API-generated logfiles.
+java.util.logging.FileHandler.pattern = /var/log/pool/java%u.log
+java.util.logging.FileHandler.formatter = com.sun.solaris.service.logging.SysloglikeFormatter
diff --git a/usr/src/cmd/pools/poolstat/Makefile b/usr/src/cmd/pools/poolstat/Makefile
new file mode 100644
index 0000000000..f45f974697
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/Makefile
@@ -0,0 +1,65 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/pools/poolstat/Makefile
+
+PROG = poolstat
+OBJS = poolstat.o poolstat_utils.o sa_libpool.o sa_kstat.o
+SRCS = $(OBJS:%.o=%.c) $(COMMON_SRCS)
+POFILES = $(OBJS:.o=.po)
+
+include ../../Makefile.cmd
+include ../Makefile.pools
+
+CFLAGS += -I$(POOLSCOMMONDIR) $(EXTRA_CFLAGS)
+sparc_COPTFLAG=
+LDLIBS += -lpool -lkstat
+XGETFLAGS = -a
+CLOBBERFILES += $(POFILES)
+
+lint := LINTFLAGS += -I$(POOLSCOMMONDIR)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS) $(COMMON_OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(COMMON_OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o : $(POOLSCOMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS) $(COMMON_OBJS) $(POFILES)
+
+lint: lint_SRCS
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/pools/poolstat/poolstat.c b/usr/src/cmd/pools/poolstat/poolstat.c
new file mode 100644
index 0000000000..abea3e2e83
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/poolstat.c
@@ -0,0 +1,1009 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * poolstat - report active pool statistics
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <locale.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <pool.h>
+#include "utils.h"
+#include "poolstat.h"
+#include "poolstat_utils.h"
+
+#ifndef TEXT_DOMAIN
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+
+/* calculate offset of a particular element in a structure */
+#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
+#define addrof(s) ((char **)&(s))
+
+/* verify if a field is printable in respect of the current option flags */
+#define PRINTABLE(i) ((lf->plf_ffs[(i)].pff_prt & D_FIELD) || \
+ (lf->plf_ffs[(i)].pff_prt & X_FIELD))
+
+typedef int (* formatter) (char *, int, int, poolstat_field_format_t *, char *);
+
+/* available field formatters */
+static int default_f(char *, int, int, poolstat_field_format_t *, char *);
+static int bigno_f(char *, int, int, poolstat_field_format_t *, char *);
+static int used_stat_f(char *, int, int, poolstat_field_format_t *, char *);
+static int header_f(char *, int, int, poolstat_field_format_t *, char *);
+
+/* statistics bags used to collect data from various provider */
+static statistic_bag_t pool_sbag_s;
+static statistic_bag_t pset_sbag_s;
+static statistic_bag_t *pool_sbag = &pool_sbag_s;
+static statistic_bag_t *pset_sbag = &pset_sbag_s;
+
+/* formatter objects for pset, defined in a default printing sequence */
+static poolstat_field_format_t pset_ffs[] = {
+ /* prt flags,name,header,type,width,minwidth,offset,formatter */
+ { DX_FIELD, "id", "id", LL, 3, 1, addrof(pool_sbag),
+ offsetof(statistic_bag_t, sb_sysid),
+ (formatter)default_f },
+ { DX_FIELD, "pool", "pool", STR, 20, 14, addrof(pool_sbag),
+ offsetof(statistic_bag_t, sb_name),
+ (formatter)default_f },
+ { DX_FIELD, "type", "type", STR, 4, 5, addrof(pset_sbag),
+ offsetof(statistic_bag_t, sb_type),
+ (formatter)default_f },
+ { D_FIELD, "rid", "rid", LL, 3, 1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_sysid),
+ (formatter)default_f },
+ { DX_FIELD, "rset", "rset", STR, 20, 14, addrof(pset_sbag),
+ offsetof(statistic_bag_t, sb_name),
+ (formatter)default_f },
+ { DX_FIELD, "min", "min", ULL, 4, 1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_min),
+ (formatter)bigno_f },
+ { DX_FIELD, "max", "max", ULL, 4, 1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_max),
+ (formatter)bigno_f },
+ { DX_FIELD, "size", "size", ULL, 4, 1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_size),
+ (formatter)default_f },
+ { DX_FIELD, "used", "used", FL, 4, -1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_used),
+ (formatter)used_stat_f },
+ { DX_FIELD, "load", "load", FL, 4, -1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_load),
+ (formatter)default_f }
+};
+
+/* formatter objects for pool, defined in a default printing sequence */
+static poolstat_field_format_t pool_ffs[] = {
+ /* prt flags,name,header,type,width,minwidth,offset,formatter */
+ { D_FIELD, "id", "id", LL, 3, 1, addrof(pool_sbag),
+ offsetof(statistic_bag_t, sb_sysid),
+ (formatter)default_f },
+ { D_FIELD, "pool", "pool", STR, 20, 13, addrof(pool_sbag),
+ offsetof(statistic_bag_t, sb_name),
+ (formatter)default_f },
+ { D_FIELD, "p_size", "size", ULL, 4, 1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_size),
+ (formatter)default_f },
+ { D_FIELD, "p_used", "used", FL, 4, -1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_used),
+ (formatter)default_f },
+ { D_FIELD, "p_load", "load", FL, 4, -1, addrof(pset_sbag_s.bag),
+ offsetof(pset_statistic_bag_t, pset_sb_load),
+ (formatter)default_f },
+};
+
+/* lists with formatter objects, one for each statistics field */
+static poolstat_line_format_t pool_lf; /* formatting list in default mode */
+static poolstat_line_format_t pset_lf; /* formatting list for psets */
+
+/* name of pools to be shown */
+static poolstat_list_element_t *pnames;
+/*
+ * type of resources to be shown, currently we only have one type 'pset'
+ * but, poolstat can be extended to handle new upcoming resource types.
+ */
+static poolstat_list_element_t *rtypes;
+
+/* a handle to the pool configuration */
+static pool_conf_t *conf;
+
+/* option flags */
+static int rflag;
+static int pflag;
+static int oflag;
+
+/* operands */
+static int interval = 0; /* update interval */
+static long count = 1; /* one run */
+
+/* data structure handlers */
+static poolstat_list_element_t *
+ create_prt_sequence_list(char *, poolstat_line_format_t *);
+static poolstat_list_element_t *
+ create_args_list(char *, poolstat_list_element_t *, const char *);
+
+/* statistics update function */
+static void sa_update(statistic_bag_t *, int);
+
+/* statistics printing function */
+static void prt_pool_stats(poolstat_list_element_t *);
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, gettext(
+"Usage:\n"
+"poolstat [-p pool-list] [-r rset-list] [interval [count]]\n"
+"poolstat [-p pool-list] [-o format -r rset-list] [interval [count]]\n"
+" \'pool-list\' is a space-separated list of pool IDs or names\n"
+" \'rset-list\' is \'all\' or \'pset\'\n"
+" \'format\' for all resource types is one or more of:\n"
+"\tid pool type rid rset min max size used load\n"));
+ (void) exit(E_USAGE);
+}
+
+static int
+Atoi(char *p, int *errp)
+{
+ int i;
+ char *q;
+ errno = 0;
+ i = strtol(p, &q, 10);
+ if (errno != 0 || q == p || *q != '\0')
+ *errp = -1;
+ else
+ *errp = 0;
+ return (i);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ int error = 0;
+
+ (void) getpname(argv[0]);
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ /* pset_sbag_s is used to collect pset statistics */
+ pset_sbag_s.sb_type = PSET_TYPE_NAME;
+ pset_sbag_s.bag = ZALLOC(sizeof (pset_statistic_bag_t));
+ pool_sbag_s.sb_type = POOL_TYPE_NAME;
+
+ pset_lf.plf_ffs = pset_ffs;
+ pset_lf.plf_ff_len = sizeof (pset_ffs) /
+ sizeof (poolstat_field_format_t);
+ pool_lf.plf_ffs = pool_ffs;
+ pool_lf.plf_ff_len = sizeof (pool_ffs) /
+ sizeof (poolstat_field_format_t);
+
+ while ((c = getopt(argc, argv, ":p:r:o:")) != EOF) {
+ switch (c) {
+ case 'p': /* pool name specification */
+ pflag++;
+ pnames = create_args_list(optarg, pnames,
+ " \t");
+ break;
+ case 'r': { /* resource type */
+ rflag++;
+ rtypes = create_args_list(optarg, rtypes,
+ " \t,");
+ break;
+ }
+ case 'o': { /* format specification */
+ oflag++;
+ if (create_prt_sequence_list(optarg, &pset_lf) == NULL)
+ usage();
+ break;
+ }
+ case ':': {
+ (void) fprintf(stderr,
+ gettext(ERR_OPTION_ARGS), optopt);
+ usage();
+ /*NOTREACHED*/
+ }
+ default:
+ (void) fprintf(stderr, gettext(ERR_OPTION), optopt);
+ usage();
+ /*NOTREACHED*/
+ }
+ }
+
+ /* get operands */
+ if (argc > optind) {
+ if ((interval = Atoi(argv[optind++], &error)) < 1 || error != 0)
+ usage();
+ count = -1;
+ }
+ if (argc > optind) {
+ if ((count = Atoi(argv[optind++], &error)) < 1 || error != 0)
+ usage();
+ }
+ /* check for extra options/operands */
+ if (argc > optind)
+ usage();
+
+ /* check options */
+ if (oflag && !rflag)
+ usage();
+
+ /* global initializations */
+ if (!oflag) {
+ /* create the default print sequences */
+ (void) create_prt_sequence_list(NULL, &pool_lf);
+ (void) create_prt_sequence_list(NULL, &pset_lf);
+ }
+
+ if (rtypes == NULL || strcmp(rtypes->ple_obj, "all") == 0) {
+ /* crate a default resource list */
+ FREE(rtypes);
+ rtypes = create_args_list("pset", NULL, " \t,");
+ }
+
+ if ((conf = pool_conf_alloc()) == NULL)
+ die(gettext(ERR_NOMEM));
+ if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
+ != PO_SUCCESS)
+ die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
+
+ /* initialize statistic adapters */
+ sa_libpool_init(conf);
+ sa_kstat_init(NULL);
+
+ /* collect and print out statistics */
+ while (count-- != 0) {
+ sa_update(pool_sbag, SA_REFRESH);
+ if (pool_sbag->sb_changed & POU_POOL)
+ (void) printf(
+ "<<State change>>\n");
+ prt_pool_stats(pnames);
+ if (count != 0) {
+ (void) sleep(interval);
+ if (rflag)
+ (void) printf("\n");
+ }
+ }
+
+ return (E_PO_SUCCESS);
+}
+
+/*
+ * Take the arguments and create/append a string list to the 'le' list.
+ */
+static poolstat_list_element_t *
+create_args_list(char *arg, poolstat_list_element_t *le, const char *delim)
+{
+ poolstat_list_element_t *head = le;
+
+ while (arg != NULL && *arg != '\0') {
+ char *name = arg;
+ arg = strpbrk(arg, delim);
+ if (arg != NULL) {
+ *arg++ = '\0';
+ }
+ if (le == NULL) {
+ /* create first element */
+ NEW0(le);
+ head = le;
+ } else {
+ /* find last and append */
+ while (le->ple_next != NULL)
+ le = le->ple_next;
+ NEW0(le->ple_next);
+ le = le->ple_next;
+ }
+ le->ple_obj = (void *)name;
+ }
+
+ return (head);
+}
+
+/*
+ * Take the arguments to the -o option, and create a format field list in order
+ * specified by 'arg'.
+ * If 'arg' is NULL a list in a default printing order is created.
+ */
+static poolstat_list_element_t *
+create_prt_sequence_list(char *arg, poolstat_line_format_t *lf)
+{
+ /*
+ * Create a default print sequence. It is the sequence defined
+ * statically in the format list. At the same time mark the fields
+ * printable according to the current option settings.
+ */
+ if (arg == NULL) {
+ int i;
+ NEW0(lf->plf_prt_seq);
+ lf->plf_ffs[0].pff_prt |= PRINTABLE(0) ? PABLE_FIELD : 0;
+ lf->plf_last = lf->plf_prt_seq;
+ lf->plf_last->ple_obj = &(lf->plf_ffs[0]);
+ for (i = 1; i < lf->plf_ff_len; i++) {
+ lf->plf_ffs[i].pff_prt |=
+ PRINTABLE(i) ? PABLE_FIELD : 0;
+ NEW0(lf->plf_last->ple_next);
+ lf->plf_last = lf->plf_last->ple_next;
+ lf->plf_last->ple_obj = &(lf->plf_ffs[i]);
+ }
+ return (lf->plf_prt_seq);
+ }
+
+ while (arg != NULL && *arg != '\0') {
+ poolstat_field_format_t *ff; /* current format field */
+ int ffIdx; /* format field index */
+ char *name; /* name of field */
+ int n; /* no. of chars to strip */
+
+ n = strspn(arg, " ,\t\r\v\f\n");
+ arg += n; /* strip multiples separator */
+ name = arg;
+
+ if (strlen(name) < 1)
+ break;
+
+ if ((arg = strpbrk(arg, " ,\t\r\v\f\n")) != NULL)
+ *arg++ = '\0';
+
+ /* search for a named format field */
+ for (ffIdx = 0; ffIdx < lf->plf_ff_len; ffIdx++) {
+ ff = lf->plf_ffs + ffIdx;
+ if (strcmp(ff->pff_name, name) == 0) {
+ ff->pff_prt |= PABLE_FIELD;
+ break;
+ }
+ }
+ /* if the name wasn't found */
+ if (ffIdx == lf->plf_ff_len) {
+ (void) fprintf(stderr, gettext(ERR_UNSUPP_STAT_FIELD),
+ name);
+ usage();
+ }
+ if (lf->plf_last == NULL) {
+ /* create first print handle */
+ NEW0(lf->plf_prt_seq);
+ lf->plf_last = lf->plf_prt_seq;
+ } else {
+ NEW0(lf->plf_last->ple_next);
+ lf->plf_last = lf->plf_last->ple_next;
+ }
+ lf->plf_last->ple_obj = ff; /* refer to the format field */
+ }
+
+ return (lf->plf_prt_seq);
+}
+
+/* update the statistic data by adapters */
+static void
+sa_update(statistic_bag_t *sbag, int flags)
+{
+ sa_libpool_update(sbag, flags);
+ sa_kstat_update(sbag, flags);
+}
+
+/*
+ * Format one statistic field and put it into the 'str' buffer. 'ff' contains
+ * the field formatting parameters. Return the number of used bytes.
+ */
+static int
+default_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
+{
+ int used;
+
+ switch (ff->pff_type) {
+ case LL: {
+ int64_t v;
+ v = *((int64_t *)(void *)(data + ff->pff_offset));
+ used = snprintf(str + pos, left, "%*.*lld",
+ ff->pff_width, ff->pff_minwidth, v);
+ }
+ break;
+ case ULL: {
+ uint64_t v;
+ v = *((uint64_t *)(void *)(data + ff->pff_offset));
+ used = snprintf(str + pos, left, "%*.*llu",
+ ff->pff_width, ff->pff_minwidth, v);
+ };
+ break;
+ case FL: {
+ int pw = 0;
+ double v = *((double *)(void *)(data + ff->pff_offset));
+ if (v < 10) {
+ pw = ff->pff_width - 2;
+ } else if (v < 100) {
+ pw = ff->pff_width - 3;
+ } else if (v < 1000) {
+ pw = ff->pff_width - 4;
+ }
+ if (pw < 0)
+ pw = 0;
+ used = snprintf(str + pos, left, "%*.*f",
+ ff->pff_width, pw, v);
+ };
+ break;
+ case STR: {
+ char *v;
+ int sl;
+ v = *((char **)(void *)(data + ff->pff_offset));
+ sl = strlen(v);
+ /* truncate if it doesn't fit */
+ if (sl > ff->pff_width) {
+ char *cp = v + ff->pff_width - 1;
+ if (ff->pff_width < 4)
+ die(gettext(ERR_STATS_FORMAT),
+ ff->pff_header);
+ *cp-- = 0;
+ *cp-- = '.';
+ *cp-- = '.';
+ *cp-- = '.';
+ }
+ used = snprintf(str + pos, left, "%-*s", ff->pff_width,
+ v);
+ }
+ break;
+ }
+
+ return (used);
+}
+
+/* format big numbers */
+static int
+bigno_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
+{
+ uint64_t v;
+ char tag;
+ int pw = ff->pff_width - 4;
+ double pv;
+ int used;
+
+ v = *((uint64_t *)(void *)(data + ff->pff_offset));
+ /*
+ * the max value can be ULONG_MAX, which is formatted as:
+ * E P T G M K
+ * 18 446 744 073 709 551 615
+ * As a result ULONG_MAX is displayed as 18E
+ */
+ pv = v;
+ if (v < 1000) {
+ pw = 0;
+ } else if (v < KILO * 10) {
+ pv = (double)v / KILO;
+ tag = 'K';
+ } else if (v < KILO * 100) {
+ pv = (double)v / KILO;
+ tag = 'K'; pw -= 1;
+ } else if (v < KILO * 1000) {
+ pv = (double)v / KILO;
+ tag = 'K'; pw -= 2;
+ } else if (v < MEGA * 10) {
+ pv = (double)v / MEGA;
+ tag = 'M';
+ } else if (v < MEGA * 100) {
+ pv = (double)v / MEGA;
+ tag = 'M'; pw -= 1;
+ } else if (v < MEGA * 1000) {
+ pv = (double)v / MEGA;
+ tag = 'M'; pw -= 2;
+ } else if (v < GIGA * 10) {
+ pv = (double)v / GIGA;
+ tag = 'G';
+ } else if (v < GIGA * 100) {
+ pv = (double)v / GIGA;
+ tag = 'G'; pw -= 1;
+ } else if (v < GIGA * 1000) {
+ pv = (double)v / GIGA;
+ tag = 'G'; pw -= 2;
+ } else if (v < TERA * 10) {
+ pv = (double)v / TERA;
+ tag = 'T';
+ } else if (v < TERA * 100) {
+ pv = (double)v / TERA;
+ tag = 'T'; pw -= 1;
+ } else if (v < TERA * 1000) {
+ pv = (double)v / TERA;
+ tag = 'T'; pw -= 2;
+ } else if (v < PETA * 10) {
+ pv = (double)v / PETA;
+ tag = 'P';
+ } else if (v < PETA * 100) {
+ pv = (double)v / PETA;
+ tag = 'P'; pw -= 1;
+ } else if (v < PETA * 1000) {
+ pv = (double)v / PETA;
+ tag = 'P'; pw -= 2;
+ } else if (v < EXA * 10) {
+ pv = (double)v / EXA;
+ tag = 'E';
+ } else if (v < EXA * 100) {
+ pv = (double)v / EXA;
+ tag = 'E'; pw -= 1;
+ } else {
+ pv = (double)v / EXA;
+ tag = 'E'; pw -= 2;
+ }
+ if (pw < 0)
+ pw = 0;
+ if (v < 1000)
+ used = snprintf(str + pos, left, "%*.*f",
+ ff->pff_width, pw, pv);
+ else
+ used = snprintf(str + pos, left, "%*.*f%c",
+ ff->pff_width - 1, pw, pv, tag);
+
+ return (used);
+}
+
+/* format usage statistic, if configuration has changed print '-'. */
+static int
+used_stat_f(char *str, int pos, int left, poolstat_field_format_t *ff,
+ char *data)
+{
+ int pw = 0;
+ double v = *((double *)(void *)(data + ff->pff_offset));
+ int used;
+
+ if (pool_sbag->sb_changed & POU_POOL) {
+ used = snprintf(str + pos, left, "%*c", ff->pff_width, '-');
+ } else {
+ if (v < 10) {
+ pw = ff->pff_width - 2;
+ } else if (v < 100) {
+ pw = ff->pff_width - 3;
+ } else if (v < 1000) {
+ pw = ff->pff_width - 4;
+ }
+ if (pw < 0)
+ pw = 0;
+ used = snprintf(str + pos, left, "%*.*f",
+ ff->pff_width, pw, v);
+ }
+ return (used);
+}
+
+/*
+ * Format one header field and put it into the 'str' buffer.
+ */
+/*ARGSUSED*/
+static int
+header_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
+{
+ int used = 0;
+
+ if (ff->pff_type == STR)
+ /* strings are left justified */
+ used = snprintf(str + pos, left, "%-*s",
+ ff->pff_width, ff->pff_header);
+ else
+ used = snprintf(str + pos, left, "%*s",
+ ff->pff_width, ff->pff_header);
+ return (used);
+}
+
+/*
+ * Print one statistic line according to the definitions in 'lf'.
+ */
+static void
+prt_stat_line(poolstat_line_format_t *lf)
+{
+ poolstat_list_element_t *le; /* list element in the print sequence */
+ char *line;
+ int pos = 0; /* position in the printed line */
+ int len = MAXLINE; /* the length of the line */
+ int left = len; /* chars left to use in the line */
+
+ line = ZALLOC(len);
+ for (le = lf->plf_prt_seq; le; le = le->ple_next) {
+ int used;
+ poolstat_field_format_t *ff =
+ (poolstat_field_format_t *)le->ple_obj;
+ /* if the filed is marked to be printed */
+ if (ff->pff_prt & PABLE_FIELD) {
+ if (((used = ff->pff_format(line, pos, left, ff,
+ *ff->pff_data_ptr)) + 1) >= left) {
+ /* if field doesn't fit allocate new space */
+ len += used + MAXLINE;
+ left += used + MAXLINE;
+ line = REALLOC(line, len);
+ if (((used = ff->pff_format(line, pos, left, ff,
+ *ff->pff_data_ptr)) + 1) >= left)
+ die(gettext(ERR_STATS_FORMAT), line);
+ }
+ left -= used;
+ pos += used;
+ if (le->ple_next != NULL) {
+ /* separate columns with a space */
+ line[pos++] = ' ';
+ left--;
+ }
+ }
+ }
+
+ (void) printf("%s\n", line);
+ FREE(line);
+}
+
+/*
+ * Print a statistics header line for a given resource type.
+ */
+static void
+prt_stat_hd(const char *type)
+{
+ poolstat_line_format_t *lf; /* line format */
+ poolstat_list_element_t *le; /* list element in the print sequence */
+ char *line;
+ int pos = 0; /* position in the printed line */
+ int len = MAXLINE; /* the length of the line */
+ int left = len; /* chars left to use in the line */
+
+ if (strcmp(type, POOL_TYPE_NAME) == 0) {
+ /* pool format needs an extra header */
+ (void) printf("%*s\n", 19 + 15, "pset");
+ lf = &pool_lf;
+ } else if (strcmp(type, PSET_TYPE_NAME) == 0) {
+ lf = &pset_lf;
+ } else {
+ die(gettext(ERR_UNSUPP_RTYPE), type);
+ }
+ line = ZALLOC(len);
+ for (le = lf->plf_prt_seq; le; le = le->ple_next) {
+ int used; /* used chars in line */
+ poolstat_field_format_t *ff =
+ (poolstat_field_format_t *)le->ple_obj;
+ /* if the filed is marked to be printed */
+ if (ff->pff_prt& PABLE_FIELD) {
+ if (((used = header_f(line, pos, left, ff, NULL)) + 1)
+ >= left) {
+ /* if field doesn't fit allocate new space */
+ len += used + MAXLINE;
+ left += used + MAXLINE;
+ line = REALLOC(line, len);
+ if (((used = header_f(line, pos, left, ff,
+ NULL)) + 1) >= left)
+ die(gettext(ERR_STATS_FORMAT), line);
+ }
+ left -= used;
+ pos += used;
+ if (le->ple_next != NULL) {
+ /* separate columns with a space */
+ line[pos++] = ' ';
+ left--;
+ }
+ }
+ }
+
+ /* only header line with non space characters should be printed */
+ pos = 0;
+ while (*(line + pos) != '\n') {
+ if (!isspace(*(line + pos))) {
+ (void) printf("%s\n", line);
+
+ break;
+ }
+ pos++;
+ }
+ FREE(line);
+}
+
+/*
+ * Create a pool value instance and set its name to 'name'.
+ */
+static pool_value_t *
+create_pool_value(const char *name)
+{
+ pool_value_t *pval;
+
+ if ((pval = pool_value_alloc()) == NULL) {
+ return (NULL);
+ }
+ if (pool_value_set_name(pval, name) != PO_SUCCESS) {
+ pool_value_free(pval);
+ return (NULL);
+ }
+
+ return (pval);
+}
+
+/*
+ * Find all resources of type 'rtype'.
+ * If 'pool_name' is defined find all resources bound to this pool.
+ */
+static pool_resource_t **
+get_resources(const char *pool_name, const char *rtype, uint_t *nelem)
+{
+ pool_resource_t **resources = NULL;
+ pool_value_t *pvals[] = { NULL, NULL, NULL};
+ pool_value_t *pv_sys_id;
+ pool_value_t *pv_name;
+ char *name_prop; /* set name property */
+
+ if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
+ if ((pv_sys_id = create_pool_value(PSET_SYSID)) == NULL)
+ goto on_error;
+ name_prop = PSET_NAME;
+ } else {
+ die(gettext(ERR_UNSUPP_RTYPE), rtype);
+ }
+
+ if ((pvals[0] = create_pool_value("type")) == NULL)
+ goto on_error;
+ if ((pool_value_set_string(pvals[0], rtype)) == -1)
+ goto on_error;
+
+ if ((pv_name = create_pool_value(name_prop)) == NULL)
+ goto on_error;
+
+ if (pool_name != NULL) {
+ /* collect resources associated to 'pool_name' */
+ pool_t *pool;
+ if ((pool = pool_get_pool(conf, pool_name)) == NULL)
+ die(gettext(ERR_STATS_POOL_N), pool_name);
+ if ((resources = pool_query_pool_resources(
+ conf, pool, nelem, pvals)) == NULL)
+ goto on_error;
+ } else {
+ /* collect all resources */
+ if ((resources =
+ pool_query_resources(conf, nelem, pvals)) == NULL)
+ goto on_error;
+ }
+
+ if (pv_name != NULL)
+ pool_value_free(pv_name);
+ if (pv_sys_id != NULL)
+ pool_value_free(pv_sys_id);
+ if (pvals[0] != NULL)
+ pool_value_free(pvals[0]);
+
+ return (resources);
+on_error:
+ die(gettext(ERR_STATS_RES), get_errstr());
+ /*NOTREACHED*/
+}
+
+/*
+ * Print statistics for all resources of type 'rtype' passed in 'resources'.
+ */
+static void
+prt_resource_stats_by_type(pool_resource_t **resources, const char *rtype)
+{
+ int i;
+ pool_elem_t *elem;
+ pool_value_t *pv_name;
+ char *name_prop;
+
+ poolstat_line_format_t *lf;
+ statistic_bag_t *sbag;
+
+ if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
+ name_prop = PSET_NAME;
+ lf = &pset_lf;
+ sbag = pset_sbag;
+ } else {
+ die(gettext(ERR_UNSUPP_RTYPE), rtype);
+ }
+
+ if ((pv_name = create_pool_value(name_prop)) == NULL)
+ goto on_error;
+
+ /* collect and print statistics for the given resources */
+ for (i = 0; resources[i] != NULL; i++) {
+ if ((elem = pool_resource_to_elem(conf, resources[i])) == NULL)
+ goto on_error;
+ if (pool_get_property(conf, elem, name_prop, pv_name) == -1)
+ goto on_error;
+ if (pool_value_get_string(pv_name, &sbag->sb_name) == -1)
+ goto on_error;
+ sa_update(sbag, 0);
+
+ prt_stat_line(lf);
+ }
+
+ if (pv_name != NULL)
+ pool_value_free(pv_name);
+ return;
+on_error:
+ die(gettext(ERR_STATS_RES), get_errstr());
+}
+
+/*
+ * Update statistics for all resources of type 'rtype' pased in 'resources'.
+ */
+static void
+update_resource_stats(pool_resource_t *resource, const char *rtype)
+{
+ pool_elem_t *elem;
+ pool_value_t *pv_name;
+ char *name_prop; /* set name property */
+
+ statistic_bag_t *sbag;
+
+ if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
+ name_prop = PSET_NAME;
+ sbag = pset_sbag;
+ } else {
+ die(gettext(ERR_UNSUPP_RTYPE), rtype);
+ }
+
+ if ((pv_name = create_pool_value(name_prop)) == NULL)
+ goto on_error;
+
+ if ((elem = pool_resource_to_elem(conf, resource)) == NULL)
+ goto on_error;
+ if (pool_get_property(conf, elem, name_prop, pv_name) == -1)
+ goto on_error;
+ if (pool_value_get_string(pv_name, &sbag->sb_name) == -1)
+ goto on_error;
+ sa_update(sbag, 0);
+
+ if (pv_name != NULL)
+ pool_value_free(pv_name);
+ return;
+
+on_error:
+ die(gettext(ERR_STATS_RES), get_errstr());
+}
+
+/*
+ * For each pool in the configuration print statistics of associated resources.
+ * If the pool name list 'pn' is defined, only print resources of pools
+ * specified in the list. The list can specify the pool name or its system id.
+ */
+static void
+prt_pool_stats(poolstat_list_element_t *pn)
+{
+ uint_t nelem;
+ pool_elem_t *elem;
+ int i;
+ int error;
+ pool_t **pools = NULL;
+ pool_value_t *pvals[] = { NULL, NULL };
+ pool_value_t *pv_name = NULL;
+ pool_value_t *pv_sys_id = NULL;
+ statistic_bag_t *sbag = pool_sbag;
+ poolstat_list_element_t *rtype;
+ pool_resource_t **resources;
+
+ if ((pv_sys_id = create_pool_value(POOL_SYSID)) == NULL)
+ goto on_error;
+ if ((pv_name = create_pool_value(POOL_NAME)) == NULL)
+ goto on_error;
+
+ if (pn == NULL) {
+ /* collect all pools */
+ if ((pools = pool_query_pools(conf, &nelem, NULL)) == NULL)
+ goto on_error;
+ } else {
+ /*
+ * collect pools specified in the 'pn' list.
+ * 'poolid' the pool identifier can be a pool name or sys_id.
+ */
+ poolstat_list_element_t *poolid;
+ for (poolid = pn, i = 1; poolid; poolid = poolid->ple_next)
+ i++;
+ pools = ZALLOC(sizeof (pool_t *) * (i + 1));
+ for (poolid = pn, i = 0; poolid;
+ poolid = poolid->ple_next, i++) {
+ pool_t **pool;
+ int64_t sysid = Atoi(poolid->ple_obj, &error);
+ if (error == 0) {
+ /* the pool is identified by sys_id */
+ pool_value_set_int64(pv_sys_id, sysid);
+ pvals[0] = pv_sys_id;
+ pool = pool_query_pools(conf, &nelem, pvals);
+ } else {
+ if (pool_value_set_string(pv_name,
+ poolid->ple_obj) == -1)
+ die(gettext(ERR_NOMEM));
+ pvals[0] = pv_name;
+ pool = pool_query_pools(conf, &nelem, pvals);
+ }
+ if (pool == NULL)
+ die(gettext(ERR_STATS_POOL_N), poolid->ple_obj);
+ pools[i] = pool[0];
+ FREE(pool);
+ }
+ }
+
+ /* print statistic for all pools found */
+ if (!rflag) {
+ /* print the common resource header */
+ prt_stat_hd(POOL_TYPE_NAME);
+
+ /* print statistics for the resources bound to the pools */
+ for (i = 0; pools[i] != NULL; i++) {
+ elem = pool_to_elem(conf, pools[i]);
+ if (pool_get_property(conf, elem, POOL_NAME, pv_name)
+ == -1)
+ goto on_error;
+ if (pool_value_get_string(pv_name, &sbag->sb_name) != 0)
+ goto on_error;
+ if (pool_get_property(
+ conf, elem, "pool.sys_id", pv_sys_id) == -1)
+ goto on_error;
+ if (pool_value_get_int64(
+ pv_sys_id, &sbag->sb_sysid) != 0)
+ goto on_error;
+
+ for (rtype = rtypes; rtype; rtype = rtype->ple_next) {
+ resources = get_resources(
+ sbag->sb_name, rtype->ple_obj, &nelem);
+ update_resource_stats(*resources,
+ rtype->ple_obj);
+ FREE(resources);
+ }
+ prt_stat_line(&pool_lf);
+ }
+ } else {
+ /* print statistic for all resource types defined in rtypes */
+ for (rtype = rtypes; rtype; rtype = rtype->ple_next) {
+ prt_stat_hd(rtype->ple_obj);
+ for (i = 0; pools[i] != NULL; i++) {
+ elem = pool_to_elem(conf, pools[i]);
+ if (pool_get_property(
+ conf, elem, POOL_NAME, pv_name) == -1)
+ goto on_error;
+ if (pool_value_get_string(
+ pv_name, &sbag->sb_name) != 0)
+ goto on_error;
+ if (pool_get_property(
+ conf, elem, POOL_SYSID, pv_sys_id)
+ == -1)
+ goto on_error;
+ if (pool_value_get_int64(
+ pv_sys_id, &sbag->sb_sysid) != 0)
+ goto on_error;
+ resources = get_resources(
+ sbag->sb_name, rtype->ple_obj, &nelem);
+ if (resources == NULL)
+ continue;
+ update_resource_stats(
+ *resources, rtype->ple_obj);
+ prt_resource_stats_by_type(resources,
+ rtype->ple_obj);
+ FREE(resources);
+ }
+ }
+ }
+
+ FREE(pools);
+ if (pv_name != NULL)
+ pool_value_free(pv_name);
+ if (pv_sys_id != NULL)
+ pool_value_free(pv_sys_id);
+
+ return;
+on_error:
+ die(gettext(ERR_STATS_POOL), get_errstr());
+}
diff --git a/usr/src/cmd/pools/poolstat/poolstat.h b/usr/src/cmd/pools/poolstat/poolstat.h
new file mode 100644
index 0000000000..ba5204c33d
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/poolstat.h
@@ -0,0 +1,190 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _POOLSTAT_H
+#define _POOLSTAT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following are types and defines used to collect statistic data.
+ * Different statistic providers can be used to collect the data.
+ * Two functions build the interface to each provider:
+ * 'provider'_init(), and 'provider'_update(). In the update function
+ * a provider fills out the passed data structure with statistics data
+ * it is responsible for.
+ */
+
+/* Error messages for poolstat */
+#define ERR_LOAD_AVERAGE "cannot get load average: %s\n"
+#define ERR_BINDING "cannot get resource binding: %s\n"
+#define ERR_STATS_POOL_N "cannot get statistics for pool '%s'\n"
+#define ERR_STATS_RES_N "cannot get statistics for resource '%s': %s\n"
+#define ERR_STATS_POOL "cannot get pool statistics: %s\n"
+#define ERR_STATS_RES "cannot get resource statistics: %s\n"
+#define ERR_STATS_FORMAT "cannot format statistic line: %s\n"
+#define ERR_KSTAT_OPEN "kstat open failed: %s\n"
+#define ERR_KSTAT_DATA "cannot get kstat data: %s\n"
+#define ERR_KSTAT_DLOOKUP "kstat_data_lookup('%s', '%s') failed: %s\n"
+#define ERR_OPTION_ARGS "Option -%c requires an argument\n"
+#define ERR_OPTION "poolstat: illegal option -- %c\n"
+#define ERR_CONF_UPDATE "pool configuration update failed: %s\n"
+#define ERR_UNSUPP_STYPE "unsupported statistic type: %s\n"
+#define ERR_UNSUPP_RTYPE "unsupported resource type: %s\n"
+#define ERR_UNSUPP_STAT_FIELD "unsupported statistic field: %s\n"
+
+#define POOL_TYPE_NAME "pool"
+#define PSET_TYPE_NAME "pset"
+#define POOL_SYSID "pool.sys_id"
+#define PSET_SYSID "pset.sys_id"
+
+/* set types */
+typedef enum { ST_PSET } st_t;
+
+/* update flag, forces refresh of statistic data */
+#define SA_REFRESH 1
+
+/* data bag used to collect statistics for a processor set */
+typedef struct {
+ int64_t pset_sb_sysid;
+ uint64_t pset_sb_min;
+ uint64_t pset_sb_max;
+ uint64_t pset_sb_size;
+ double pset_sb_used;
+ double pset_sb_load;
+ uint64_t pset_sb_changed;
+} pset_statistic_bag_t;
+
+/* wrapper for different statistic bags */
+typedef struct {
+ const char *sb_name; /* pool or resource name used as identifier */
+ int64_t sb_sysid; /* the sysid */
+ const char *sb_type; /* the type can be "pool", or "pset" */
+ uint64_t sb_changed;
+ void* bag;
+} statistic_bag_t;
+
+/* shortcut to access a element in the pset statistic bag. */
+#define PSETBAG_ELEM(p, e) (((pset_statistic_bag_t *)(p)->bag)->e)
+
+/* statistic adapters */
+extern void sa_libpool_init(void *);
+extern void sa_libpool_update(statistic_bag_t *sbag, int flags);
+extern void sa_kstat_init(void *);
+extern void sa_kstat_update(statistic_bag_t *sbag, int flags);
+
+/*
+ * The following types and defines are used to format statistic lines.
+ * All formatting information for a particular line are grouped in 'lf_t'
+ * structure.
+ * Two data sequences are anchored there: an array with all possible formatting
+ * directives for fields that can occur in a statistic line, and a list with
+ * pointers to elements in this array. This list defines which fields and in
+ * which order should be printed.
+ * Formatting directives for one field are grouped in 'poolstat_field_format_t'
+ * structure. Basically it contains a pointer to a formatting function and some
+ * formatting parameters used by this function.
+ */
+
+/* the length of a statistic line */
+#define MAXLINE 160
+/* default print field */
+#define D_FIELD 0x01
+/* -x option print field */
+#define X_FIELD 0x02
+/* -o option print field */
+#define O_FIELD 0x04
+
+/* print field in default and extended mode */
+#define DX_FIELD (D_FIELD | X_FIELD)
+
+/* marks a field as printable */
+#define PABLE_FIELD 0x80
+
+#define KILO 1000
+#define MEGA ((uint64_t)(KILO * 1000))
+#define GIGA ((uint64_t)(MEGA * 1000))
+#define TERA ((uint64_t)(GIGA * 1000))
+#define PETA ((uint64_t)(TERA * 1000))
+#define EXA ((uint64_t)(PETA * 1000))
+
+#define KBYTE 1024
+#define MBYTE ((uint64_t)(KBYTE * 1024))
+#define GBYTE ((uint64_t)(MBYTE * 1024))
+#define TBYTE ((uint64_t)(GBYTE * 1024))
+#define PBYTE ((uint64_t)(TBYTE * 1024))
+#define EBYTE ((uint64_t)(PBYTE * 1024))
+
+/* statistic data types */
+typedef enum { ULL, LL, FL, STR } dt_t;
+
+/* poolstat_field_format_t contains information for one statistic field */
+typedef struct poolstat_field_format {
+ int pff_prt; /* printable flag */
+ const char *pff_name; /* name of the statistic */
+ const char *pff_header;
+ const dt_t pff_type; /* the data type */
+ int pff_width; /* width, excluding whitespace */
+ const int pff_minwidth;
+ char **pff_data_ptr;
+ const size_t pff_offset; /* offset in a data block */
+ /* formatter */
+ int (* pff_format)
+ (char *, int, int, struct poolstat_field_format *, char *);
+} poolstat_field_format_t;
+
+/* list element, used to link arbitrary objects in a list */
+typedef struct _myself {
+ void *ple_obj;
+ struct _myself *ple_next;
+} poolstat_list_element_t;
+
+/*
+ * poolstat_line_format_t contains formatting information for one
+ * statistics line.
+ */
+typedef struct {
+ /* pointer to an array with all format fields */
+ poolstat_field_format_t *plf_ffs;
+ /* the lenght of format field array */
+ int plf_ff_len;
+ /* the field's print sequence */
+ poolstat_list_element_t *plf_prt_seq;
+ /* pointer to the last field in prt. sequence */
+ poolstat_list_element_t *plf_last;
+} poolstat_line_format_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _POOLSTAT_H */
diff --git a/usr/src/cmd/pools/poolstat/poolstat_utils.c b/usr/src/cmd/pools/poolstat/poolstat_utils.c
new file mode 100644
index 0000000000..28c1f44fce
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/poolstat_utils.c
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libintl.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+
+#include "utils.h"
+#include "poolstat_utils.h"
+
+void *
+Realloc(void *ptr, size_t nbytes)
+{
+ if ((ptr = realloc(ptr, nbytes)))
+ return (ptr);
+
+ die(gettext(ERR_NOMEM));
+ /*NOTREACHED*/
+}
+
+void *
+Zalloc(size_t nbytes)
+{
+ return (memset(Realloc(NULL, nbytes), 0, nbytes));
+}
diff --git a/usr/src/cmd/pools/poolstat/poolstat_utils.h b/usr/src/cmd/pools/poolstat/poolstat_utils.h
new file mode 100644
index 0000000000..7beb2d5637
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/poolstat_utils.h
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _POOLSTAT_UTILS_H
+#define _POOLSTAT_UTILS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REALLOC(p, nbytes) Realloc((p), (nbytes))
+#define ZALLOC(nbytes) Zalloc((nbytes))
+
+#define FREE(p) ((void) (free((p)), (p) = 0))
+#define NEW0(p) ((p) = ZALLOC((long)sizeof (*(p))))
+
+extern void *Zalloc(size_t);
+extern void *Realloc(void *, size_t);
+extern void Free(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _POOLSTAT_UTILS_H */
diff --git a/usr/src/cmd/pools/poolstat/sa_kstat.c b/usr/src/cmd/pools/poolstat/sa_kstat.c
new file mode 100644
index 0000000000..465e38f1d1
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/sa_kstat.c
@@ -0,0 +1,346 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * sa_kstat - kstat statistic adapter, collects statistic data provided
+ * by kstat.
+ */
+
+#include <locale.h>
+#include <string.h>
+#include <assert.h>
+#include <kstat.h>
+#include <pool.h>
+#include "utils.h"
+#include <sys/pset.h>
+#include "poolstat.h"
+#include "poolstat_utils.h"
+
+/* marks 'sdata_t' element as updated */
+#define SD_UPDATED 1
+
+/* Specified value for an invalid set. */
+#define INVALID_SET -2
+
+/* statistic data */
+typedef struct sdata {
+ kstat_t sd_oks; /* old kstat */
+ kstat_t sd_nks; /* new kstat */
+ void *sd_udata; /* user data */
+ uint_t sd_state; /* state of this data (UPDATED) */
+ struct sdata *sd_next;
+} sdata_t;
+
+/* pset user data */
+typedef struct {
+ psetid_t opset; /* old pset sysid */
+ psetid_t npset; /* new pset sysid */
+} pset_ud_t;
+
+/* shortcuts to access set's id in 'pset_ud_t' */
+#define SD_OPSET(p) (((pset_ud_t *)(p)->sd_udata)->opset)
+#define SD_NPSET(p) (((pset_ud_t *)(p)->sd_udata)->npset)
+
+static kstat_ctl_t *ks_ctl; /* libkstat handle */
+static sdata_t *cpu_list; /* list with cpu statistics */
+
+static sdata_t *update_sdata_list(sdata_t *, kstat_ctl_t *, char *, int,
+ char *, int *);
+static void update_cpu_list(sdata_t *list);
+static void update_pset_stats(statistic_bag_t *, sdata_t *);
+
+/*ARGSUSED*/
+void
+sa_kstat_init(void *unused)
+{
+ if ((ks_ctl = kstat_open()) == NULL)
+ die(gettext(ERR_KSTAT_OPEN), get_errstr());
+}
+
+void
+sa_kstat_update(statistic_bag_t *sbag, int flags)
+{
+ /* The SA_REFRESH flag forces the update of local data structures. */
+ if (flags & SA_REFRESH) {
+ int ks_error = 0;
+
+ if (kstat_chain_update(ks_ctl) == -1)
+ die(gettext(ERR_KSTAT_DATA), get_errstr());
+ cpu_list = update_sdata_list(cpu_list, ks_ctl, "cpu",
+ -1, "sys", &ks_error);
+ if (ks_error)
+ die(gettext(ERR_KSTAT_DATA), get_errstr());
+
+ /* update info about cpu binding to processor sets */
+ update_cpu_list(cpu_list);
+ }
+
+ if (strcmp(sbag->sb_type, PSET_TYPE_NAME) == 0) {
+ update_pset_stats(sbag, cpu_list);
+ } else if (strcmp(sbag->sb_type, POOL_TYPE_NAME) == 0) {
+ return;
+ } else {
+ die(gettext(ERR_UNSUPP_STYPE), sbag->sb_type);
+ }
+
+}
+
+static void *
+safe_kstat_data_lookup(kstat_t *ksp, char *name)
+{
+ void *dp;
+
+ if ((dp = kstat_data_lookup(ksp, name)) == NULL)
+ die(gettext(ERR_KSTAT_DLOOKUP),
+ ksp->ks_name, name, get_errstr());
+
+ return (dp);
+}
+
+/*
+ * Find the delta over the interval between new_ksp and old_ksp.
+ * If old_ksp->ks_data is NULL and 'oz' is set then pretend
+ * that old_ksp is zero otherwise return 0.
+ */
+static uint64_t
+delta(kstat_t *new_ksp, kstat_t *old_ksp, char *name, int oz)
+{
+ kstat_named_t *new_ksn;
+ kstat_named_t *old_ksn;
+
+ new_ksn = (kstat_named_t *)safe_kstat_data_lookup(new_ksp, name);
+ if (old_ksp == NULL || old_ksp->ks_data == NULL)
+ return ((oz == 1) ? new_ksn->value.ui64 : 0);
+ old_ksn = (kstat_named_t *)safe_kstat_data_lookup(old_ksp, name);
+
+ return (new_ksn->value.ui64 - old_ksn->value.ui64);
+}
+
+/*
+ * Create a clone of the passed kstat_t structure 'kstat_t'. If
+ * 'fr' flag is set free the old ks_data structure in 'dst'.
+ */
+static void
+kstat_clone(kstat_t *src, kstat_t *dst, int fr)
+{
+ if (fr)
+ FREE(dst->ks_data);
+ *dst = *src;
+ if (src->ks_data != NULL) {
+ dst->ks_data = ZALLOC(src->ks_data_size);
+ (void) memcpy(dst->ks_data, src->ks_data, src->ks_data_size);
+ } else {
+ dst->ks_data = NULL;
+ dst->ks_data_size = 0;
+ }
+}
+
+/*
+ * Erase the data from 'src'.
+ */
+static void
+kstat_erase(kstat_t *src)
+{
+ FREE(src->ks_data);
+ (void) memset(src, 0, sizeof (*src));
+}
+
+/*
+ * Create a new statistic data object with its own copy of the passed
+ * kstat.
+ */
+static sdata_t *
+sdata_new(kstat_t *ksp)
+{
+ sdata_t *sdp;
+
+ NEW0(sdp);
+ kstat_clone(ksp, &sdp->sd_nks, 0);
+
+ return (sdp);
+}
+
+static void
+sdata_free(sdata_t *sdp)
+{
+ FREE(sdp->sd_oks.ks_data);
+ FREE(sdp->sd_nks.ks_data);
+ FREE(sdp->sd_udata);
+ FREE(sdp);
+}
+
+/*
+ * Create new or update an existing list of cpu statistics. For each
+ * cpu two kstats are kept. One old kstat which contains the data from
+ * the previous scan, and new with the current data. The old and the new
+ * kstats *must* be for the same instance and have the same kid.
+ * If 'instance' argument is set to -1 don't use it as a filter.
+ */
+static sdata_t *
+update_sdata_list(sdata_t *list, kstat_ctl_t *kc, char *module,
+ int instance, char *name, int *errp)
+{
+ kstat_t *ksp;
+ sdata_t *sdp, *sdpp; /* kstat instance pointer/previous-pointer */
+
+ for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
+ if (strcmp(ksp->ks_module, module) == 0 &&
+ (name == NULL || strcmp(ksp->ks_name, name) == 0) &&
+ (instance == -1 || ksp->ks_instance == instance)) {
+ if (kstat_read(kc, ksp, NULL) == -1) {
+ *errp = -1;
+ return (list);
+ }
+ /*
+ * Find the kstat in the existing list:
+ * If we find one for the same instance and with the
+ * same ks_kid we'll save it as old_kstat.
+ * If we find one for the same instance but with a
+ * different ks_kid we'll removed it.
+ */
+ for (sdpp = sdp = list; sdp; sdp = sdp->sd_next) {
+ if (ksp->ks_instance ==
+ sdp->sd_nks.ks_instance) {
+ if (ksp->ks_kid == sdp->sd_nks.ks_kid) {
+ kstat_clone(&sdp->sd_nks,
+ &sdp->sd_oks, 1);
+ } else {
+ kstat_erase(&sdp->sd_oks);
+ }
+ kstat_clone(ksp, &sdp->sd_nks, 1);
+ sdp->sd_state |= SD_UPDATED;
+ break;
+ }
+ sdpp = sdp;
+ }
+ /* add a new kstat instance */
+ if (!sdp) {
+ /* first instance */
+ if (!list) {
+ list = sdata_new(ksp);
+ list->sd_state |= SD_UPDATED;
+ } else {
+ sdpp->sd_next = sdata_new(ksp);
+ sdpp->sd_next->sd_state |= SD_UPDATED;
+ }
+ }
+ }
+ }
+
+ /* remove untouched statistics */
+ sdp = list;
+ sdpp = NULL;
+ while (sdp != NULL) {
+
+ if (sdp->sd_state & SD_UPDATED) {
+ sdp->sd_state &= ~SD_UPDATED;
+ sdpp = sdp;
+ sdp = sdp->sd_next;
+ } else {
+ sdata_t *tmp;
+
+ if (sdpp == NULL)
+ list = sdp->sd_next;
+ else
+ sdpp->sd_next = sdp->sd_next;
+ tmp = sdp->sd_next;
+ sdata_free(sdp);
+ sdp = tmp;
+ }
+ }
+
+ *errp = 0;
+ return (list);
+}
+
+/*
+ * Update the pset assignment information for each cpu in the statistic
+ * data list.
+ */
+static void
+update_cpu_list(sdata_t *list)
+{
+ sdata_t *sdp;
+
+ for (sdp = list; sdp; sdp = sdp->sd_next) {
+ /* for new CPU create a new user data object */
+ if (sdp->sd_udata == NULL) {
+ sdp->sd_udata = ZALLOC(sizeof (pset_ud_t));
+ /*
+ * set its pset to invalid, so it will not be
+ * used in statistics calculation.
+ */
+ SD_NPSET(sdp) = INVALID_SET;
+ }
+ /* copy the pset assignment information to the previous stat */
+ SD_OPSET(sdp) = SD_NPSET(sdp);
+ /* set the current assignment */
+ if (pset_assign(PS_QUERY, sdp->sd_nks.ks_instance,
+ &(SD_NPSET(sdp))) == -1)
+ SD_NPSET(sdp) = INVALID_SET;
+ }
+}
+
+/*
+ * Update statistic data for pset. Calculate the CPU usage in a pset.
+ */
+static void
+update_pset_stats(statistic_bag_t *sbag, sdata_t *list)
+{
+ sdata_t *sdp;
+ pset_statistic_bag_t *bag = (pset_statistic_bag_t *)sbag->bag;
+ uint64_t allticks, ust, kst, ist, wst;
+
+ ust = kst = ist = wst = 0;
+ for (sdp = list; sdp; sdp = sdp->sd_next) {
+ /*
+ * only calculate for the asked pset id and if the cpu belongs
+ * to the same set in the previous and in the current snapshot.
+ * It means that the usage for CPUs that were rebound during
+ * the sampling interval are not charged to any set.
+ */
+ if ((SD_OPSET(sdp) == SD_NPSET(sdp)) &&
+ (SD_NPSET(sdp) == bag->pset_sb_sysid)) {
+ ust += delta(&sdp->sd_nks, &sdp->sd_oks,
+ "cpu_ticks_user", 0);
+ kst += delta(&sdp->sd_nks, &sdp->sd_oks,
+ "cpu_ticks_kernel", 0);
+ ist += delta(&sdp->sd_nks, &sdp->sd_oks,
+ "cpu_ticks_idle", 0);
+ wst += delta(&sdp->sd_nks, &sdp->sd_oks,
+ "cpu_ticks_wait", 0);
+ }
+ }
+
+ if ((allticks = ust + kst + wst + ist) != 0) {
+ bag->pset_sb_used =
+ (double)(ust + kst) / allticks * bag->pset_sb_size;
+ } else {
+ bag->pset_sb_used = 0.0;
+ }
+}
diff --git a/usr/src/cmd/pools/poolstat/sa_libpool.c b/usr/src/cmd/pools/poolstat/sa_libpool.c
new file mode 100644
index 0000000000..6b2642eed3
--- /dev/null
+++ b/usr/src/cmd/pools/poolstat/sa_libpool.c
@@ -0,0 +1,156 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * sa_libpool - libpool statistic adapter, collect statistic data provided
+ * by libpool.
+ */
+
+#include <string.h>
+#include <locale.h>
+#include <assert.h>
+
+#include <pool.h>
+
+#include "utils.h"
+#include "poolstat.h"
+
+typedef int (*prop_walk_cb_t)
+ (pool_conf_t *, pool_elem_t *, const char *, pool_value_t *, void *);
+
+/* user data used in the property walk callback function. */
+typedef struct {
+ int ud_result;
+ void* ud_bag;
+} userdata_cb_t;
+
+static pool_conf_t *conf;
+static const char *conf_loc;
+
+static void update_pset(statistic_bag_t *);
+
+/*
+ * If not NULL use the passed 'configuration' to access the pool framework,
+ * otherwise create and open a private access point.
+ */
+void
+sa_libpool_init(void *configuration)
+{
+ if (configuration) {
+ conf = configuration;
+ } else {
+ conf_loc = pool_dynamic_location();
+ if ((conf = pool_conf_alloc()) == NULL)
+ die(gettext(ERR_NOMEM));
+ if (pool_conf_open(conf, conf_loc, PO_RDONLY | PO_UPDATE)
+ != PO_SUCCESS)
+ die(gettext(ERR_OPEN_STATIC), conf_loc, get_errstr());
+ }
+}
+
+/*ARGSUSED*/
+void
+sa_libpool_update(statistic_bag_t *sbag, int flags)
+{
+ static int changed;
+
+ /* The SA_REFRESH flag forces the update of local data structures. */
+ if (flags & SA_REFRESH) {
+ changed = 0;
+ if (pool_conf_update(conf, &changed) != PO_SUCCESS)
+ die(gettext(ERR_CONF_UPDATE), get_errstr());
+ sbag->sb_changed = changed;
+ }
+ if (strcmp(sbag->sb_type, PSET_TYPE_NAME) == 0) {
+ if (changed & POU_PSET || changed & POU_CPU)
+ ((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
+ changed;
+ else
+ ((pset_statistic_bag_t *)sbag->bag)->pset_sb_changed =
+ 0;
+ update_pset(sbag);
+ } else if (strcmp(sbag->sb_type, POOL_TYPE_NAME) == 0) {
+ return;
+ } else {
+ die(gettext(ERR_UNSUPP_STYPE), sbag->sb_type);
+ }
+}
+
+/*
+ * callback function to property walker, copies the property value from
+ * the passed 'pvalue' to the corresponding field in the statistic data bag.
+ */
+/*ARGSUSED*/
+static int
+populate_userdata_cb(pool_conf_t *unused1, pool_elem_t *unused2,
+ const char *name, pool_value_t *pval, userdata_cb_t *ud)
+{
+ pset_statistic_bag_t *bag = (pset_statistic_bag_t *)ud->ud_bag;
+
+ ud->ud_result = 0;
+ if (strcmp("pset.min", name) == 0) {
+ ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_min);
+ } else if (strcmp("pset.max", name) == 0) {
+ ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_max);
+ } else if (strcmp("pset.load", name) == 0) {
+ uint64_t load;
+
+ ud->ud_result = pool_value_get_uint64(pval, &load);
+ bag->pset_sb_load = (double)load / 1000.0;
+ } else if (strcmp("pset.size", name) == 0) {
+ ud->ud_result = pool_value_get_uint64(pval, &bag->pset_sb_size);
+ } else if (strcmp("pset.sys_id", name) == 0) {
+ ud->ud_result = pool_value_get_int64(pval, &bag->pset_sb_sysid);
+ }
+
+ return (0);
+}
+
+/*
+ * Update statistic data for the procssor set with the name 'sbag->name'.
+ * Use 'sbag->bag' to store the data.
+ */
+static void
+update_pset(statistic_bag_t *sbag)
+{
+ pool_resource_t *pset_reso;
+ pool_elem_t *pset_elem;
+ userdata_cb_t ud;
+
+ ud.ud_bag = (void *) sbag->bag;
+ if ((pset_reso = pool_get_resource(conf, PSET_TYPE_NAME, sbag->sb_name))
+ == NULL)
+ die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
+ if ((pset_elem = pool_resource_to_elem(conf, pset_reso)) == NULL)
+ die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
+
+ /* use the property walker to collect the resource properties */
+ if (pool_walk_properties(conf, pset_elem, &ud,
+ (prop_walk_cb_t)populate_userdata_cb) == -1)
+ die(gettext(ERR_STATS_RES_N), sbag->sb_name, get_errstr());
+}