17c478bdstevel@tonic-gate%{
27c478bdstevel@tonic-gate/*
37c478bdstevel@tonic-gate * CDDL HEADER START
47c478bdstevel@tonic-gate *
57c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
67c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
77c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
87c478bdstevel@tonic-gate * with the License.
97c478bdstevel@tonic-gate *
107c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
117c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
127c478bdstevel@tonic-gate * See the License for the specific language governing permissions
137c478bdstevel@tonic-gate * and limitations under the License.
147c478bdstevel@tonic-gate *
157c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
167c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
177c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
187c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
197c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
207c478bdstevel@tonic-gate *
217c478bdstevel@tonic-gate * CDDL HEADER END
227c478bdstevel@tonic-gate *
2326d8ba2garypen * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate/*
287c478bdstevel@tonic-gate * Overview of poolcfg(1)
297c478bdstevel@tonic-gate *
307c478bdstevel@tonic-gate * poolcfg(1) implements a small grammar for manipulating pools configurations.
317c478bdstevel@tonic-gate * yacc(1) is used to generate the parser and poolcfg.l contains a simple lexer
327c478bdstevel@tonic-gate * (generted by lex(1)) to perform lexical processsing of the input.
337c478bdstevel@tonic-gate *
347c478bdstevel@tonic-gate * Refer to the poolcfg(1) manpage for more details of the grammar.
357c478bdstevel@tonic-gate *
367c478bdstevel@tonic-gate * The parser is designed so that all operations implement the same interface.
377c478bdstevel@tonic-gate * This allows the parser to simply build up the command (using the cmd
387c478bdstevel@tonic-gate * variable) by storing arguments and a pointer to the desired function in the
397c478bdstevel@tonic-gate * cmd. The command is executed when the commands production is matched.
407c478bdstevel@tonic-gate *
417c478bdstevel@tonic-gate * Properties and associations are stored in simple linked lists and processed
427c478bdstevel@tonic-gate * in the order submitted by the user.
437c478bdstevel@tonic-gate */
447c478bdstevel@tonic-gate
457c478bdstevel@tonic-gate#include <stdlib.h>
467c478bdstevel@tonic-gate#include <stdio.h>
477c478bdstevel@tonic-gate#include <string.h>
487c478bdstevel@tonic-gate#include <errno.h>
497c478bdstevel@tonic-gate#include <sys/types.h>
507c478bdstevel@tonic-gate#include <locale.h>
517c478bdstevel@tonic-gate#include <libintl.h>
527c478bdstevel@tonic-gate#include <sys/utsname.h>
537c478bdstevel@tonic-gate
547c478bdstevel@tonic-gate#include <pool.h>
557c478bdstevel@tonic-gate#include "utils.h"
567c478bdstevel@tonic-gate#include "poolcfg.h"
577c478bdstevel@tonic-gate
587c478bdstevel@tonic-gate
597c478bdstevel@tonic-gate
607c478bdstevel@tonic-gate#define	USAGE1	\
617c478bdstevel@tonic-gate"Usage:\n" \
627c478bdstevel@tonic-gate"%s -h\n" \
637c478bdstevel@tonic-gate"%s -c command [ -d | [ file ] ]\n" \
647c478bdstevel@tonic-gate"%s -f command-file [-d | [ file ] ]\n\n"
657c478bdstevel@tonic-gate
667c478bdstevel@tonic-gate#define	USAGE2	\
677c478bdstevel@tonic-gate"command:\n" \
687c478bdstevel@tonic-gate"  info [entity name]\n" \
697c478bdstevel@tonic-gate"         display configuration (or specified portion) in readable form\n" \
707c478bdstevel@tonic-gate"  create entity name [property-list]\n" \
717c478bdstevel@tonic-gate"         make an entity of the specified type and name\n" \
727c478bdstevel@tonic-gate"  destroy entity name\n" \
737c478bdstevel@tonic-gate"         remove the specified entity\n" \
747c478bdstevel@tonic-gate"  modify entity name [property-list]\n" \
757c478bdstevel@tonic-gate"         change the listed properties on the named entity\n" \
767c478bdstevel@tonic-gate"  associate pool name [resource-list]\n" \
777c478bdstevel@tonic-gate"         connect one or more resources to a pool, or replace one or more\n" \
787c478bdstevel@tonic-gate"         existing connections\n" \
797c478bdstevel@tonic-gate"  transfer to resource name [component-list]\n" \
807c478bdstevel@tonic-gate"         transfer one or more discreet components to a resource\n" \
817c478bdstevel@tonic-gate"  transfer [quantity] from resource src to tgt\n" \
827c478bdstevel@tonic-gate"         transfer a resource quantity from src to tgt\n" \
837c478bdstevel@tonic-gate"  transfer [quantity] to resource tgt from src\n" \
847c478bdstevel@tonic-gate"         transfer a resource quantity to tgt from src\n" \
857c478bdstevel@tonic-gate"  discover\n" \
867c478bdstevel@tonic-gate"         create a system entity, with one pool entity and resources to\n" \
877c478bdstevel@tonic-gate"         match current system configuration\n" \
887c478bdstevel@tonic-gate"  rename entity old_name to new_name\n" \
897c478bdstevel@tonic-gate"         change the name of the entity on the system to its new name\n\n" \
907c478bdstevel@tonic-gate"property-list:\n" \
917c478bdstevel@tonic-gate"  ( proptype name = value [ ; proptype name = value ]* )\n" \
927c478bdstevel@tonic-gate"         where multiple definitions in the sentence for a given\n" \
937c478bdstevel@tonic-gate"         proptype, name pair are ignored; the last one provided is used.\n" \
947c478bdstevel@tonic-gate"         For property deletion, use \"~ proptype name\"\n\n" \
957c478bdstevel@tonic-gate"resource-list:\n" \
967c478bdstevel@tonic-gate"  ( resource name [; resource name ] )\n" \
977c478bdstevel@tonic-gate"         where multiple uses of a resource are ignored; the last provided\n" \
987c478bdstevel@tonic-gate"         is the one used.\n" \
997c478bdstevel@tonic-gate"         There is no deletion syntax for resource lists.\n" \
1007c478bdstevel@tonic-gate"component-list:\n" \
1017c478bdstevel@tonic-gate"  ( cpu id [; cpu id ] )\n" \
1027c478bdstevel@tonic-gate"         where multiple uses of the same component cause the last provided\n" \
1037c478bdstevel@tonic-gate"         to be the one used.\n" \
1047c478bdstevel@tonic-gate"         There is no deletion syntax for component lists.\n" \
1057c478bdstevel@tonic-gate"entity:\n" \
1067c478bdstevel@tonic-gate"  system | pool | pset | cpu\n" \
1077c478bdstevel@tonic-gate"         where cpu is only valid for transfer, info and modify commands.\n" \
1087c478bdstevel@tonic-gate"resource:\n" \
1097c478bdstevel@tonic-gate"  pset\n\n" \
1107c478bdstevel@tonic-gate"proptype:\n" \
1117c478bdstevel@tonic-gate"  boolean | int | uint | string | float\n\n"
1127c478bdstevel@tonic-gate
1137c478bdstevel@tonic-gateint dofile = PO_FALSE;			/* poolcfg.l uses this for errors */
1147c478bdstevel@tonic-gateint conf_edit_error = POE_OK;		/* cached error for error reporting */
1157c478bdstevel@tonic-gateint conf_edit_errno = 0;		/* cached errno for error reporting */
1167c478bdstevel@tonic-gateint conf_list_error = POE_OK;		/* cached error for error reporting */
1177c478bdstevel@tonic-gateint conf_list_errno = 0;		/* cached errno for error reporting */
1187c478bdstevel@tonic-gatestatic const char cmdname[] = "poolcfg";
1197c478bdstevel@tonic-gatestatic const char cmd_options[] = "c:df:h";
1207c478bdstevel@tonic-gatestatic void usage(int);
1217c478bdstevel@tonic-gatestatic const char *max_suffix = ".max";
1227c478bdstevel@tonic-gatestatic const char *min_suffix = ".min";
1237c478bdstevel@tonic-gate
1247c478bdstevel@tonic-gatestatic const char *conf_file = NULL;	/* Location of target config */
1257c478bdstevel@tonic-gatestatic cmd_t *cmd = NULL;		/* Command being processed */
1267c478bdstevel@tonic-gatestatic pool_conf_t *conf = NULL;	/* Config to be processed */
1277c478bdstevel@tonic-gatestatic int edited = PO_FALSE;		/* Has the configuration been changed */
1287c478bdstevel@tonic-gate
1297c478bdstevel@tonic-gate/* yacc externals */
1307c478bdstevel@tonic-gateextern FILE *yyin;
1317c478bdstevel@tonic-gateextern int yydebug;
1327c478bdstevel@tonic-gateextern void yyerror(char *s);
1337c478bdstevel@tonic-gate
1347c478bdstevel@tonic-gate/* Utility functions */
1357c478bdstevel@tonic-gatestatic void arg_parse(const char *);
1367c478bdstevel@tonic-gatestatic void file_parse(const char *);
1377c478bdstevel@tonic-gatestatic cmd_t *alloc_cmd(void);
1387c478bdstevel@tonic-gatestatic prop_t *alloc_prop(prop_op_t);
1397c478bdstevel@tonic-gatestatic assoc_t *alloc_assoc(int, const char *);
1407c478bdstevel@tonic-gatestatic void free_cmd(cmd_t *);
1417c478bdstevel@tonic-gatestatic void check_conf_name(cmd_t *);
1427c478bdstevel@tonic-gatestatic void prop_list_walk(cmd_t *, pool_elem_t *);
1437c478bdstevel@tonic-gatestatic void assoc_list_walk(cmd_t *, pool_t *);
1447c478bdstevel@tonic-gatestatic void transfer_list_walk(cmd_t *, pool_resource_t *);
1457c478bdstevel@tonic-gatestatic void terminate(void);
1467c478bdstevel@tonic-gatestatic pool_component_t *get_cpu(const char *);
1477c478bdstevel@tonic-gatestatic void process_min_max(pool_resource_t *);
1487c478bdstevel@tonic-gate
1497c478bdstevel@tonic-gate/* Info Commands */
1507c478bdstevel@tonic-gatestatic void parser_conf_info(cmd_t *);
1517c478bdstevel@tonic-gatestatic void parser_pool_info(cmd_t *);
1527c478bdstevel@tonic-gatestatic void parser_resource_info(cmd_t *, const char *);
1537c478bdstevel@tonic-gatestatic void parser_pset_info(cmd_t *);
1547c478bdstevel@tonic-gatestatic void parser_cpu_info(cmd_t *);
1557c478bdstevel@tonic-gate
1567c478bdstevel@tonic-gate/* Create Commands */
1577c478bdstevel@tonic-gatestatic void parser_conf_create(cmd_t *);
1587c478bdstevel@tonic-gatestatic void parser_pool_create(cmd_t *);
1597c478bdstevel@tonic-gatestatic void parser_resource_create(cmd_t *, const char *);
1607c478bdstevel@tonic-gatestatic void parser_pset_create(cmd_t *);
1617c478bdstevel@tonic-gate
1627c478bdstevel@tonic-gate/* Destroy Commands */
1637c478bdstevel@tonic-gatestatic void parser_conf_destroy(cmd_t *);
1647c478bdstevel@tonic-gatestatic void parser_pool_destroy(cmd_t *);
1657c478bdstevel@tonic-gatestatic void parser_resource_destroy(cmd_t *, const char *);
1667c478bdstevel@tonic-gatestatic void parser_pset_destroy(cmd_t *);
1677c478bdstevel@tonic-gate
1687c478bdstevel@tonic-gate/* Modify Commands */
1697c478bdstevel@tonic-gatestatic void parser_conf_modify(cmd_t *);
1707c478bdstevel@tonic-gatestatic void parser_pool_modify(cmd_t *);
1717c478bdstevel@tonic-gatestatic void parser_resource_modify(cmd_t *, const char *);
1727c478bdstevel@tonic-gatestatic void parser_pset_modify(cmd_t *);
1737c478bdstevel@tonic-gatestatic void parser_cpu_modify(cmd_t *);
1747c478bdstevel@tonic-gate
1757c478bdstevel@tonic-gate/* Associate Commands */
1767c478bdstevel@tonic-gatestatic void parser_pool_associate(cmd_t *);
1777c478bdstevel@tonic-gate
1787c478bdstevel@tonic-gate/* Assign Commands */
1797c478bdstevel@tonic-gatestatic void parser_resource_xtransfer(cmd_t *);
1807c478bdstevel@tonic-gatestatic void parser_resource_transfer(cmd_t *);
1817c478bdstevel@tonic-gate
1827c478bdstevel@tonic-gate/* Discover Commands */
1837c478bdstevel@tonic-gatestatic void parser_conf_discover(cmd_t *);
1847c478bdstevel@tonic-gate
1857c478bdstevel@tonic-gate/* Rename Commands */
1867c478bdstevel@tonic-gatestatic void parser_rename(cmd_t *, pool_elem_t *, const char *);
1877c478bdstevel@tonic-gatestatic void parser_conf_rename(cmd_t *);
1887c478bdstevel@tonic-gatestatic void parser_pool_rename(cmd_t *);
1897c478bdstevel@tonic-gatestatic void parser_pset_rename(cmd_t *);
1907c478bdstevel@tonic-gate
1917c478bdstevel@tonic-gate
1927c478bdstevel@tonic-gate%}
1937c478bdstevel@tonic-gate
1947c478bdstevel@tonic-gate%union {
1957c478bdstevel@tonic-gate	double dval;
1967c478bdstevel@tonic-gate	uint64_t uval;
1977c478bdstevel@tonic-gate	int64_t ival;
1987c478bdstevel@tonic-gate	char *sval;
1997c478bdstevel@tonic-gate	uchar_t bval;
2007c478bdstevel@tonic-gate	cmd_t *cmd;
2017c478bdstevel@tonic-gate	prop_t *prop;
2027c478bdstevel@tonic-gate	pv_u val;
2037c478bdstevel@tonic-gate	assoc_t *assoc;
2047c478bdstevel@tonic-gate}
2057c478bdstevel@tonic-gate
2067c478bdstevel@tonic-gate%start commands
2077c478bdstevel@tonic-gate
2087c478bdstevel@tonic-gate%token PCC_INFO PCC_CREATE PCC_DESTROY PCC_MODIFY PCC_ASSOC PCC_DISC PCC_RENAME
2097c478bdstevel@tonic-gate%token PCC_TRANSFER
2107c478bdstevel@tonic-gate%token PCK_FROM PCK_TO PCK_OPENLST PCK_CLOSELST PCK_SEPLST PCK_ASSIGN PCK_UNDEF
2117c478bdstevel@tonic-gatePCK_COMMAND
2127c478bdstevel@tonic-gate%token PCV_FILENAME PCV_SYMBOL PCV_VAL_INT PCV_VAL_UINT PCV_VAL_FLOAT
2137c478bdstevel@tonic-gatePCV_VAL_STRING PCV_VAL_BOOLEAN
2147c478bdstevel@tonic-gate%token PCT_INT PCT_UINT PCT_BOOLEAN PCT_FLOAT PCT_STRING
2157c478bdstevel@tonic-gate%token PCE_SYSTEM PCE_POOL PCE_PSET PCE_CPU
2167c478bdstevel@tonic-gate
2177c478bdstevel@tonic-gate%type <ival> PCV_VAL_INT
2187c478bdstevel@tonic-gate%type <uval> PCV_VAL_UINT
2197c478bdstevel@tonic-gate%type <bval> PCV_VAL_BOOLEAN
2207c478bdstevel@tonic-gate%type <dval> PCV_VAL_FLOAT
2217c478bdstevel@tonic-gate%type <sval> PCV_VAL_STRING
2227c478bdstevel@tonic-gate%type <sval> PCV_SYMBOL
2237c478bdstevel@tonic-gate%type <sval> PCV_FILENAME
2247c478bdstevel@tonic-gate
2257c478bdstevel@tonic-gate%type <ival> PCC_INFO
2267c478bdstevel@tonic-gate%type <ival> PCE_SYSTEM PCE_POOL PCE_PSET PCE_CPU
2277c478bdstevel@tonic-gate%type <ival> entity proptype info_entity modify_entity
2287c478bdstevel@tonic-gate%type <sval> name src tgt
2297c478bdstevel@tonic-gate%type <cmd> command
2307c478bdstevel@tonic-gate%type <cmd> list_command info_command edit_command create_command
2317c478bdstevel@tonic-gatedestroy_command modify_command associate_command discover_command
2327c478bdstevel@tonic-gaterename_command transfer_command transfer_qty transfer_components
2337c478bdstevel@tonic-gate%type <prop> prop_remove prop_assign prop_op prop_ops property_list
2347c478bdstevel@tonic-gate%type <assoc> resource_assign resource_assigns resource_list
2357c478bdstevel@tonic-gate%type <assoc> component_assign component_assigns component_list
2367c478bdstevel@tonic-gate%type <val> value
2377c478bdstevel@tonic-gate%type <ival> resource component
2387c478bdstevel@tonic-gate
2397c478bdstevel@tonic-gate%%
2407c478bdstevel@tonic-gate
2417c478bdstevel@tonic-gatecommands: command
2427c478bdstevel@tonic-gate	{
2437c478bdstevel@tonic-gate		if ($1->cmd != NULL)
2447c478bdstevel@tonic-gate			$1->cmd($1);
2457c478bdstevel@tonic-gate		free_cmd($1);
2467c478bdstevel@tonic-gate	}
2477c478bdstevel@tonic-gate	| commands command
2487c478bdstevel@tonic-gate	{
2497c478bdstevel@tonic-gate		if ($2->cmd != NULL)
2507c478bdstevel@tonic-gate			$2->cmd($2);
2517c478bdstevel@tonic-gate		free_cmd($2);
2527c478bdstevel@tonic-gate	}
2537c478bdstevel@tonic-gate	| command error { YYERROR;};
2547c478bdstevel@tonic-gate
2557c478bdstevel@tonic-gatecommand: list_command
2567c478bdstevel@tonic-gate	| edit_command
2577c478bdstevel@tonic-gate	{
2587c478bdstevel@tonic-gate		if (conf_edit_error != POE_OK) {
2597c478bdstevel@tonic-gate			if ($1->cmd != parser_conf_create &&
2607c478bdstevel@tonic-gate			    $1->cmd != parser_conf_discover) {
2617c478bdstevel@tonic-gate				die(gettext(ERR_CONF_LOAD), conf_file,
2627c478bdstevel@tonic-gate				    get_errstr_err(conf_edit_error,
2637c478bdstevel@tonic-gate				        conf_edit_errno));
2647c478bdstevel@tonic-gate			}
2657c478bdstevel@tonic-gate		}
2667c478bdstevel@tonic-gate		edited = PO_TRUE;
2677c478bdstevel@tonic-gate	};
2687c478bdstevel@tonic-gate
2697c478bdstevel@tonic-gatelist_command: info_command
2707c478bdstevel@tonic-gate	{
2717c478bdstevel@tonic-gate		if (conf_list_error != POE_OK) {
2727c478bdstevel@tonic-gate			if ($1->cmd != parser_conf_create &&
2737c478bdstevel@tonic-gate			    $1->cmd != parser_conf_discover) {
2747c478bdstevel@tonic-gate				die(gettext(ERR_CONF_LOAD), conf_file,
2757c478bdstevel@tonic-gate				    get_errstr_err(conf_list_error,
2767c478bdstevel@tonic-gate				        conf_list_errno));
2777c478bdstevel@tonic-gate			}
2787c478bdstevel@tonic-gate		}
2797c478bdstevel@tonic-gate	}
2807c478bdstevel@tonic-gate	| discover_command {conf_list_error = conf_edit_error = POE_OK;};
2817c478bdstevel@tonic-gate
2827c478bdstevel@tonic-gateedit_command: create_command
2837c478bdstevel@tonic-gate	| destroy_command
2847c478bdstevel@tonic-gate	| modify_command
2857c478bdstevel@tonic-gate	| associate_command
2867c478bdstevel@tonic-gate	| transfer_command
2877c478bdstevel@tonic-gate	| rename_command;
2887c478bdstevel@tonic-gate
2897c478bdstevel@tonic-gateinfo_command: PCC_INFO
2907c478bdstevel@tonic-gate	{
2917c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
2927c478bdstevel@tonic-gate			YYERROR;
2937c478bdstevel@tonic-gate		cmd = $$;
2947c478bdstevel@tonic-gate		$$->cmd = &parser_conf_info;
2957c478bdstevel@tonic-gate	}
2967c478bdstevel@tonic-gate	| PCC_INFO info_entity name
2977c478bdstevel@tonic-gate	{
2987c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
2997c478bdstevel@tonic-gate			YYERROR;
3007c478bdstevel@tonic-gate		cmd = $$;
3017c478bdstevel@tonic-gate		switch ($2) {
3027c478bdstevel@tonic-gate		case PCE_SYSTEM:
3037c478bdstevel@tonic-gate			$$->cmd = &parser_conf_info;
3047c478bdstevel@tonic-gate			break;
3057c478bdstevel@tonic-gate		case PCE_POOL:
3067c478bdstevel@tonic-gate			$$->cmd = &parser_pool_info;
3077c478bdstevel@tonic-gate			break;
3087c478bdstevel@tonic-gate		case PCE_PSET:
3097c478bdstevel@tonic-gate			$$->cmd = &parser_pset_info;
3107c478bdstevel@tonic-gate			break;
3117c478bdstevel@tonic-gate		case PCE_CPU:
3127c478bdstevel@tonic-gate			$$->cmd = &parser_cpu_info;
3137c478bdstevel@tonic-gate			break;
3147c478bdstevel@tonic-gate		default:
3157c478bdstevel@tonic-gate			warn(gettext(ERR_UNKNOWN_ENTITY), $2);
3167c478bdstevel@tonic-gate			YYERROR;
3177c478bdstevel@tonic-gate		}
3187c478bdstevel@tonic-gate		$$->cmd_tgt1 = $3;
3197c478bdstevel@tonic-gate	};
3207c478bdstevel@tonic-gate
3217c478bdstevel@tonic-gatecreate_command: PCC_CREATE entity name
3227c478bdstevel@tonic-gate	{
3237c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
3247c478bdstevel@tonic-gate			YYERROR;
3257c478bdstevel@tonic-gate		cmd = $$;
3267c478bdstevel@tonic-gate		switch ($2) {
3277c478bdstevel@tonic-gate		case PCE_SYSTEM:
3287c478bdstevel@tonic-gate			$$->cmd = &parser_conf_create;
32926d8ba2garypen			/*
33026d8ba2garypen			 * When creating a new system element, ensure
33126d8ba2garypen			 * pre-existing errors are ignored.
33226d8ba2garypen			 */
33326d8ba2garypen			conf_list_error = conf_edit_error = POE_OK;
3347c478bdstevel@tonic-gate			break;
3357c478bdstevel@tonic-gate		case PCE_POOL:
3367c478bdstevel@tonic-gate			$$->cmd = &parser_pool_create;
3377c478bdstevel@tonic-gate			break;
3387c478bdstevel@tonic-gate		case PCE_PSET:
3397c478bdstevel@tonic-gate			$$->cmd = &parser_pset_create;
3407c478bdstevel@tonic-gate			break;
3417c478bdstevel@tonic-gate		default:
3427c478bdstevel@tonic-gate			warn(gettext(ERR_UNKNOWN_ENTITY), $2);
3437c478bdstevel@tonic-gate			YYERROR;
3447c478bdstevel@tonic-gate		}
3457c478bdstevel@tonic-gate		$$->cmd_tgt1 = $3;
3467c478bdstevel@tonic-gate	}
3477c478bdstevel@tonic-gate	| create_command property_list;
3487c478bdstevel@tonic-gate
3497c478bdstevel@tonic-gatedestroy_command: PCC_DESTROY entity name
3507c478bdstevel@tonic-gate	{
3517c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
3527c478bdstevel@tonic-gate			YYERROR;
3537c478bdstevel@tonic-gate		cmd = $$;
3547c478bdstevel@tonic-gate		switch ($2) {
3557c478bdstevel@tonic-gate		case PCE_SYSTEM:
3567c478bdstevel@tonic-gate			$$->cmd = &parser_conf_destroy;
3577c478bdstevel@tonic-gate			break;
3587c478bdstevel@tonic-gate		case PCE_POOL:
3597c478bdstevel@tonic-gate			$$->cmd = &parser_pool_destroy;
3607c478bdstevel@tonic-gate			break;
3617c478bdstevel@tonic-gate		case PCE_PSET:
3627c478bdstevel@tonic-gate			$$->cmd = &parser_pset_destroy;
3637c478bdstevel@tonic-gate			break;
3647c478bdstevel@tonic-gate		default:
3657c478bdstevel@tonic-gate			warn(gettext(ERR_UNKNOWN_ENTITY), $2);
3667c478bdstevel@tonic-gate			YYERROR;
3677c478bdstevel@tonic-gate		}
3687c478bdstevel@tonic-gate		$$->cmd_tgt1 = $3;
3697c478bdstevel@tonic-gate	};
3707c478bdstevel@tonic-gate
3717c478bdstevel@tonic-gatemodify_command: PCC_MODIFY modify_entity name
3727c478bdstevel@tonic-gate	{
3737c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
3747c478bdstevel@tonic-gate			YYERROR;
3757c478bdstevel@tonic-gate		cmd = $$;
3767c478bdstevel@tonic-gate		switch ($2) {
3777c478bdstevel@tonic-gate		case PCE_SYSTEM:
3787c478bdstevel@tonic-gate			$$->cmd = &parser_conf_modify;
3797c478bdstevel@tonic-gate			break;
3807c478bdstevel@tonic-gate		case PCE_POOL:
3817c478bdstevel@tonic-gate			$$->cmd = &parser_pool_modify;
3827c478bdstevel@tonic-gate			break;
3837c478bdstevel@tonic-gate		case PCE_PSET:
3847c478bdstevel@tonic-gate			$$->cmd = &parser_pset_modify;
3857c478bdstevel@tonic-gate			break;
3867c478bdstevel@tonic-gate		case PCE_CPU:
3877c478bdstevel@tonic-gate			$$->cmd = &parser_cpu_modify;
3887c478bdstevel@tonic-gate			break;
3897c478bdstevel@tonic-gate		default:
3907c478bdstevel@tonic-gate			warn(gettext(ERR_UNKNOWN_ENTITY), $2);
3917c478bdstevel@tonic-gate			YYERROR;
3927c478bdstevel@tonic-gate		}
3937c478bdstevel@tonic-gate		$$->cmd_tgt1 = $3;
3947c478bdstevel@tonic-gate	}
3957c478bdstevel@tonic-gate	| modify_command property_list;
3967c478bdstevel@tonic-gate
3977c478bdstevel@tonic-gateassociate_command: PCC_ASSOC PCE_POOL name
3987c478bdstevel@tonic-gate	{
3997c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4007c478bdstevel@tonic-gate			YYERROR;
4017c478bdstevel@tonic-gate		cmd = $$;
4027c478bdstevel@tonic-gate		$$->cmd = &parser_pool_associate;
4037c478bdstevel@tonic-gate		cmd->cmd_tgt1 = $3;
4047c478bdstevel@tonic-gate	}
4057c478bdstevel@tonic-gate	| associate_command resource_list;
4067c478bdstevel@tonic-gate
4077c478bdstevel@tonic-gatetransfer_command: transfer_qty
4087c478bdstevel@tonic-gate	| transfer_components;
4097c478bdstevel@tonic-gate
4107c478bdstevel@tonic-gatetransfer_components: PCC_TRANSFER PCK_TO PCE_PSET name
4117c478bdstevel@tonic-gate	{
4127c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4137c478bdstevel@tonic-gate			YYERROR;
4147c478bdstevel@tonic-gate		cmd = $$;
4157c478bdstevel@tonic-gate		$$->cmd = &parser_resource_xtransfer;
4167c478bdstevel@tonic-gate		cmd->cmd_tgt1 = $4;
4177c478bdstevel@tonic-gate	}
4187c478bdstevel@tonic-gate	| transfer_components component_list;
4197c478bdstevel@tonic-gate
4207c478bdstevel@tonic-gatetransfer_qty: PCC_TRANSFER PCV_VAL_UINT PCK_FROM PCE_PSET src PCK_TO tgt
4217c478bdstevel@tonic-gate	{
4227c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4237c478bdstevel@tonic-gate			YYERROR;
4247c478bdstevel@tonic-gate		cmd = $$;
4257c478bdstevel@tonic-gate		$$->cmd = &parser_resource_transfer;
4267c478bdstevel@tonic-gate		cmd->cmd_tgt1 = $5;
4277c478bdstevel@tonic-gate		cmd->cmd_tgt2 = $7;
4287c478bdstevel@tonic-gate		cmd->cmd_qty = $2;
4297c478bdstevel@tonic-gate	}
4307c478bdstevel@tonic-gate	| PCC_TRANSFER  PCV_VAL_UINT PCK_TO PCE_PSET tgt PCK_FROM src
4317c478bdstevel@tonic-gate	{
4327c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4337c478bdstevel@tonic-gate			YYERROR;
4347c478bdstevel@tonic-gate		cmd = $$;
4357c478bdstevel@tonic-gate		$$->cmd = &parser_resource_transfer;
4367c478bdstevel@tonic-gate		cmd->cmd_tgt1 = $7;
4377c478bdstevel@tonic-gate		cmd->cmd_tgt2 = $5;
4387c478bdstevel@tonic-gate		cmd->cmd_qty = $2;
4397c478bdstevel@tonic-gate	};
44003dfa5bToomas Soome
4417c478bdstevel@tonic-gatediscover_command: PCC_DISC
4427c478bdstevel@tonic-gate	{
4437c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4447c478bdstevel@tonic-gate			YYERROR;
4457c478bdstevel@tonic-gate		cmd = $$;
4467c478bdstevel@tonic-gate		$$->cmd = &parser_conf_discover;
4477c478bdstevel@tonic-gate	};
4487c478bdstevel@tonic-gate
4497c478bdstevel@tonic-gaterename_command: PCC_RENAME entity name PCK_TO name
4507c478bdstevel@tonic-gate	{
4517c478bdstevel@tonic-gate		if (($$ = alloc_cmd()) == NULL)
4527c478bdstevel@tonic-gate			YYERROR;
4537c478bdstevel@tonic-gate		cmd = $$;
4547c478bdstevel@tonic-gate		switch ($2) {
4557c478bdstevel@tonic-gate		case PCE_SYSTEM:
4567c478bdstevel@tonic-gate			$$->cmd = &parser_conf_rename;
4577c478bdstevel@tonic-gate			break;
4587c478bdstevel@tonic-gate		case PCE_POOL:
4597c478bdstevel@tonic-gate			$$->cmd = &parser_pool_rename;
4607c478bdstevel@tonic-gate			break;
4617c478bdstevel@tonic-gate		case PCE_PSET:
4627c478bdstevel@tonic-gate			$$->cmd = &parser_pset_rename;
4637c478bdstevel@tonic-gate			break;
4647c478bdstevel@tonic-gate		default:
4657c478bdstevel@tonic-gate			warn(gettext(ERR_UNKNOWN_ENTITY), $2);
4667c478bdstevel@tonic-gate			YYERROR;
4677c478bdstevel@tonic-gate		}
4687c478bdstevel@tonic-gate		$$->cmd_tgt1 = $3;
4697c478bdstevel@tonic-gate		$$->cmd_tgt2 = $5;
4707c478bdstevel@tonic-gate	};
4717c478bdstevel@tonic-gate
4727c478bdstevel@tonic-gatemodify_entity: entity
4737c478bdstevel@tonic-gate	| PCE_CPU  {$$ = PCE_CPU;};
4747c478bdstevel@tonic-gate
4757c478bdstevel@tonic-gateinfo_entity: entity
4767c478bdstevel@tonic-gate	| PCE_CPU  {$$ = PCE_CPU;};
4777c478bdstevel@tonic-gate
4787c478bdstevel@tonic-gateentity: PCE_SYSTEM {$$ = PCE_SYSTEM;}
4797c478bdstevel@tonic-gate	| PCE_POOL {$$ = PCE_POOL;}
4807c478bdstevel@tonic-gate	| PCE_PSET {$$ = PCE_PSET;};
4817c478bdstevel@tonic-gate
4827c478bdstevel@tonic-gatename: PCV_SYMBOL;
4837c478bdstevel@tonic-gate
4847c478bdstevel@tonic-gatesrc: PCV_SYMBOL;
4857c478bdstevel@tonic-gate
4867c478bdstevel@tonic-gatetgt: PCV_SYMBOL;
4877c478bdstevel@tonic-gate
4887c478bdstevel@tonic-gatevalue: PCV_VAL_INT { $$.i = $1;}
4897c478bdstevel@tonic-gate	| PCV_VAL_UINT { $$.u = $1;}
4907c478bdstevel@tonic-gate	| PCV_VAL_FLOAT { $$.d = $1;}
4917c478bdstevel@tonic-gate	| PCV_VAL_BOOLEAN { $$.b = $1;}
4927c478bdstevel@tonic-gate	| PCV_VAL_STRING { $$.s = $1;};
4937c478bdstevel@tonic-gate
4947c478bdstevel@tonic-gateprop_remove: PCK_UNDEF proptype name
4957c478bdstevel@tonic-gate	{
4967c478bdstevel@tonic-gate		if (($$ = alloc_prop(po_remove)) == NULL)
4977c478bdstevel@tonic-gate			YYERROR;
4987c478bdstevel@tonic-gate		$$->prop_name = $3;
4997c478bdstevel@tonic-gate	};
5007c478bdstevel@tonic-gate
5017c478bdstevel@tonic-gateprop_op: prop_assign
5027c478bdstevel@tonic-gate	| prop_remove;
5037c478bdstevel@tonic-gate
5047c478bdstevel@tonic-gateprop_ops: prop_op
5057c478bdstevel@tonic-gate	{
5067c478bdstevel@tonic-gate		prop_t *prop = NULL;
5077c478bdstevel@tonic-gate		prop_t *prev = NULL;
5087c478bdstevel@tonic-gate
5097c478bdstevel@tonic-gate		for (prop = cmd->cmd_prop_list; prop != NULL;
5107c478bdstevel@tonic-gate		    prop = prop->prop_next)
5117c478bdstevel@tonic-gate			prev = prop; /* Find end of list */
5127c478bdstevel@tonic-gate		if (prev != NULL)
5137c478bdstevel@tonic-gate			prev->prop_next = $1;
5147c478bdstevel@tonic-gate		else
5157c478bdstevel@tonic-gate			cmd->cmd_prop_list = $1;
5167c478bdstevel@tonic-gate		$$ = cmd->cmd_prop_list;
5177c478bdstevel@tonic-gate	}
5187c478bdstevel@tonic-gate	| prop_ops PCK_SEPLST prop_op
5197c478bdstevel@tonic-gate	{
5207c478bdstevel@tonic-gate		prop_t *prop = NULL;
5217c478bdstevel@tonic-gate		prop_t *prev = NULL;
5227c478bdstevel@tonic-gate
5237c478bdstevel@tonic-gate		for (prop = cmd->cmd_prop_list; prop != NULL;
5247c478bdstevel@tonic-gate		    prop = prop->prop_next)
5257c478bdstevel@tonic-gate			prev = prop; /* Find end of list */
5267c478bdstevel@tonic-gate		if (prev != NULL)
5277c478bdstevel@tonic-gate			prev->prop_next = $3;
5287c478bdstevel@tonic-gate		else
5297c478bdstevel@tonic-gate			cmd->cmd_prop_list = $3;
5307c478bdstevel@tonic-gate		$$ = cmd->cmd_prop_list;
5317c478bdstevel@tonic-gate
5327c478bdstevel@tonic-gate	};
5337c478bdstevel@tonic-gate
5347c478bdstevel@tonic-gateprop_assign: proptype name PCK_ASSIGN value
5357c478bdstevel@tonic-gate	{
5367c478bdstevel@tonic-gate		if (($$ = alloc_prop(po_create)) == NULL)
5377c478bdstevel@tonic-gate			YYERROR;
5387c478bdstevel@tonic-gate		$$->prop_name = $2;
5397c478bdstevel@tonic-gate		switch ($1) {
5407c478bdstevel@tonic-gate		case PCT_INT:
5417c478bdstevel@tonic-gate			pool_value_set_int64($$->prop_value, $4.i);
5427c478bdstevel@tonic-gate			break;
5437c478bdstevel@tonic-gate		case PCT_UINT:
5447c478bdstevel@tonic-gate			pool_value_set_uint64($$->prop_value, $4.u);
5457c478bdstevel@tonic-gate			break;
5467c478bdstevel@tonic-gate		case PCT_BOOLEAN:
5477c478bdstevel@tonic-gate			pool_value_set_bool($$->prop_value, $4.b);
5487c478bdstevel@tonic-gate			break;
5497c478bdstevel@tonic-gate		case PCT_FLOAT:
5507c478bdstevel@tonic-gate			pool_value_set_double($$->prop_value, $4.d);
5517c478bdstevel@tonic-gate			break;
5527c478bdstevel@tonic-gate		case PCT_STRING:
5537c478bdstevel@tonic-gate			pool_value_set_string($$->prop_value, $4.s);
5547c478bdstevel@tonic-gate			break;
5557c478bdstevel@tonic-gate		}
5567c478bdstevel@tonic-gate	};
5577c478bdstevel@tonic-gate
5587c478bdstevel@tonic-gateproperty_list: PCK_OPENLST prop_ops PCK_CLOSELST
5597c478bdstevel@tonic-gate	{
5607c478bdstevel@tonic-gate		$$ = $2;
5617c478bdstevel@tonic-gate	};
5627c478bdstevel@tonic-gate
5637c478bdstevel@tonic-gateresource_assigns: resource_assign
5647c478bdstevel@tonic-gate	{
5657c478bdstevel@tonic-gate		assoc_t *assoc = NULL;
5667c478bdstevel@tonic-gate		assoc_t *prev = NULL;
5677c478bdstevel@tonic-gate
5687c478bdstevel@tonic-gate		for (assoc = cmd->cmd_assoc_list; assoc != NULL;
5697c478bdstevel@tonic-gate		    assoc = assoc->assoc_next)
5707c478bdstevel@tonic-gate			prev = assoc; /* Find end of list */
5717c478bdstevel@tonic-gate		if (prev != NULL)
5727c478bdstevel@tonic-gate			prev->assoc_next = $1;
5737c478bdstevel@tonic-gate		else
5747c478bdstevel@tonic-gate			cmd->cmd_assoc_list = $1;
5757c478bdstevel@tonic-gate		$$ = cmd->cmd_assoc_list;
5767c478bdstevel@tonic-gate	}
5777c478bdstevel@tonic-gate
5787c478bdstevel@tonic-gate	| resource_assigns PCK_SEPLST resource_assign
5797c478bdstevel@tonic-gate	{
5807c478bdstevel@tonic-gate		assoc_t *assoc = NULL;
5817c478bdstevel@tonic-gate		assoc_t *prev = NULL;
5827c478bdstevel@tonic-gate
5837c478bdstevel@tonic-gate		for (assoc = cmd->cmd_assoc_list; assoc != NULL;
5847c478bdstevel@tonic-gate		    assoc = assoc->assoc_next)
5857c478bdstevel@tonic-gate			prev = assoc; /* Find end of list */
5867c478bdstevel@tonic-gate		if (prev != NULL)
5877c478bdstevel@tonic-gate			prev->assoc_next = $3;
5887c478bdstevel@tonic-gate		$$ = $3;
5897c478bdstevel@tonic-gate	};
5907c478bdstevel@tonic-gate
5917c478bdstevel@tonic-gateresource_assign: resource name
5927c478bdstevel@tonic-gate	{
5937c478bdstevel@tonic-gate		if (($$ = alloc_assoc($1, $2)) == NULL)
5947c478bdstevel@tonic-gate			YYERROR;
5957c478bdstevel@tonic-gate	};
5967c478bdstevel@tonic-gate
5977c478bdstevel@tonic-gateresource: PCE_PSET {$$ = PCE_PSET;};
5987c478bdstevel@tonic-gate
5997c478bdstevel@tonic-gateresource_list: PCK_OPENLST resource_assigns PCK_CLOSELST
6007c478bdstevel@tonic-gate	{
6017c478bdstevel@tonic-gate		$$ = $2;
6027c478bdstevel@tonic-gate	};
6037c478bdstevel@tonic-gate
6047c478bdstevel@tonic-gatecomponent_assigns: component_assign
6057c478bdstevel@tonic-gate	{
6067c478bdstevel@tonic-gate		assoc_t *assoc = NULL;
6077c478bdstevel@tonic-gate		assoc_t *prev = NULL;
6087c478bdstevel@tonic-gate
6097c478bdstevel@tonic-gate		for (assoc = cmd->cmd_assoc_list; assoc != NULL;
6107c478bdstevel@tonic-gate		    assoc = assoc->assoc_next)
6117c478bdstevel@tonic-gate			prev = assoc; /* Find end of list */
6127c478bdstevel@tonic-gate		if (prev != NULL)
6137c478bdstevel@tonic-gate			prev->assoc_next = $1;
6147c478bdstevel@tonic-gate		else
6157c478bdstevel@tonic-gate			cmd->cmd_assoc_list = $1;
6167c478bdstevel@tonic-gate		$$ = cmd->cmd_assoc_list;
6177c478bdstevel@tonic-gate	}
6187c478bdstevel@tonic-gate
6197c478bdstevel@tonic-gate	| component_assigns PCK_SEPLST component_assign
6207c478bdstevel@tonic-gate	{
6217c478bdstevel@tonic-gate		assoc_t *assoc = NULL;
6227c478bdstevel@tonic-gate		assoc_t *prev = NULL;
6237c478bdstevel@tonic-gate
6247c478bdstevel@tonic-gate		for (assoc = cmd->cmd_assoc_list; assoc != NULL;
6257c478bdstevel@tonic-gate		    assoc = assoc->assoc_next)
6267c478bdstevel@tonic-gate			prev = assoc; /* Find end of list */
6277c478bdstevel@tonic-gate		if (prev != NULL)
6287c478bdstevel@tonic-gate			prev->assoc_next = $3;
6297c478bdstevel@tonic-gate		$$ = $3;
6307c478bdstevel@tonic-gate	};
6317c478bdstevel@tonic-gate
6327c478bdstevel@tonic-gatecomponent_list: PCK_OPENLST component_assigns PCK_CLOSELST
6337c478bdstevel@tonic-gate	{
6347c478bdstevel@tonic-gate		$$ = $2;
6357c478bdstevel@tonic-gate	};
6367c478bdstevel@tonic-gate
6377c478bdstevel@tonic-gatecomponent_assign: component name
6387c478bdstevel@tonic-gate	{
6397c478bdstevel@tonic-gate		if (($$ = alloc_assoc($1, $2)) == NULL)
6407c478bdstevel@tonic-gate			YYERROR;
6417c478bdstevel@tonic-gate	};
6427c478bdstevel@tonic-gate
6437c478bdstevel@tonic-gatecomponent: PCE_CPU {$$ = PCE_CPU;};
6447c478bdstevel@tonic-gate
6457c478bdstevel@tonic-gateproptype: PCT_INT {$$ = PCT_INT;}
6467c478bdstevel@tonic-gate	| PCT_UINT {$$ = PCT_UINT;}
6477c478bdstevel@tonic-gate	| PCT_BOOLEAN {$$ = PCT_BOOLEAN;}
6487c478bdstevel@tonic-gate	| PCT_FLOAT {$$ = PCT_FLOAT;}
6497c478bdstevel@tonic-gate	| PCT_STRING {$$ = PCT_STRING;};
6507c478bdstevel@tonic-gate
6517c478bdstevel@tonic-gate%%
6527c478bdstevel@tonic-gate
6537c478bdstevel@tonic-gate#ifndef	TEXT_DOMAIN
6547c478bdstevel@tonic-gate#define	TEXT_DOMAIN "SYS_TEST"
6557c478bdstevel@tonic-gate#endif
6567c478bdstevel@tonic-gate
6577c478bdstevel@tonic-gateint
6587c478bdstevel@tonic-gatemain(int argc, char *argv[])
6597c478bdstevel@tonic-gate{
6607c478bdstevel@tonic-gate	int opt;
6617c478bdstevel@tonic-gate	int docmd = PO_FALSE;
6627c478bdstevel@tonic-gate
6637c478bdstevel@tonic-gate	(void) getpname(argv[0]);
6647c478bdstevel@tonic-gate	(void) setlocale(LC_ALL, "");
6657c478bdstevel@tonic-gate	(void) textdomain(TEXT_DOMAIN);
6667c478bdstevel@tonic-gate	if (atexit(terminate) != 0) {
6677c478bdstevel@tonic-gate		die(gettext(ERR_SET_TERM), get_errstr());
6687c478bdstevel@tonic-gate	}
6697c478bdstevel@tonic-gate
6707c478bdstevel@tonic-gate	conf_file = pool_static_location();
6717c478bdstevel@tonic-gate
6727c478bdstevel@tonic-gate	yydebug = 0;
6737c478bdstevel@tonic-gate	while ((opt = getopt(argc, argv, cmd_options)) != (int)EOF) {
6747c478bdstevel@tonic-gate
6757c478bdstevel@tonic-gate		switch (opt) {
6767c478bdstevel@tonic-gate		case 'c': /* Process command line */
6777c478bdstevel@tonic-gate			if (dofile == PO_TRUE)
6787c478bdstevel@tonic-gate				usage(1);
6797c478bdstevel@tonic-gate			arg_parse(optarg);
6807c478bdstevel@tonic-gate			docmd = PO_TRUE;
6817c478bdstevel@tonic-gate			break;
6827c478bdstevel@tonic-gate		case 'd': /* Manipulate dynamic configuration */
6837c478bdstevel@tonic-gate			conf_file = pool_dynamic_location();
6847c478bdstevel@tonic-gate			break;
6857c478bdstevel@tonic-gate		case 'f': /* Process command file */
6867c478bdstevel@tonic-gate			if (docmd == PO_TRUE)
6877c478bdstevel@tonic-gate				usage(1);
6887c478bdstevel@tonic-gate			file_parse(optarg);
6897c478bdstevel@tonic-gate			dofile = PO_TRUE;
6907c478bdstevel@tonic-gate			break;
6917c478bdstevel@tonic-gate		case 'h':
6927c478bdstevel@tonic-gate			usage(2);
6937c478bdstevel@tonic-gate			break;
6947c478bdstevel@tonic-gate		case '?':
6957c478bdstevel@tonic-gate		default:
6967c478bdstevel@tonic-gate			usage(1);
6977c478bdstevel@tonic-gate			break;
6987c478bdstevel@tonic-gate		}
6997c478bdstevel@tonic-gate	}
7007c478bdstevel@tonic-gate	if (docmd == PO_FALSE && dofile == PO_FALSE)
7017c478bdstevel@tonic-gate		usage(1);
7027c478bdstevel@tonic-gate
7037c478bdstevel@tonic-gate	if (optind == argc - 1) {
7047c478bdstevel@tonic-gate		if (strcmp(conf_file, pool_dynamic_location()) == 0)
7057c478bdstevel@tonic-gate			usage(1);
7067c478bdstevel@tonic-gate		conf_file = argv[optind];
7077c478bdstevel@tonic-gate	} else if (optind <  argc - 1)
7087c478bdstevel@tonic-gate		usage(1);
7097c478bdstevel@tonic-gate
7107c478bdstevel@tonic-gate	if ((conf = pool_conf_alloc()) == NULL) {
7117c478bdstevel@tonic-gate		die(gettext(ERR_ALLOC_ELEMENT), gettext(CONFIGURATION),
7127c478bdstevel@tonic-gate		    get_errstr());
7137c478bdstevel@tonic-gate	}
7147c478bdstevel@tonic-gate	/*
7157c478bdstevel@tonic-gate	 * Opening a conf is complex, since we may be opening one of the
7167c478bdstevel@tonic-gate	 * following:
7177c478bdstevel@tonic-gate	 *	- An existing configuration that we can modify
7187c478bdstevel@tonic-gate	 *	- An existing configuration that we can't modify
7197c478bdstevel@tonic-gate	 *	- A new configuration that we can modify
7207c478bdstevel@tonic-gate	 *	- A new configuration that we can't modify
7217c478bdstevel@tonic-gate	 * The parser_conf_discover() function closes the file and reopens
7227c478bdstevel@tonic-gate	 * in PO_CREAT mode, so we only need be concerned here with the
7237c478bdstevel@tonic-gate	 * first two cases.
7247c478bdstevel@tonic-gate	 * Always try to open RDWR, if fail try RDONLY. Don't check
7257c478bdstevel@tonic-gate	 * if that fails, since we may be trying to discover a configuration
7267c478bdstevel@tonic-gate	 * in which case it's valid for both open attempts to fail. Later, when
7277c478bdstevel@tonic-gate	 * processing commands, if we don't have a valid configuration and
7287c478bdstevel@tonic-gate	 * we are trying to process a command which isn't a create or a discover
7297c478bdstevel@tonic-gate	 * we will fail the command as there is no valid configuration to
7307c478bdstevel@tonic-gate	 * work with.
7317c478bdstevel@tonic-gate	 */
7327c478bdstevel@tonic-gate	if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) {
7337c478bdstevel@tonic-gate		conf_edit_error = pool_error();
7347c478bdstevel@tonic-gate		conf_edit_errno = errno;
7357c478bdstevel@tonic-gate		if (pool_conf_open(conf, conf_file, PO_RDONLY) != 0) {
7367c478bdstevel@tonic-gate			conf_list_error = pool_error();
7377c478bdstevel@tonic-gate			conf_list_errno = errno;
7387c478bdstevel@tonic-gate		}
7397c478bdstevel@tonic-gate	}
7407c478bdstevel@tonic-gate
7417c478bdstevel@tonic-gate	if (yyparse() == 0) {
7427c478bdstevel@tonic-gate		if (pool_conf_status(conf) >= POF_VALID) {
7437c478bdstevel@tonic-gate			if (pool_conf_validate(conf, POV_STRICT) == PO_FAIL) {
7447c478bdstevel@tonic-gate				die(gettext(ERR_VALIDATION_FAILED),
7457c478bdstevel@tonic-gate				    get_errstr());
7467c478bdstevel@tonic-gate			}
7477c478bdstevel@tonic-gate			/*
7487c478bdstevel@tonic-gate			 * If the user attempted to change the configuration,
7497c478bdstevel@tonic-gate			 * then we should try to save the changes.
7507c478bdstevel@tonic-gate			 */
7517c478bdstevel@tonic-gate			if (edited == PO_TRUE) {
7527c478bdstevel@tonic-gate				if (pool_conf_commit(conf, 0) == PO_FAIL) {
7537c478bdstevel@tonic-gate					die(gettext(ERR_CONFIG_SAVE_FAILED),
7547c478bdstevel@tonic-gate					    get_errstr());
7557c478bdstevel@tonic-gate				}
7567c478bdstevel@tonic-gate			}
7577c478bdstevel@tonic-gate			pool_conf_close(conf);
7587c478bdstevel@tonic-gate		}
7597c478bdstevel@tonic-gate	} else {
7607c478bdstevel@tonic-gate		die(gettext(ERR_CMDPARSE_FAILED));
7617c478bdstevel@tonic-gate	}
7627c478bdstevel@tonic-gate
7637c478bdstevel@tonic-gate	/*
7647c478bdstevel@tonic-gate	 * Cleanup is performed in terminate(), using atexit
7657c478bdstevel@tonic-gate	 */
7667c478bdstevel@tonic-gate	return (0);
7677c478bdstevel@tonic-gate}
7687c478bdstevel@tonic-gate
7697c478bdstevel@tonic-gate/*
7707c478bdstevel@tonic-gate * Info Commands
7717c478bdstevel@tonic-gate * Invoke the appropriate libpool info function and display the returned
7727c478bdstevel@tonic-gate * information.
7737c478bdstevel@tonic-gate */
7747c478bdstevel@tonic-gatestatic void
7757c478bdstevel@tonic-gateparser_conf_info(cmd_t *cmd)
7767c478bdstevel@tonic-gate{
7777c478bdstevel@tonic-gate	char *info_buf;
7787c478bdstevel@tonic-gate	const char *tgt = cmd->cmd_tgt1;
7797c478bdstevel@tonic-gate	pool_value_t *pv = NULL;
7807c478bdstevel@tonic-gate	pool_elem_t *pe;
7817c478bdstevel@tonic-gate
7827c478bdstevel@tonic-gate	if ((pe = pool_conf_to_elem(conf)) == NULL)
7837c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS),
7847c478bdstevel@tonic-gate		    gettext(CONFIGURATION), "unknown", get_errstr());
7857c478bdstevel@tonic-gate
7867c478bdstevel@tonic-gate	if (tgt != NULL)
7877c478bdstevel@tonic-gate		check_conf_name(cmd);
7887c478bdstevel@tonic-gate	else {
7897c478bdstevel@tonic-gate		if ((pv = pool_value_alloc()) == NULL)
7907c478bdstevel@tonic-gate			die(gettext(ERR_GET_ELEMENT_DETAILS),
7917c478bdstevel@tonic-gate			    gettext(CONFIGURATION), "unknown", get_errstr());
7927c478bdstevel@tonic-gate		if (pool_get_property(conf, pe, "system.name", pv) ==
7937c478bdstevel@tonic-gate		    POC_INVAL ||
7947c478bdstevel@tonic-gate		    pool_value_get_string(pv, &tgt) != PO_SUCCESS)
7957c478bdstevel@tonic-gate			die(gettext(ERR_GET_ELEMENT_DETAILS),
7967c478bdstevel@tonic-gate			    gettext(CONFIGURATION), "unknown", get_errstr());
7977c478bdstevel@tonic-gate	}
7987c478bdstevel@tonic-gate	if ((info_buf = pool_conf_info(conf, PO_TRUE)) == NULL) {
7997c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION),
8007c478bdstevel@tonic-gate		    tgt, get_errstr());
8017c478bdstevel@tonic-gate	}
8027c478bdstevel@tonic-gate	if (pv != NULL) {
8037c478bdstevel@tonic-gate		pool_value_free(pv);
8047c478bdstevel@tonic-gate	}
8057c478bdstevel@tonic-gate	(void) printf("%s\n", info_buf);
8067c478bdstevel@tonic-gate	free(info_buf);
8077c478bdstevel@tonic-gate}
8087c478bdstevel@tonic-gate
8097c478bdstevel@tonic-gatestatic void
8107c478bdstevel@tonic-gateparser_pool_info(cmd_t *cmd)
8117c478bdstevel@tonic-gate{
8127c478bdstevel@tonic-gate	pool_t *pool;
8137c478bdstevel@tonic-gate	char *info_buf;
8147c478bdstevel@tonic-gate
8157c478bdstevel@tonic-gate	if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
8167c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
8177c478bdstevel@tonic-gate		    get_errstr());
8187c478bdstevel@tonic-gate
8197c478bdstevel@tonic-gate	if ((info_buf = pool_info(conf, pool, PO_TRUE)) == NULL)
8207c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(POOL),
8217c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8227c478bdstevel@tonic-gate	(void) printf("%s\n", info_buf);
8237c478bdstevel@tonic-gate	free(info_buf);
8247c478bdstevel@tonic-gate}
8257c478bdstevel@tonic-gate
8267c478bdstevel@tonic-gatestatic void
8277c478bdstevel@tonic-gateparser_resource_info(cmd_t *cmd, const char *type)
8287c478bdstevel@tonic-gate{
8297c478bdstevel@tonic-gate	pool_resource_t *resource;
8307c478bdstevel@tonic-gate	char *info_buf;
8317c478bdstevel@tonic-gate
8327c478bdstevel@tonic-gate	if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
8337c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
8347c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8357c478bdstevel@tonic-gate
8367c478bdstevel@tonic-gate	if ((info_buf = pool_resource_info(conf, resource, PO_TRUE)) == NULL)
8377c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(RESOURCE),
8387c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8397c478bdstevel@tonic-gate	(void) printf("%s\n", info_buf);
8407c478bdstevel@tonic-gate	free(info_buf);
8417c478bdstevel@tonic-gate}
8427c478bdstevel@tonic-gate
8437c478bdstevel@tonic-gatestatic void
8447c478bdstevel@tonic-gateparser_pset_info(cmd_t *cmd)
8457c478bdstevel@tonic-gate{
8467c478bdstevel@tonic-gate	parser_resource_info(cmd, PSET);
8477c478bdstevel@tonic-gate}
8487c478bdstevel@tonic-gate
8497c478bdstevel@tonic-gatestatic void
8507c478bdstevel@tonic-gateparser_cpu_info(cmd_t *cmd)
8517c478bdstevel@tonic-gate{
8527c478bdstevel@tonic-gate	pool_component_t *comp;
8537c478bdstevel@tonic-gate	char *info_buf;
8547c478bdstevel@tonic-gate
8557c478bdstevel@tonic-gate	if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL)
8567c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
8577c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8587c478bdstevel@tonic-gate	if ((info_buf = pool_component_info(conf, comp, PO_TRUE)) == NULL) {
8597c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CPU),
8607c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8617c478bdstevel@tonic-gate	}
8627c478bdstevel@tonic-gate	(void) printf("%s\n", info_buf);
8637c478bdstevel@tonic-gate	free(info_buf);
8647c478bdstevel@tonic-gate}
8657c478bdstevel@tonic-gate
8667c478bdstevel@tonic-gate/*
8677c478bdstevel@tonic-gate * Create Commands
8687c478bdstevel@tonic-gate * Invoke the appropriate libpool create function and perform any requested
8697c478bdstevel@tonic-gate * property operations.
8707c478bdstevel@tonic-gate */
8717c478bdstevel@tonic-gatestatic void
8727c478bdstevel@tonic-gateparser_conf_create(cmd_t *cmd)
8737c478bdstevel@tonic-gate{
8747c478bdstevel@tonic-gate	const char *tmp_name;
8757c478bdstevel@tonic-gate	pool_elem_t *pe;
8767c478bdstevel@tonic-gate
8777c478bdstevel@tonic-gate	if (conf != NULL && pool_conf_status(conf) >= POF_VALID)
8787c478bdstevel@tonic-gate		pool_conf_close(conf);
8797c478bdstevel@tonic-gate	if (pool_conf_open(conf, conf_file, PO_CREAT) != 0) {
8807c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
8817c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
8827c478bdstevel@tonic-gate	}
8837c478bdstevel@tonic-gate	tmp_name = cmd->cmd_tgt1;
8847c478bdstevel@tonic-gate	cmd->cmd_tgt1 = cmd->cmd_tgt2;
8857c478bdstevel@tonic-gate	cmd->cmd_tgt2 = tmp_name;
8867c478bdstevel@tonic-gate	parser_conf_rename(cmd);
8877c478bdstevel@tonic-gate	if ((pe = pool_conf_to_elem(conf)) == NULL)
8887c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS),
8897c478bdstevel@tonic-gate		    gettext(CONFIGURATION), "unknown", get_errstr());
8907c478bdstevel@tonic-gate	prop_list_walk(cmd, pe);
8917c478bdstevel@tonic-gate}
8927c478bdstevel@tonic-gate
8937c478bdstevel@tonic-gatestatic void
8947c478bdstevel@tonic-gateparser_pool_create(cmd_t *cmd)
8957c478bdstevel@tonic-gate{
8967c478bdstevel@tonic-gate	pool_t *pool;
8977c478bdstevel@tonic-gate
8987c478bdstevel@tonic-gate	if ((pool = pool_create(conf, cmd->cmd_tgt1)) == NULL)
8997c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
9007c478bdstevel@tonic-gate		    get_errstr());
9017c478bdstevel@tonic-gate	prop_list_walk(cmd, pool_to_elem(conf, pool));
9027c478bdstevel@tonic-gate}
9037c478bdstevel@tonic-gate
9047c478bdstevel@tonic-gatestatic void
9057c478bdstevel@tonic-gateparser_resource_create(cmd_t *cmd, const char *type)
9067c478bdstevel@tonic-gate{
9077c478bdstevel@tonic-gate	pool_resource_t *resource;
9087c478bdstevel@tonic-gate
9097c478bdstevel@tonic-gate	if ((resource = pool_resource_create(conf, type, cmd->cmd_tgt1))
9107c478bdstevel@tonic-gate	    == NULL)
9117c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), type, cmd->cmd_tgt1,
9127c478bdstevel@tonic-gate		    get_errstr());
91303dfa5bToomas Soome
9147c478bdstevel@tonic-gate	process_min_max(resource);
9157c478bdstevel@tonic-gate
9167c478bdstevel@tonic-gate	prop_list_walk(cmd, pool_resource_to_elem(conf, resource));
9177c478bdstevel@tonic-gate}
9187c478bdstevel@tonic-gate
9197c478bdstevel@tonic-gatestatic void
9207c478bdstevel@tonic-gateparser_pset_create(cmd_t *cmd)
9217c478bdstevel@tonic-gate{
9227c478bdstevel@tonic-gate	parser_resource_create(cmd, PSET);
9237c478bdstevel@tonic-gate}
9247c478bdstevel@tonic-gate
9257c478bdstevel@tonic-gate/*
9267c478bdstevel@tonic-gate * Rename Commands
9277c478bdstevel@tonic-gate * Rename the target by calling pool_put_property for the name property.
9287c478bdstevel@tonic-gate */
9297c478bdstevel@tonic-gatestatic void
9307c478bdstevel@tonic-gateparser_rename(cmd_t *cmd, pool_elem_t *pe, const char *name)
9317c478bdstevel@tonic-gate{
9327c478bdstevel@tonic-gate	pool_value_t *pv;
9337c478bdstevel@tonic-gate
9347c478bdstevel@tonic-gate	if ((pv = pool_value_alloc()) == NULL) {
9357c478bdstevel@tonic-gate		die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE),
9367c478bdstevel@tonic-gate		    get_errstr());
9377c478bdstevel@tonic-gate	}
9387c478bdstevel@tonic-gate	pool_value_set_string(pv, cmd->cmd_tgt2);
9397c478bdstevel@tonic-gate	if (pool_put_property(conf, pe, name, pv) != 0)
9407c478bdstevel@tonic-gate		die(gettext(ERR_PUT_PROPERTY), name, get_errstr());
9417c478bdstevel@tonic-gate	pool_value_free(pv);
9427c478bdstevel@tonic-gate}
9437c478bdstevel@tonic-gate
9447c478bdstevel@tonic-gatestatic void
9457c478bdstevel@tonic-gateparser_conf_rename(cmd_t *cmd)
9467c478bdstevel@tonic-gate{
9477c478bdstevel@tonic-gate	pool_elem_t *pe;
9487c478bdstevel@tonic-gate
9497c478bdstevel@tonic-gate	if ((pe = pool_conf_to_elem(conf)) == NULL)
9507c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS),
9517c478bdstevel@tonic-gate		    gettext(CONFIGURATION), "unknown", get_errstr());
9527c478bdstevel@tonic-gate
9537c478bdstevel@tonic-gate	if (cmd->cmd_tgt1 != NULL)
9547c478bdstevel@tonic-gate		check_conf_name(cmd);
9557c478bdstevel@tonic-gate
9567c478bdstevel@tonic-gate	parser_rename(cmd, pe, SYSTEM_NAME);
9577c478bdstevel@tonic-gate}
9587c478bdstevel@tonic-gate
9597c478bdstevel@tonic-gatestatic void
9607c478bdstevel@tonic-gateparser_pool_rename(cmd_t *cmd)
9617c478bdstevel@tonic-gate{
9627c478bdstevel@tonic-gate	pool_t *pool;
9637c478bdstevel@tonic-gate
9647c478bdstevel@tonic-gate	if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
9657c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
9667c478bdstevel@tonic-gate		    get_errstr());
9677c478bdstevel@tonic-gate
9687c478bdstevel@tonic-gate	parser_rename(cmd, pool_to_elem(conf, pool), POOL_NAME);
9697c478bdstevel@tonic-gate}
9707c478bdstevel@tonic-gate
9717c478bdstevel@tonic-gatestatic void
9727c478bdstevel@tonic-gateparser_pset_rename(cmd_t *cmd)
9737c478bdstevel@tonic-gate{
9747c478bdstevel@tonic-gate	pool_resource_t *resource;
9757c478bdstevel@tonic-gate
9767c478bdstevel@tonic-gate	if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
9777c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET), cmd->cmd_tgt1,
9787c478bdstevel@tonic-gate		    get_errstr());
9797c478bdstevel@tonic-gate
9807c478bdstevel@tonic-gate	parser_rename(cmd, pool_resource_to_elem(conf, resource), PSET_NAME);
9817c478bdstevel@tonic-gate}
9827c478bdstevel@tonic-gate
9837c478bdstevel@tonic-gate/*
9847c478bdstevel@tonic-gate * Destroy Commands
9857c478bdstevel@tonic-gate * Invoke the appropriate libpool destroy function to remove the target of the
9867c478bdstevel@tonic-gate * command from the configuration.
9877c478bdstevel@tonic-gate */
9887c478bdstevel@tonic-gatestatic void
9897c478bdstevel@tonic-gateparser_conf_destroy(cmd_t *cmd)
9907c478bdstevel@tonic-gate{
9917c478bdstevel@tonic-gate	if (cmd->cmd_tgt1 != NULL)
9927c478bdstevel@tonic-gate		check_conf_name(cmd);
9937c478bdstevel@tonic-gate
9947c478bdstevel@tonic-gate	if (pool_conf_remove(conf) != 0)
9957c478bdstevel@tonic-gate		die(gettext(ERR_DESTROY_ELEMENT), gettext(CONFIGURATION),
9967c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
9977c478bdstevel@tonic-gate}
9987c478bdstevel@tonic-gate
9997c478bdstevel@tonic-gatestatic void
10007c478bdstevel@tonic-gateparser_pool_destroy(cmd_t *cmd)
10017c478bdstevel@tonic-gate{
10027c478bdstevel@tonic-gate	pool_t *pool;
10037c478bdstevel@tonic-gate
10047c478bdstevel@tonic-gate	if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
10057c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
10067c478bdstevel@tonic-gate		    get_errstr());
10077c478bdstevel@tonic-gate
10087c478bdstevel@tonic-gate	if (pool_destroy(conf, pool) != 0)
10097c478bdstevel@tonic-gate		die(gettext(ERR_DESTROY_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
10107c478bdstevel@tonic-gate		    get_errstr());
10117c478bdstevel@tonic-gate}
10127c478bdstevel@tonic-gate
10137c478bdstevel@tonic-gatestatic void
10147c478bdstevel@tonic-gateparser_resource_destroy(cmd_t *cmd, const char *type)
10157c478bdstevel@tonic-gate{
10167c478bdstevel@tonic-gate	pool_resource_t *resource;
10177c478bdstevel@tonic-gate
10187c478bdstevel@tonic-gate	if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
10197c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), type, cmd->cmd_tgt1,
10207c478bdstevel@tonic-gate		    get_errstr());
10217c478bdstevel@tonic-gate
10227c478bdstevel@tonic-gate	if (pool_resource_destroy(conf, resource) != 0)
10237c478bdstevel@tonic-gate		die(gettext(ERR_DESTROY_ELEMENT), type, cmd->cmd_tgt1,
10247c478bdstevel@tonic-gate		    get_errstr());
10257c478bdstevel@tonic-gate}
10267c478bdstevel@tonic-gate
10277c478bdstevel@tonic-gatestatic void
10287c478bdstevel@tonic-gateparser_pset_destroy(cmd_t *cmd)
10297c478bdstevel@tonic-gate{
10307c478bdstevel@tonic-gate	parser_resource_destroy(cmd, PSET);
10317c478bdstevel@tonic-gate}
10327c478bdstevel@tonic-gate
10337c478bdstevel@tonic-gate/*
10347c478bdstevel@tonic-gate * Modify Commands
10357c478bdstevel@tonic-gate * Perform any requested property operations.
10367c478bdstevel@tonic-gate */
10377c478bdstevel@tonic-gatestatic void
10387c478bdstevel@tonic-gateparser_conf_modify(cmd_t *cmd)
10397c478bdstevel@tonic-gate{
10407c478bdstevel@tonic-gate	pool_elem_t *pe;
10417c478bdstevel@tonic-gate
10427c478bdstevel@tonic-gate	if ((pe = pool_conf_to_elem(conf)) == NULL)
10437c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS),
10447c478bdstevel@tonic-gate		    gettext(CONFIGURATION), "unknown", get_errstr());
10457c478bdstevel@tonic-gate
10467c478bdstevel@tonic-gate	if (cmd->cmd_tgt1 != NULL)
10477c478bdstevel@tonic-gate		check_conf_name(cmd);
10487c478bdstevel@tonic-gate
10497c478bdstevel@tonic-gate	prop_list_walk(cmd, pe);
10507c478bdstevel@tonic-gate}
10517c478bdstevel@tonic-gate
10527c478bdstevel@tonic-gatestatic void
10537c478bdstevel@tonic-gateparser_pool_modify(cmd_t *cmd)
10547c478bdstevel@tonic-gate{
10557c478bdstevel@tonic-gate	pool_t *pool;
10567c478bdstevel@tonic-gate
10577c478bdstevel@tonic-gate	if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
10587c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
10597c478bdstevel@tonic-gate		    get_errstr());
10607c478bdstevel@tonic-gate	prop_list_walk(cmd, pool_to_elem(conf, pool));
10617c478bdstevel@tonic-gate}
10627c478bdstevel@tonic-gate
10637c478bdstevel@tonic-gatestatic void
10647c478bdstevel@tonic-gateparser_resource_modify(cmd_t *cmd, const char *type)
10657c478bdstevel@tonic-gate{
10667c478bdstevel@tonic-gate	pool_resource_t *resource;
10677c478bdstevel@tonic-gate
10687c478bdstevel@tonic-gate	if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL)
10697c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
10707c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
10717c478bdstevel@tonic-gate
10727c478bdstevel@tonic-gate	process_min_max(resource);
10737c478bdstevel@tonic-gate
10747c478bdstevel@tonic-gate	prop_list_walk(cmd, pool_resource_to_elem(conf, resource));
10757c478bdstevel@tonic-gate}
10767c478bdstevel@tonic-gate
10777c478bdstevel@tonic-gatestatic void
10787c478bdstevel@tonic-gateparser_pset_modify(cmd_t *cmd)
10797c478bdstevel@tonic-gate{
10807c478bdstevel@tonic-gate	parser_resource_modify(cmd, PSET);
10817c478bdstevel@tonic-gate}
10827c478bdstevel@tonic-gate
10837c478bdstevel@tonic-gatestatic void
10847c478bdstevel@tonic-gateparser_cpu_modify(cmd_t *cmd)
10857c478bdstevel@tonic-gate{
10867c478bdstevel@tonic-gate	pool_component_t *comp;
10877c478bdstevel@tonic-gate
10887c478bdstevel@tonic-gate	if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL)
10897c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
10907c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
10917c478bdstevel@tonic-gate	prop_list_walk(cmd, pool_component_to_elem(conf, comp));
10927c478bdstevel@tonic-gate}
10937c478bdstevel@tonic-gate
10947c478bdstevel@tonic-gate/*
10957c478bdstevel@tonic-gate * Discover Commands
10967c478bdstevel@tonic-gate * Invoke the libpool pool_conf_open function so that discovery will be
10977c478bdstevel@tonic-gate * performed.
10987c478bdstevel@tonic-gate */
10997c478bdstevel@tonic-gate
11007c478bdstevel@tonic-gate/*ARGSUSED*/
11017c478bdstevel@tonic-gatestatic void
11027c478bdstevel@tonic-gateparser_conf_discover(cmd_t *cmd)
11037c478bdstevel@tonic-gate{
11047c478bdstevel@tonic-gate	struct utsname utsname;
11057c478bdstevel@tonic-gate
11067c478bdstevel@tonic-gate	if (strcmp(conf_file, pool_dynamic_location()) == 0)
11077c478bdstevel@tonic-gate		return;
11087c478bdstevel@tonic-gate
11097c478bdstevel@tonic-gate	if (uname(&utsname) < 0)
11107c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
11117c478bdstevel@tonic-gate		    "unknown", get_errstr());
11127c478bdstevel@tonic-gate
11137c478bdstevel@tonic-gate	if (conf != NULL && pool_conf_status(conf) >= POF_VALID)
11147c478bdstevel@tonic-gate		pool_conf_close(conf);
11157c478bdstevel@tonic-gate	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != 0) {
11167c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
11177c478bdstevel@tonic-gate		    utsname.nodename, get_errstr());
11187c478bdstevel@tonic-gate	}
11197c478bdstevel@tonic-gate	if (pool_conf_export(conf, conf_file, POX_NATIVE) != 0) {
11207c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
11217c478bdstevel@tonic-gate		    utsname.nodename, get_errstr());
11227c478bdstevel@tonic-gate	}
11237c478bdstevel@tonic-gate	(void) pool_conf_close(conf);
11247c478bdstevel@tonic-gate	if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) {
11257c478bdstevel@tonic-gate		die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION),
11267c478bdstevel@tonic-gate		    utsname.nodename, get_errstr());
11277c478bdstevel@tonic-gate	}
11287c478bdstevel@tonic-gate}
11297c478bdstevel@tonic-gate
11307c478bdstevel@tonic-gate/*
11317c478bdstevel@tonic-gate * Associate Commands
11327c478bdstevel@tonic-gate * Walk the list of specified associations so that the target pool will be
11337c478bdstevel@tonic-gate * associated with the required resources.
11347c478bdstevel@tonic-gate */
11357c478bdstevel@tonic-gate
11367c478bdstevel@tonic-gatestatic void
11377c478bdstevel@tonic-gateparser_pool_associate(cmd_t *cmd)
11387c478bdstevel@tonic-gate{
11397c478bdstevel@tonic-gate	pool_t *pool;
11407c478bdstevel@tonic-gate
11417c478bdstevel@tonic-gate	if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL)
11427c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1,
11437c478bdstevel@tonic-gate		    get_errstr());
11447c478bdstevel@tonic-gate	assoc_list_walk(cmd, pool);
11457c478bdstevel@tonic-gate}
11467c478bdstevel@tonic-gate
11477c478bdstevel@tonic-gate/*
11487c478bdstevel@tonic-gate * Assign Commands
11497c478bdstevel@tonic-gate * Walk the list of specified assignations so that the required
11507c478bdstevel@tonic-gate * components will be assigned to the target resource.
11517c478bdstevel@tonic-gate */
11527c478bdstevel@tonic-gate
11537c478bdstevel@tonic-gatestatic void
11547c478bdstevel@tonic-gateparser_resource_xtransfer(cmd_t *cmd)
11557c478bdstevel@tonic-gate{
11567c478bdstevel@tonic-gate	pool_resource_t *resource;
11577c478bdstevel@tonic-gate
11587c478bdstevel@tonic-gate	if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
11597c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
11607c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
11617c478bdstevel@tonic-gate	transfer_list_walk(cmd, resource);
11627c478bdstevel@tonic-gate}
11637c478bdstevel@tonic-gate
11647c478bdstevel@tonic-gate/*
11657c478bdstevel@tonic-gate * Transfer Commands
11667c478bdstevel@tonic-gate * Transfer the specified quantity of resource between the src and the tgt.
11677c478bdstevel@tonic-gate */
11687c478bdstevel@tonic-gate
11697c478bdstevel@tonic-gatestatic void
11707c478bdstevel@tonic-gateparser_resource_transfer(cmd_t *cmd)
11717c478bdstevel@tonic-gate{
11727c478bdstevel@tonic-gate	pool_resource_t *src;
11737c478bdstevel@tonic-gate	pool_resource_t *tgt;
11747c478bdstevel@tonic-gate
11757c478bdstevel@tonic-gate	if ((src = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL)
11767c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
11777c478bdstevel@tonic-gate		    cmd->cmd_tgt1, get_errstr());
11787c478bdstevel@tonic-gate	if ((tgt = pool_get_resource(conf, PSET, cmd->cmd_tgt2)) == NULL)
11797c478bdstevel@tonic-gate		die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE),
11807c478bdstevel@tonic-gate		    cmd->cmd_tgt2, get_errstr());
11817c478bdstevel@tonic-gate	if (pool_resource_transfer(conf, src, tgt, cmd->cmd_qty) != PO_SUCCESS)
11827c478bdstevel@tonic-gate		die(gettext(ERR_XFER_QUANTITY), cmd->cmd_qty,
11837c478bdstevel@tonic-gate		    cmd->cmd_tgt1, cmd->cmd_tgt2, get_errstr());
11847c478bdstevel@tonic-gate}
11857c478bdstevel@tonic-gate
11867c478bdstevel@tonic-gate/*
11877c478bdstevel@tonic-gate * arg_parse() puts the parser into command parsing mode. Create a tmpfile
11887c478bdstevel@tonic-gate * and instruct the parser to read instructions from this location by setting
11897c478bdstevel@tonic-gate * yyin to the value returned by tmpfile. Write the command into the file.
11907c478bdstevel@tonic-gate * Then seek back to to the start of the file so that the parser can read
11917c478bdstevel@tonic-gate * the instructions.
11927c478bdstevel@tonic-gate */
11937c478bdstevel@tonic-gatestatic void
11947c478bdstevel@tonic-gatearg_parse(const char *command)
11957c478bdstevel@tonic-gate{
11967c478bdstevel@tonic-gate	if ((yyin = tmpfile()) == NULL)
11977c478bdstevel@tonic-gate		die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
11987c478bdstevel@tonic-gate	if (fwrite(command, strlen(command), 1, yyin) != 1)
11997c478bdstevel@tonic-gate		die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
12007c478bdstevel@tonic-gate	if (fseek(yyin, 0, SEEK_SET) != 0)
12017c478bdstevel@tonic-gate		die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
12027c478bdstevel@tonic-gate}
12037c478bdstevel@tonic-gate
12047c478bdstevel@tonic-gate/*
12057c478bdstevel@tonic-gate * file_parse() puts the parser into command file parsing mode. Firstly check
12067c478bdstevel@tonic-gate * to see if the user wishes to parse from standard input, if so do nothing.
12077c478bdstevel@tonic-gate * Attempt to open the specified file and instruct the parser to read
12087c478bdstevel@tonic-gate * instructions from this location by setting yyin to the value returned by
12097c478bdstevel@tonic-gate * fopen.
12107c478bdstevel@tonic-gate */
12117c478bdstevel@tonic-gatestatic void
12127c478bdstevel@tonic-gatefile_parse(const char *file)
12137c478bdstevel@tonic-gate{
12147c478bdstevel@tonic-gate	if (strcmp(file, "-") == 0)
12157c478bdstevel@tonic-gate		return;
12167c478bdstevel@tonic-gate
12177c478bdstevel@tonic-gate	if ((yyin = fopen(file, "r")) == NULL) {
12187c478bdstevel@tonic-gate		die(gettext(ERR_CMD_FILE_INIT), strerror(errno));
12197c478bdstevel@tonic-gate	}
12207c478bdstevel@tonic-gate}
12217c478bdstevel@tonic-gate
12227c478bdstevel@tonic-gate/*
12237c478bdstevel@tonic-gate * free_cmd() releases the resources associated with the supplied cmd parameter.
12247c478bdstevel@tonic-gate */
12257c478bdstevel@tonic-gatestatic void
12267c478bdstevel@tonic-gatefree_cmd(cmd_t *cmd)
12277c478bdstevel@tonic-gate{
12287c478bdstevel@tonic-gate	prop_t *prop = cmd->cmd_prop_list;
12297c478bdstevel@tonic-gate	assoc_t *assoc = cmd->cmd_assoc_list;
12307c478bdstevel@tonic-gate
12317c478bdstevel@tonic-gate	free((void *)cmd->cmd_tgt1);
12327c478bdstevel@tonic-gate	free((void *)cmd->cmd_tgt2);
12337c478bdstevel@tonic-gate	while (prop != NULL) {
12347c478bdstevel@tonic-gate		prop_t *tmp = prop;
12357c478bdstevel@tonic-gate		prop = prop->prop_next;
12367c478bdstevel@tonic-gate		pool_value_free(tmp->prop_value);
12377c478bdstevel@tonic-gate		free((void *)tmp->prop_name);
12387c478bdstevel@tonic-gate		free(tmp);
12397c478bdstevel@tonic-gate	}
12407c478bdstevel@tonic-gate	while (assoc != NULL) {
12417c478bdstevel@tonic-gate		assoc_t *tmp = assoc;
12427c478bdstevel@tonic-gate		assoc = assoc->assoc_next;
12437c478bdstevel@tonic-gate		free((void *)tmp->assoc_name);
12447c478bdstevel@tonic-gate		free(tmp);
12457c478bdstevel@tonic-gate	}
12467c478bdstevel@tonic-gate	free(cmd);
12477c478bdstevel@tonic-gate}
12487c478bdstevel@tonic-gate
12497c478bdstevel@tonic-gate/*
12507c478bdstevel@tonic-gate * alloc_cmd() allocates the required resources for a cmd_t. On failure, a
12517c478bdstevel@tonic-gate * warning is issued and NULL is returned.
12527c478bdstevel@tonic-gate */
12537c478bdstevel@tonic-gatestatic cmd_t *
12547c478bdstevel@tonic-gatealloc_cmd(void)
12557c478bdstevel@tonic-gate{
12567c478bdstevel@tonic-gate	cmd_t *cmd;
12577c478bdstevel@tonic-gate
12587c478bdstevel@tonic-gate	if ((cmd = malloc(sizeof (cmd_t))) == NULL) {
12597c478bdstevel@tonic-gate		warn(gettext(ERR_CMD_LINE_ALLOC));
12607c478bdstevel@tonic-gate		return (NULL);
12617c478bdstevel@tonic-gate	}
12627c478bdstevel@tonic-gate
12637c478bdstevel@tonic-gate	(void) memset(cmd, 0, sizeof (cmd_t));
12647c478bdstevel@tonic-gate
12657c478bdstevel@tonic-gate	return (cmd);
12667c478bdstevel@tonic-gate}
12677c478bdstevel@tonic-gate
12687c478bdstevel@tonic-gate/*
12697c478bdstevel@tonic-gate * alloc_prop() allocates the required resources for a prop_t. On failure, a
12707c478bdstevel@tonic-gate * warning is issued and NULL is returned. The prop_t is initialised with
12717c478bdstevel@tonic-gate * the prop_op_t parameter.
12727c478bdstevel@tonic-gate */
12737c478bdstevel@tonic-gatestatic prop_t *
12747c478bdstevel@tonic-gatealloc_prop(prop_op_t op)
12757c478bdstevel@tonic-gate{
12767c478bdstevel@tonic-gate	prop_t *prop;
12777c478bdstevel@tonic-gate
12787c478bdstevel@tonic-gate	if ((prop = malloc(sizeof (prop_t))) == NULL) {
12797c478bdstevel@tonic-gate		warn(gettext(ERR_PROP_ALLOC));
12807c478bdstevel@tonic-gate		return (NULL);
12817c478bdstevel@tonic-gate	}
12827c478bdstevel@tonic-gate
12837c478bdstevel@tonic-gate	(void) memset(prop, 0, sizeof (prop_t));
12847c478bdstevel@tonic-gate	if ((prop->prop_value = pool_value_alloc()) == NULL) {
12857c478bdstevel@tonic-gate		warn(gettext(ERR_PROP_ALLOC));
12867c478bdstevel@tonic-gate		free(prop);
12877c478bdstevel@tonic-gate		return (NULL);
12887c478bdstevel@tonic-gate	}
12897c478bdstevel@tonic-gate	prop->prop_op = op;
12907c478bdstevel@tonic-gate	return (prop);
12917c478bdstevel@tonic-gate}
12927c478bdstevel@tonic-gate
12937c478bdstevel@tonic-gate/*
12947c478bdstevel@tonic-gate * alloc_assoc() allocates the required resources for an assoc_t. On failure, a
12957c478bdstevel@tonic-gate * warning is issued and NULL is returned. The assoc_t is initialised with
12967c478bdstevel@tonic-gate * the type and name of the association.
12977c478bdstevel@tonic-gate */
12987c478bdstevel@tonic-gatestatic assoc_t *
12997c478bdstevel@tonic-gatealloc_assoc(int type, const char *name)
13007c478bdstevel@tonic-gate{
13017c478bdstevel@tonic-gate	assoc_t *assoc;
13027c478bdstevel@tonic-gate
13037c478bdstevel@tonic-gate	if ((assoc = malloc(sizeof (assoc_t))) == NULL) {
13047c478bdstevel@tonic-gate		warn(gettext(ERR_ASSOC_ALLOC));
13057c478bdstevel@tonic-gate		return (NULL);
13067c478bdstevel@tonic-gate	}
13077c478bdstevel@tonic-gate	(void) memset(assoc, 0, sizeof (assoc_t));
13087c478bdstevel@tonic-gate	assoc->assoc_type = type;
13097c478bdstevel@tonic-gate	assoc->assoc_name = name;
13107c478bdstevel@tonic-gate	return (assoc);
13117c478bdstevel@tonic-gate}
13127c478bdstevel@tonic-gate
13137c478bdstevel@tonic-gate/*
13147c478bdstevel@tonic-gate * check_conf_name() ensures the the name of the system in the configuration
13157c478bdstevel@tonic-gate * which is being manipulated matches the name of the system in the command.
13167c478bdstevel@tonic-gate * If not, the command is terminated with an appropriate error message.
13177c478bdstevel@tonic-gate */
13187c478bdstevel@tonic-gatestatic void
13197c478bdstevel@tonic-gatecheck_conf_name(cmd_t *cmd)
13207c478bdstevel@tonic-gate{
13217c478bdstevel@tonic-gate	pool_value_t *pv;
13227c478bdstevel@tonic-gate	const char *name;
13237c478bdstevel@tonic-gate	pool_elem_t *pe;
13247c478bdstevel@tonic-gate
13257c478bdstevel@tonic-gate	if ((pe = pool_conf_to_elem(conf)) == NULL)
13267c478bdstevel@tonic-gate		die(gettext(ERR_GET_ELEMENT_DETAILS),
13277c478bdstevel@tonic-gate		    gettext(CONFIGURATION), "unknown", get_errstr());
13287c478bdstevel@tonic-gate
13297c478bdstevel@tonic-gate
13307c478bdstevel@tonic-gate	if ((pv = pool_value_alloc()) == NULL) {
13317c478bdstevel@tonic-gate		die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE),
13327c478bdstevel@tonic-gate		    get_errstr());
13337c478bdstevel@tonic-gate	}
13347c478bdstevel@tonic-gate
13357c478bdstevel@tonic-gate	if (pool_get_property(conf, pe, SYSTEM_NAME, pv)
13367c478bdstevel@tonic-gate	    == POC_INVAL)
13377c478bdstevel@tonic-gate		die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME),
13387c478bdstevel@tonic-gate		    get_errstr());
13397c478bdstevel@tonic-gate
13407c478bdstevel@tonic-gate	if (pool_value_get_string(pv, &name) == PO_FAIL)
13417c478bdstevel@tonic-gate		die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME),
13427c478bdstevel@tonic-gate		    get_errstr());
13437c478bdstevel@tonic-gate
13447c478bdstevel@tonic-gate	if (strcmp(cmd->cmd_tgt1, name) != 0) {
13457c478bdstevel@tonic-gate		die(gettext(ERR_WRONG_SYSTEM_NAME), cmd->cmd_tgt1);
13467c478bdstevel@tonic-gate	}
13477c478bdstevel@tonic-gate	pool_value_free(pv);
13487c478bdstevel@tonic-gate}
13497c478bdstevel@tonic-gate
13507c478bdstevel@tonic-gate/*
13517c478bdstevel@tonic-gate * usage() display brief or verbose help for the poolcfg(1) command.
13527c478bdstevel@tonic-gate */
13537c478bdstevel@tonic-gatestatic void
13547c478bdstevel@tonic-gateusage(int help)
13557c478bdstevel@tonic-gate{
13567c478bdstevel@tonic-gate	if (help >= 1)
13577c478bdstevel@tonic-gate		(void) fprintf(stderr, gettext(USAGE1), cmdname, cmdname,
13587c478bdstevel@tonic-gate		    cmdname);
13597c478bdstevel@tonic-gate	if (help >= 2)
13607c478bdstevel@tonic-gate		(void) fprintf(stderr, gettext(USAGE2));
13617c478bdstevel@tonic-gate	exit(E_USAGE);
13627c478bdstevel@tonic-gate}
13637c478bdstevel@tonic-gate
13647c478bdstevel@tonic-gate/*
13657c478bdstevel@tonic-gate * prop_list_walk() walks the property manipulation requests and either puts
13667c478bdstevel@tonic-gate * or removes the property as appropriate.
13677c478bdstevel@tonic-gate */
13687c478bdstevel@tonic-gatestatic void
13697c478bdstevel@tonic-gateprop_list_walk(cmd_t *cmd, pool_elem_t *pe)
13707c478bdstevel@tonic-gate{
13717c478bdstevel@tonic-gate	prop_t *prop;
13727c478bdstevel@tonic-gate
13737c478bdstevel@tonic-gate	for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) {
13747c478bdstevel@tonic-gate		switch (prop->prop_op) {
13757c478bdstevel@tonic-gate		case po_create:
13767c478bdstevel@tonic-gate			if (pool_put_property(conf, pe, prop->prop_name,
13777c478bdstevel@tonic-gate			    prop->prop_value) != 0)
13787c478bdstevel@tonic-gate				die(gettext(ERR_PUT_PROPERTY),
13797c478bdstevel@tonic-gate				    prop->prop_name, get_errstr());
13807c478bdstevel@tonic-gate			break;
13817c478bdstevel@tonic-gate		case po_remove:
13827c478bdstevel@tonic-gate			if (pool_rm_property(conf, pe, prop->prop_name) != 0)
13837c478bdstevel@tonic-gate				die(gettext(ERR_REMOVE_PROPERTY),
13847c478bdstevel@tonic-gate				    prop->prop_name, get_errstr());
13857c478bdstevel@tonic-gate			break;
13867c478bdstevel@tonic-gate		}
13877c478bdstevel@tonic-gate	}
13887c478bdstevel@tonic-gate}
13897c478bdstevel@tonic-gate
13907c478bdstevel@tonic-gate/*
13917c478bdstevel@tonic-gate * assoc_list_walk() walks the resource association requests and attempts
13927c478bdstevel@tonic-gate * to associate the pool with the specified resource.
13937c478bdstevel@tonic-gate */
13947c478bdstevel@tonic-gatestatic void
13957c478bdstevel@tonic-gateassoc_list_walk(cmd_t *cmd, pool_t *pool)
13967c478bdstevel@tonic-gate{
13977c478bdstevel@tonic-gate	assoc_t *assoc;
13987c478bdstevel@tonic-gate
13997c478bdstevel@tonic-gate	for (assoc = cmd->cmd_assoc_list; assoc != NULL;
14007c478bdstevel@tonic-gate	    assoc = assoc->assoc_next) {
14017c478bdstevel@tonic-gate		pool_resource_t *resource;
14027c478bdstevel@tonic-gate
14037c478bdstevel@tonic-gate		switch (assoc->assoc_type) {
14047c478bdstevel@tonic-gate		case PCE_PSET:
14057c478bdstevel@tonic-gate			if ((resource = pool_get_resource(conf,
14067c478bdstevel@tonic-gate			    PSET, assoc->assoc_name)) == NULL)
14077c478bdstevel@tonic-gate				die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET),
14087c478bdstevel@tonic-gate				    assoc->assoc_name, get_errstr());
14097c478bdstevel@tonic-gate			break;
14107c478bdstevel@tonic-gate		default:
14117c478bdstevel@tonic-gate			die(gettext(ERR_UNKNOWN_RESOURCE),
14127c478bdstevel@tonic-gate			    assoc->assoc_type);
14137c478bdstevel@tonic-gate			break;
14147c478bdstevel@tonic-gate		}
14157c478bdstevel@tonic-gate		if (pool_associate(conf, pool, resource) != 0)
14167c478bdstevel@tonic-gate			die(gettext(ERR_ASSOC_RESOURCE), assoc->assoc_name,
14177c478bdstevel@tonic-gate			    get_errstr());
14187c478bdstevel@tonic-gate	}
14197c478bdstevel@tonic-gate}
14207c478bdstevel@tonic-gate
14217c478bdstevel@tonic-gate/*
14227c478bdstevel@tonic-gate * transfer_list_walk() walks the component assign requests and attempts
14237c478bdstevel@tonic-gate * to assign the component with the specified resource.
14247c478bdstevel@tonic-gate */
14257c478bdstevel@tonic-gatestatic void
14267c478bdstevel@tonic-gatetransfer_list_walk(cmd_t *cmd, pool_resource_t *tgt)
14277c478bdstevel@tonic-gate{
14287c478bdstevel@tonic-gate	assoc_t *assoc;
14297c478bdstevel@tonic-gate
14307c478bdstevel@tonic-gate	for (assoc = cmd->cmd_assoc_list; assoc != NULL;
14317c478bdstevel@tonic-gate	    assoc = assoc->assoc_next) {
14327c478bdstevel@tonic-gate		pool_component_t *comp;
14337c478bdstevel@tonic-gate		pool_resource_t *src;
143403dfa5bToomas Soome		pool_component_t *xfer[2] = {NULL};
14357c478bdstevel@tonic-gate
14367c478bdstevel@tonic-gate		if ((comp = get_cpu(assoc->assoc_name)) == NULL)
14377c478bdstevel@tonic-gate			die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
14387c478bdstevel@tonic-gate			    assoc->assoc_name, get_errstr());
14397c478bdstevel@tonic-gate		if ((src = pool_get_owning_resource(conf, comp)) == NULL)
14407c478bdstevel@tonic-gate			die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT),
14417c478bdstevel@tonic-gate			    assoc->assoc_name, cmd->cmd_tgt1, get_errstr());
14427c478bdstevel@tonic-gate		xfer[0] = comp;
14437c478bdstevel@tonic-gate		if (pool_resource_xtransfer(conf, src, tgt, xfer) !=
14447c478bdstevel@tonic-gate		    PO_SUCCESS)
14457c478bdstevel@tonic-gate			die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT),
14467c478bdstevel@tonic-gate			    assoc->assoc_name, cmd->cmd_tgt1, get_errstr());
14477c478bdstevel@tonic-gate	}
14487c478bdstevel@tonic-gate}
14497c478bdstevel@tonic-gate
14507c478bdstevel@tonic-gate/*
14517c478bdstevel@tonic-gate * terminate() is invoked when poolcfg exits. It cleans up
14527c478bdstevel@tonic-gate * configurations and closes the parser input stream.
14537c478bdstevel@tonic-gate */
14547c478bdstevel@tonic-gatestatic void
14557c478bdstevel@tonic-gateterminate(void)
14567c478bdstevel@tonic-gate{
14577c478bdstevel@tonic-gate	if (conf != NULL) {
14587c478bdstevel@tonic-gate		(void) pool_conf_close(conf);
14597c478bdstevel@tonic-gate		pool_conf_free(conf);
14607c478bdstevel@tonic-gate	}
14617c478bdstevel@tonic-gate	if (yyin != stdin)
14627c478bdstevel@tonic-gate		(void) fclose(yyin);
14637c478bdstevel@tonic-gate}
14647c478bdstevel@tonic-gate
14657c478bdstevel@tonic-gate/*
14667c478bdstevel@tonic-gate * get_cpu() takes the name of a CPU components and attempts to locate
14677c478bdstevel@tonic-gate * the element with that name. If the name is not formatted correctly
14687c478bdstevel@tonic-gate * (i.e. contains non-numeric characters) then the function terminates
14697c478bdstevel@tonic-gate * execution. If the components cannot be uniquely identified by the
14707c478bdstevel@tonic-gate * name, then NULL is returned.
14717c478bdstevel@tonic-gate */
14727c478bdstevel@tonic-gatestatic pool_component_t *
14737c478bdstevel@tonic-gateget_cpu(const char *name)
14747c478bdstevel@tonic-gate{
14757c478bdstevel@tonic-gate	pool_component_t **components;
14767c478bdstevel@tonic-gate	uint_t nelem;
14777c478bdstevel@tonic-gate	int64_t sysid;
14787c478bdstevel@tonic-gate	pool_value_t *vals[3] = {NULL};
14797c478bdstevel@tonic-gate	pool_component_t *ret;
14807c478bdstevel@tonic-gate	const char *c;
14817c478bdstevel@tonic-gate
14827c478bdstevel@tonic-gate	if ((vals[0] = pool_value_alloc()) == NULL)
14837c478bdstevel@tonic-gate		return (NULL);
14847c478bdstevel@tonic-gate	if ((vals[1] = pool_value_alloc()) == NULL) {
14857c478bdstevel@tonic-gate		pool_value_free(vals[0]);
14867c478bdstevel@tonic-gate		return (NULL);
14877c478bdstevel@tonic-gate	}
14887c478bdstevel@tonic-gate	if (pool_value_set_string(vals[0], "cpu") != PO_SUCCESS ||
14897c478bdstevel@tonic-gate	    pool_value_set_name(vals[0], "type") != PO_SUCCESS) {
14907c478bdstevel@tonic-gate		pool_value_free(vals[0]);
14917c478bdstevel@tonic-gate		pool_value_free(vals[1]);
14927c478bdstevel@tonic-gate		return (NULL);
14937c478bdstevel@tonic-gate	}
14947c478bdstevel@tonic-gate
149503dfa5bToomas Soome	for (c = name; *c != '\0'; c++) {
14967c478bdstevel@tonic-gate		if (!isdigit(*c)){
14977c478bdstevel@tonic-gate			pool_value_free(vals[0]);
14987c478bdstevel@tonic-gate			pool_value_free(vals[1]);
14997c478bdstevel@tonic-gate			die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU),
150003dfa5bToomas Soome			    cmd->cmd_tgt1, gettext("CPU id should only contain "
15017c478bdstevel@tonic-gate			    "digits"));
15027c478bdstevel@tonic-gate		}
15037c478bdstevel@tonic-gate	}
15047c478bdstevel@tonic-gate	sysid = strtoll(name, NULL, 0);
15057c478bdstevel@tonic-gate	if (errno == ERANGE || errno == EINVAL) {
15067c478bdstevel@tonic-gate		pool_value_free(vals[0]);
15077c478bdstevel@tonic-gate		pool_value_free(vals[1]);
15087c478bdstevel@tonic-gate		return (NULL);
15097c478bdstevel@tonic-gate	}
15107c478bdstevel@tonic-gate	pool_value_set_int64(vals[1], sysid);
15117c478bdstevel@tonic-gate	if (pool_value_set_name(vals[1], CPU_SYSID) != PO_SUCCESS) {
15127c478bdstevel@tonic-gate		pool_value_free(vals[0]);
15137c478bdstevel@tonic-gate		pool_value_free(vals[1]);
15147c478bdstevel@tonic-gate		return (NULL);
15157c478bdstevel@tonic-gate	}
15167c478bdstevel@tonic-gate	if ((components = pool_query_components(conf, &nelem, vals)) ==
15177c478bdstevel@tonic-gate	    NULL) {
15187c478bdstevel@tonic-gate		pool_value_free(vals[0]);
15197c478bdstevel@tonic-gate		pool_value_free(vals[1]);
15207c478bdstevel@tonic-gate		return (NULL);
15217c478bdstevel@tonic-gate	}
15227c478bdstevel@tonic-gate	if (nelem != 1) {
15237c478bdstevel@tonic-gate		free(components);
15247c478bdstevel@tonic-gate		pool_value_free(vals[0]);
15257c478bdstevel@tonic-gate		pool_value_free(vals[1]);
15267c478bdstevel@tonic-gate		return (NULL);
15277c478bdstevel@tonic-gate	}
15287c478bdstevel@tonic-gate	pool_value_free(vals[0]);
15297c478bdstevel@tonic-gate	pool_value_free(vals[1]);
15307c478bdstevel@tonic-gate	ret = components[0];
15317c478bdstevel@tonic-gate	free(components);
15327c478bdstevel@tonic-gate	return (ret);
15337c478bdstevel@tonic-gate}
15347c478bdstevel@tonic-gate
15357c478bdstevel@tonic-gate/*
15367c478bdstevel@tonic-gate * process_min_max() ensures that "min" and "max" properties are
15377c478bdstevel@tonic-gate * processed correctly by poolcfg. libpool enforces validity
15387c478bdstevel@tonic-gate * constraints on these properties and so it's important that changes
15397c478bdstevel@tonic-gate * to them are supplied to the library in the correct order.
15407c478bdstevel@tonic-gate */
15417c478bdstevel@tonic-gatevoid
15427c478bdstevel@tonic-gateprocess_min_max(pool_resource_t *resource)
15437c478bdstevel@tonic-gate{
15447c478bdstevel@tonic-gate	prop_t *minprop = NULL;
15457c478bdstevel@tonic-gate	prop_t *maxprop = NULL;
15467c478bdstevel@tonic-gate	prop_t *prop;
15477c478bdstevel@tonic-gate
15487c478bdstevel@tonic-gate	/*
15497c478bdstevel@tonic-gate	 * Before walking the list of properties, it has to be checked
15507c478bdstevel@tonic-gate	 * to ensure there are no clashes between min and max. If
15517c478bdstevel@tonic-gate	 * there are, then process these properties immediately.
15527c478bdstevel@tonic-gate	 */
15537c478bdstevel@tonic-gate	for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) {
15547c478bdstevel@tonic-gate		const char *pos;
15557c478bdstevel@tonic-gate
15567c478bdstevel@tonic-gate		if ((pos = strstr(prop->prop_name, min_suffix)) != NULL)
15577c478bdstevel@tonic-gate			if (pos == prop->prop_name + strlen(prop->prop_name)
15587c478bdstevel@tonic-gate			    - 4)
15597c478bdstevel@tonic-gate				minprop = prop;
15607c478bdstevel@tonic-gate		if ((pos = strstr(prop->prop_name, max_suffix)) != NULL)
15617c478bdstevel@tonic-gate			if (pos == prop->prop_name + strlen(prop->prop_name)
15627c478bdstevel@tonic-gate			    - 4)
15637c478bdstevel@tonic-gate				maxprop = prop;
15647c478bdstevel@tonic-gate	}
15657c478bdstevel@tonic-gate	if (minprop && maxprop) {
15667c478bdstevel@tonic-gate		pool_value_t *pv;
15677c478bdstevel@tonic-gate		uint64_t smin, smax, dmax;
15687c478bdstevel@tonic-gate		const char *type;
15697c478bdstevel@tonic-gate		char *prop_name;
15707c478bdstevel@tonic-gate		pool_elem_t *pe = pool_resource_to_elem(conf, resource);
15717c478bdstevel@tonic-gate
15727c478bdstevel@tonic-gate		if ((pv = pool_value_alloc()) == NULL)
15737c478bdstevel@tonic-gate			die(gettext(ERR_NOMEM));
15747c478bdstevel@tonic-gate
15757c478bdstevel@tonic-gate		(void) pool_get_property(conf, pe, "type", pv);
15767c478bdstevel@tonic-gate		(void) pool_value_get_string(pv, &type);
15777c478bdstevel@tonic-gate
15787c478bdstevel@tonic-gate		if ((prop_name = malloc(strlen(type) + strlen(max_suffix)
15797c478bdstevel@tonic-gate		    + 1)) == NULL)
15807c478bdstevel@tonic-gate			die(gettext(ERR_NOMEM));
15817c478bdstevel@tonic-gate
15827c478bdstevel@tonic-gate		(void) sprintf(prop_name, "%s%s", type, max_suffix);
15837c478bdstevel@tonic-gate		(void) pool_get_property(conf, pe, prop_name, pv);
15847c478bdstevel@tonic-gate		(void) pool_value_get_uint64(pv, &dmax);
15857c478bdstevel@tonic-gate
15867c478bdstevel@tonic-gate		(void) pool_value_get_uint64(minprop->prop_value, &smin);
15877c478bdstevel@tonic-gate
15887c478bdstevel@tonic-gate		(void) pool_value_get_uint64(maxprop->prop_value, &smax);
15897c478bdstevel@tonic-gate		if (smin < dmax) {
15907c478bdstevel@tonic-gate			(void) pool_put_property(conf, pe,
15917c478bdstevel@tonic-gate			minprop->prop_name, minprop->prop_value);
15927c478bdstevel@tonic-gate		} else {
15937c478bdstevel@tonic-gate			(void) pool_put_property(conf, pe,
15947c478bdstevel@tonic-gate			maxprop->prop_name, maxprop->prop_value);
15957c478bdstevel@tonic-gate		}
15967c478bdstevel@tonic-gate		free((void *)prop_name);
15977c478bdstevel@tonic-gate		pool_value_free(pv);
15987c478bdstevel@tonic-gate	}
15997c478bdstevel@tonic-gate}
1600