1 2 # line 2 "poolcfg.y" 3 /* 4 * CDDL HEADER START 5 * 6 * The contents of this file are subject to the terms of the 7 * Common Development and Distribution License, Version 1.0 only 8 * (the "License"). You may not use this file except in compliance 9 * with the License. 10 * 11 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 12 * or http://www.opensolaris.org/os/licensing. 13 * See the License for the specific language governing permissions 14 * and limitations under the License. 15 * 16 * When distributing Covered Code, include this CDDL HEADER in each 17 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 18 * If applicable, add the following below this CDDL HEADER, with the 19 * fields enclosed by brackets "[]" replaced with your own identifying 20 * information: Portions Copyright [yyyy] [name of copyright owner] 21 * 22 * CDDL HEADER END 23 * 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * Overview of poolcfg(1) 32 * 33 * poolcfg(1) implements a small grammar for manipulating pools configurations. 34 * yacc(1) is used to generate the parser and poolcfg.l contains a simple lexer 35 * (generted by lex(1)) to perform lexical processsing of the input. 36 * 37 * Refer to the poolcfg(1) manpage for more details of the grammar. 38 * 39 * The parser is designed so that all operations implement the same interface. 40 * This allows the parser to simply build up the command (using the cmd 41 * variable) by storing arguments and a pointer to the desired function in the 42 * cmd. The command is executed when the commands production is matched. 43 * 44 * Properties and associations are stored in simple linked lists and processed 45 * in the order submitted by the user. 46 */ 47 48 #include <stdlib.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <errno.h> 52 #include <sys/types.h> 53 #include <locale.h> 54 #include <libintl.h> 55 #include <sys/utsname.h> 56 57 #include <pool.h> 58 #include "utils.h" 59 #include "poolcfg.h" 60 61 62 63 #define USAGE1 \ 64 "Usage:\n" \ 65 "%s -h\n" \ 66 "%s -c command [ -d | [ file ] ]\n" \ 67 "%s -f command-file [-d | [ file ] ]\n\n" 68 69 #define USAGE2 \ 70 "command:\n" \ 71 " info [entity name]\n" \ 72 " display configuration (or specified portion) in readable form\n" \ 73 " create entity name [property-list]\n" \ 74 " make an entity of the specified type and name\n" \ 75 " destroy entity name\n" \ 76 " remove the specified entity\n" \ 77 " modify entity name [property-list]\n" \ 78 " change the listed properties on the named entity\n" \ 79 " associate pool name [resource-list]\n" \ 80 " connect one or more resources to a pool, or replace one or more\n" \ 81 " existing connections\n" \ 82 " transfer to resource name [component-list]\n" \ 83 " transfer one or more discreet components to a resource\n" \ 84 " transfer [quantity] from resource src to tgt\n" \ 85 " transfer a resource quantity from src to tgt\n" \ 86 " transfer [quantity] to resource tgt from src\n" \ 87 " transfer a resource quantity to tgt from src\n" \ 88 " discover\n" \ 89 " create a system entity, with one pool entity and resources to\n" \ 90 " match current system configuration\n" \ 91 " rename entity old_name to new_name\n" \ 92 " change the name of the entity on the system to its new name\n\n" \ 93 "property-list:\n" \ 94 " ( proptype name = value [ ; proptype name = value ]* )\n" \ 95 " where multiple definitions in the sentence for a given\n" \ 96 " proptype, name pair are ignored; the last one provided is used.\n" \ 97 " For property deletion, use \"~ proptype name\"\n\n" \ 98 "resource-list:\n" \ 99 " ( resource name [; resource name ] )\n" \ 100 " where multiple uses of a resource are ignored; the last provided\n" \ 101 " is the one used.\n" \ 102 " There is no deletion syntax for resource lists.\n" \ 103 "component-list:\n" \ 104 " ( cpu id [; cpu id ] )\n" \ 105 " where multiple uses of the same component cause the last provided\n" \ 106 " to be the one used.\n" \ 107 " There is no deletion syntax for component lists.\n" \ 108 "entity:\n" \ 109 " system | pool | pset | cpu\n" \ 110 " where cpu is only valid for transfer, info and modify commands.\n" \ 111 "resource:\n" \ 112 " pset\n\n" \ 113 "proptype:\n" \ 114 " boolean | int | uint | string | float\n\n" 115 116 int dofile = PO_FALSE; /* poolcfg.l uses this for errors */ 117 int conf_edit_error = POE_OK; /* cached error for error reporting */ 118 int conf_edit_errno = 0; /* cached errno for error reporting */ 119 int conf_list_error = POE_OK; /* cached error for error reporting */ 120 int conf_list_errno = 0; /* cached errno for error reporting */ 121 static const char cmdname[] = "poolcfg"; 122 static const char cmd_options[] = "c:df:h"; 123 static void usage(int); 124 static const char *max_suffix = ".max"; 125 static const char *min_suffix = ".min"; 126 127 static const char *conf_file = NULL; /* Location of target config */ 128 static cmd_t *cmd = NULL; /* Command being processed */ 129 static pool_conf_t *conf = NULL; /* Config to be processed */ 130 static int edited = PO_FALSE; /* Has the configuration been changed */ 131 132 /* yacc externals */ 133 extern FILE *yyin; 134 extern int yydebug; 135 extern void yyerror(char *s); 136 137 /* Utility functions */ 138 static void arg_parse(const char *); 139 static void file_parse(const char *); 140 static cmd_t *alloc_cmd(void); 141 static prop_t *alloc_prop(prop_op_t); 142 static assoc_t *alloc_assoc(int, const char *); 143 static void free_cmd(cmd_t *); 144 static void check_conf_name(cmd_t *); 145 static void prop_list_walk(cmd_t *, pool_elem_t *); 146 static void assoc_list_walk(cmd_t *, pool_t *); 147 static void transfer_list_walk(cmd_t *, pool_resource_t *); 148 static void terminate(void); 149 static pool_component_t *get_cpu(const char *); 150 static void process_min_max(pool_resource_t *); 151 152 /* Info Commands */ 153 static void parser_conf_info(cmd_t *); 154 static void parser_pool_info(cmd_t *); 155 static void parser_resource_info(cmd_t *, const char *); 156 static void parser_pset_info(cmd_t *); 157 static void parser_cpu_info(cmd_t *); 158 159 /* Create Commands */ 160 static void parser_conf_create(cmd_t *); 161 static void parser_pool_create(cmd_t *); 162 static void parser_resource_create(cmd_t *, const char *); 163 static void parser_pset_create(cmd_t *); 164 165 /* Destroy Commands */ 166 static void parser_conf_destroy(cmd_t *); 167 static void parser_pool_destroy(cmd_t *); 168 static void parser_resource_destroy(cmd_t *, const char *); 169 static void parser_pset_destroy(cmd_t *); 170 171 /* Modify Commands */ 172 static void parser_conf_modify(cmd_t *); 173 static void parser_pool_modify(cmd_t *); 174 static void parser_resource_modify(cmd_t *, const char *); 175 static void parser_pset_modify(cmd_t *); 176 static void parser_cpu_modify(cmd_t *); 177 178 /* Associate Commands */ 179 static void parser_pool_associate(cmd_t *); 180 181 /* Assign Commands */ 182 static void parser_resource_xtransfer(cmd_t *); 183 static void parser_resource_transfer(cmd_t *); 184 185 /* Discover Commands */ 186 static void parser_conf_discover(cmd_t *); 187 188 /* Rename Commands */ 189 static void parser_rename(cmd_t *, pool_elem_t *, const char *); 190 static void parser_conf_rename(cmd_t *); 191 static void parser_pool_rename(cmd_t *); 192 static void parser_pset_rename(cmd_t *); 193 194 195 196 # line 196 "poolcfg.y" 197 typedef union 198 #ifdef __cplusplus 199 YYSTYPE 200 #endif 201 { 202 double dval; 203 uint64_t uval; 204 int64_t ival; 205 char *sval; 206 uchar_t bval; 207 cmd_t *cmd; 208 prop_t *prop; 209 pv_u val; 210 assoc_t *assoc; 211 } YYSTYPE; 212 # define PCC_INFO 257 213 # define PCC_CREATE 258 214 # define PCC_DESTROY 259 215 # define PCC_MODIFY 260 216 # define PCC_ASSOC 261 217 # define PCC_DISC 262 218 # define PCC_RENAME 263 219 # define PCC_TRANSFER 264 220 # define PCK_FROM 265 221 # define PCK_TO 266 222 # define PCK_OPENLST 267 223 # define PCK_CLOSELST 268 224 # define PCK_SEPLST 269 225 # define PCK_ASSIGN 270 226 # define PCK_UNDEF 271 227 # define PCK_COMMAND 272 228 # define PCV_FILENAME 273 229 # define PCV_SYMBOL 274 230 # define PCV_VAL_INT 275 231 # define PCV_VAL_UINT 276 232 # define PCV_VAL_FLOAT 277 233 # define PCV_VAL_STRING 278 234 # define PCV_VAL_BOOLEAN 279 235 # define PCT_INT 280 236 # define PCT_UINT 281 237 # define PCT_BOOLEAN 282 238 # define PCT_FLOAT 283 239 # define PCT_STRING 284 240 # define PCE_SYSTEM 285 241 # define PCE_POOL 286 242 # define PCE_PSET 287 243 # define PCE_CPU 288 244 245 #include <inttypes.h> 246 247 #ifdef __STDC__ 248 #include <stdlib.h> 249 #include <string.h> 250 #define YYCONST const 251 #else 252 #include <malloc.h> 253 #include <memory.h> 254 #define YYCONST 255 #endif 256 257 #include <values.h> 258 259 #if defined(__cplusplus) || defined(__STDC__) 260 261 #if defined(__cplusplus) && defined(__EXTERN_C__) 262 extern "C" { 263 #endif 264 #ifndef yyerror 265 #if defined(__cplusplus) 266 void yyerror(YYCONST char *); 267 #endif 268 #endif 269 #ifndef yylex 270 int yylex(void); 271 #endif 272 int yyparse(void); 273 #if defined(__cplusplus) && defined(__EXTERN_C__) 274 } 275 #endif 276 277 #endif 278 279 #define yyclearin yychar = -1 280 #define yyerrok yyerrflag = 0 281 extern int yychar; 282 extern int yyerrflag; 283 YYSTYPE yylval; 284 YYSTYPE yyval; 285 typedef int yytabelem; 286 #ifndef YYMAXDEPTH 287 #define YYMAXDEPTH 150 288 #endif 289 #if YYMAXDEPTH > 0 290 int yy_yys[YYMAXDEPTH], *yys = yy_yys; 291 YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; 292 #else /* user does initial allocation */ 293 int *yys; 294 YYSTYPE *yyv; 295 #endif 296 static int yymaxdepth = YYMAXDEPTH; 297 # define YYERRCODE 256 298 299 # line 653 "poolcfg.y" 300 301 302 #ifndef TEXT_DOMAIN 303 #define TEXT_DOMAIN "SYS_TEST" 304 #endif 305 306 int 307 main(int argc, char *argv[]) 308 { 309 int opt; 310 int docmd = PO_FALSE; 311 312 (void) getpname(argv[0]); 313 (void) setlocale(LC_ALL, ""); 314 (void) textdomain(TEXT_DOMAIN); 315 if (atexit(terminate) != 0) { 316 die(gettext(ERR_SET_TERM), get_errstr()); 317 } 318 319 conf_file = pool_static_location(); 320 321 yydebug = 0; 322 while ((opt = getopt(argc, argv, cmd_options)) != (int)EOF) { 323 324 switch (opt) { 325 case 'c': /* Process command line */ 326 if (dofile == PO_TRUE) 327 usage(1); 328 arg_parse(optarg); 329 docmd = PO_TRUE; 330 break; 331 case 'd': /* Manipulate dynamic configuration */ 332 conf_file = pool_dynamic_location(); 333 break; 334 case 'f': /* Process command file */ 335 if (docmd == PO_TRUE) 336 usage(1); 337 file_parse(optarg); 338 dofile = PO_TRUE; 339 break; 340 case 'h': 341 usage(2); 342 break; 343 case '?': 344 default: 345 usage(1); 346 break; 347 } 348 } 349 if (docmd == PO_FALSE && dofile == PO_FALSE) 350 usage(1); 351 352 if (optind == argc - 1) { 353 if (strcmp(conf_file, pool_dynamic_location()) == 0) 354 usage(1); 355 conf_file = argv[optind]; 356 } else if (optind < argc - 1) 357 usage(1); 358 359 if ((conf = pool_conf_alloc()) == NULL) { 360 die(gettext(ERR_ALLOC_ELEMENT), gettext(CONFIGURATION), 361 get_errstr()); 362 } 363 /* 364 * Opening a conf is complex, since we may be opening one of the 365 * following: 366 * - An existing configuration that we can modify 367 * - An existing configuration that we can't modify 368 * - A new configuration that we can modify 369 * - A new configuration that we can't modify 370 * The parser_conf_discover() function closes the file and reopens 371 * in PO_CREAT mode, so we only need be concerned here with the 372 * first two cases. 373 * Always try to open RDWR, if fail try RDONLY. Don't check 374 * if that fails, since we may be trying to discover a configuration 375 * in which case it's valid for both open attempts to fail. Later, when 376 * processing commands, if we don't have a valid configuration and 377 * we are trying to process a command which isn't a create or a discover 378 * we will fail the command as there is no valid configuration to 379 * work with. 380 */ 381 if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) { 382 conf_edit_error = pool_error(); 383 conf_edit_errno = errno; 384 if (pool_conf_open(conf, conf_file, PO_RDONLY) != 0) { 385 conf_list_error = pool_error(); 386 conf_list_errno = errno; 387 } 388 } 389 390 if (yyparse() == 0) { 391 if (pool_conf_status(conf) >= POF_VALID) { 392 if (pool_conf_validate(conf, POV_STRICT) == PO_FAIL) { 393 die(gettext(ERR_VALIDATION_FAILED), 394 get_errstr()); 395 } 396 /* 397 * If the user attempted to change the configuration, 398 * then we should try to save the changes. 399 */ 400 if (edited == PO_TRUE) { 401 if (pool_conf_commit(conf, 0) == PO_FAIL) { 402 die(gettext(ERR_CONFIG_SAVE_FAILED), 403 get_errstr()); 404 } 405 } 406 pool_conf_close(conf); 407 } 408 } else { 409 die(gettext(ERR_CMDPARSE_FAILED)); 410 } 411 412 /* 413 * Cleanup is performed in terminate(), using atexit 414 */ 415 return (0); 416 } 417 418 /* 419 * Info Commands 420 * Invoke the appropriate libpool info function and display the returned 421 * information. 422 */ 423 static void 424 parser_conf_info(cmd_t *cmd) 425 { 426 char *info_buf; 427 const char *tgt = cmd->cmd_tgt1; 428 pool_value_t *pv = NULL; 429 pool_elem_t *pe; 430 431 if ((pe = pool_conf_to_elem(conf)) == NULL) 432 die(gettext(ERR_GET_ELEMENT_DETAILS), 433 gettext(CONFIGURATION), "unknown", get_errstr()); 434 435 if (tgt != NULL) 436 check_conf_name(cmd); 437 else { 438 if ((pv = pool_value_alloc()) == NULL) 439 die(gettext(ERR_GET_ELEMENT_DETAILS), 440 gettext(CONFIGURATION), "unknown", get_errstr()); 441 if (pool_get_property(conf, pe, "system.name", pv) == 442 POC_INVAL || 443 pool_value_get_string(pv, &tgt) != PO_SUCCESS) 444 die(gettext(ERR_GET_ELEMENT_DETAILS), 445 gettext(CONFIGURATION), "unknown", get_errstr()); 446 } 447 if ((info_buf = pool_conf_info(conf, PO_TRUE)) == NULL) { 448 die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION), 449 tgt, get_errstr()); 450 } 451 if (pv != NULL) { 452 pool_value_free(pv); 453 } 454 (void) printf("%s\n", info_buf); 455 free(info_buf); 456 } 457 458 static void 459 parser_pool_info(cmd_t *cmd) 460 { 461 pool_t *pool; 462 char *info_buf; 463 464 if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL) 465 die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 466 get_errstr()); 467 468 if ((info_buf = pool_info(conf, pool, PO_TRUE)) == NULL) 469 die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(POOL), 470 cmd->cmd_tgt1, get_errstr()); 471 (void) printf("%s\n", info_buf); 472 free(info_buf); 473 } 474 475 static void 476 parser_resource_info(cmd_t *cmd, const char *type) 477 { 478 pool_resource_t *resource; 479 char *info_buf; 480 481 if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL) 482 die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE), 483 cmd->cmd_tgt1, get_errstr()); 484 485 if ((info_buf = pool_resource_info(conf, resource, PO_TRUE)) == NULL) 486 die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(RESOURCE), 487 cmd->cmd_tgt1, get_errstr()); 488 (void) printf("%s\n", info_buf); 489 free(info_buf); 490 } 491 492 static void 493 parser_pset_info(cmd_t *cmd) 494 { 495 parser_resource_info(cmd, PSET); 496 } 497 498 static void 499 parser_cpu_info(cmd_t *cmd) 500 { 501 pool_component_t *comp; 502 char *info_buf; 503 504 if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL) 505 die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU), 506 cmd->cmd_tgt1, get_errstr()); 507 if ((info_buf = pool_component_info(conf, comp, PO_TRUE)) == NULL) { 508 die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CPU), 509 cmd->cmd_tgt1, get_errstr()); 510 } 511 (void) printf("%s\n", info_buf); 512 free(info_buf); 513 } 514 515 /* 516 * Create Commands 517 * Invoke the appropriate libpool create function and perform any requested 518 * property operations. 519 */ 520 static void 521 parser_conf_create(cmd_t *cmd) 522 { 523 const char *tmp_name; 524 pool_elem_t *pe; 525 526 if (conf != NULL && pool_conf_status(conf) >= POF_VALID) 527 pool_conf_close(conf); 528 if (pool_conf_open(conf, conf_file, PO_CREAT) != 0) { 529 die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION), 530 cmd->cmd_tgt1, get_errstr()); 531 } 532 tmp_name = cmd->cmd_tgt1; 533 cmd->cmd_tgt1 = cmd->cmd_tgt2; 534 cmd->cmd_tgt2 = tmp_name; 535 parser_conf_rename(cmd); 536 if ((pe = pool_conf_to_elem(conf)) == NULL) 537 die(gettext(ERR_GET_ELEMENT_DETAILS), 538 gettext(CONFIGURATION), "unknown", get_errstr()); 539 prop_list_walk(cmd, pe); 540 } 541 542 static void 543 parser_pool_create(cmd_t *cmd) 544 { 545 pool_t *pool; 546 547 if ((pool = pool_create(conf, cmd->cmd_tgt1)) == NULL) 548 die(gettext(ERR_CREATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 549 get_errstr()); 550 prop_list_walk(cmd, pool_to_elem(conf, pool)); 551 } 552 553 static void 554 parser_resource_create(cmd_t *cmd, const char *type) 555 { 556 pool_resource_t *resource; 557 558 if ((resource = pool_resource_create(conf, type, cmd->cmd_tgt1)) 559 == NULL) 560 die(gettext(ERR_CREATE_ELEMENT), type, cmd->cmd_tgt1, 561 get_errstr()); 562 563 process_min_max(resource); 564 565 prop_list_walk(cmd, pool_resource_to_elem(conf, resource)); 566 } 567 568 static void 569 parser_pset_create(cmd_t *cmd) 570 { 571 parser_resource_create(cmd, PSET); 572 } 573 574 /* 575 * Rename Commands 576 * Rename the target by calling pool_put_property for the name property. 577 */ 578 static void 579 parser_rename(cmd_t *cmd, pool_elem_t *pe, const char *name) 580 { 581 pool_value_t *pv; 582 583 if ((pv = pool_value_alloc()) == NULL) { 584 die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE), 585 get_errstr()); 586 } 587 pool_value_set_string(pv, cmd->cmd_tgt2); 588 if (pool_put_property(conf, pe, name, pv) != 0) 589 die(gettext(ERR_PUT_PROPERTY), name, get_errstr()); 590 pool_value_free(pv); 591 } 592 593 static void 594 parser_conf_rename(cmd_t *cmd) 595 { 596 pool_elem_t *pe; 597 598 if ((pe = pool_conf_to_elem(conf)) == NULL) 599 die(gettext(ERR_GET_ELEMENT_DETAILS), 600 gettext(CONFIGURATION), "unknown", get_errstr()); 601 602 if (cmd->cmd_tgt1 != NULL) 603 check_conf_name(cmd); 604 605 parser_rename(cmd, pe, SYSTEM_NAME); 606 } 607 608 static void 609 parser_pool_rename(cmd_t *cmd) 610 { 611 pool_t *pool; 612 613 if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL) 614 die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 615 get_errstr()); 616 617 parser_rename(cmd, pool_to_elem(conf, pool), POOL_NAME); 618 } 619 620 static void 621 parser_pset_rename(cmd_t *cmd) 622 { 623 pool_resource_t *resource; 624 625 if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL) 626 die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET), cmd->cmd_tgt1, 627 get_errstr()); 628 629 parser_rename(cmd, pool_resource_to_elem(conf, resource), PSET_NAME); 630 } 631 632 /* 633 * Destroy Commands 634 * Invoke the appropriate libpool destroy function to remove the target of the 635 * command from the configuration. 636 */ 637 static void 638 parser_conf_destroy(cmd_t *cmd) 639 { 640 if (cmd->cmd_tgt1 != NULL) 641 check_conf_name(cmd); 642 643 if (pool_conf_remove(conf) != 0) 644 die(gettext(ERR_DESTROY_ELEMENT), gettext(CONFIGURATION), 645 cmd->cmd_tgt1, get_errstr()); 646 } 647 648 static void 649 parser_pool_destroy(cmd_t *cmd) 650 { 651 pool_t *pool; 652 653 if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL) 654 die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 655 get_errstr()); 656 657 if (pool_destroy(conf, pool) != 0) 658 die(gettext(ERR_DESTROY_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 659 get_errstr()); 660 } 661 662 static void 663 parser_resource_destroy(cmd_t *cmd, const char *type) 664 { 665 pool_resource_t *resource; 666 667 if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL) 668 die(gettext(ERR_LOCATE_ELEMENT), type, cmd->cmd_tgt1, 669 get_errstr()); 670 671 if (pool_resource_destroy(conf, resource) != 0) 672 die(gettext(ERR_DESTROY_ELEMENT), type, cmd->cmd_tgt1, 673 get_errstr()); 674 } 675 676 static void 677 parser_pset_destroy(cmd_t *cmd) 678 { 679 parser_resource_destroy(cmd, PSET); 680 } 681 682 /* 683 * Modify Commands 684 * Perform any requested property operations. 685 */ 686 static void 687 parser_conf_modify(cmd_t *cmd) 688 { 689 pool_elem_t *pe; 690 691 if ((pe = pool_conf_to_elem(conf)) == NULL) 692 die(gettext(ERR_GET_ELEMENT_DETAILS), 693 gettext(CONFIGURATION), "unknown", get_errstr()); 694 695 if (cmd->cmd_tgt1 != NULL) 696 check_conf_name(cmd); 697 698 prop_list_walk(cmd, pe); 699 } 700 701 static void 702 parser_pool_modify(cmd_t *cmd) 703 { 704 pool_t *pool; 705 706 if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL) 707 die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 708 get_errstr()); 709 prop_list_walk(cmd, pool_to_elem(conf, pool)); 710 } 711 712 static void 713 parser_resource_modify(cmd_t *cmd, const char *type) 714 { 715 pool_resource_t *resource; 716 717 if ((resource = pool_get_resource(conf, type, cmd->cmd_tgt1)) == NULL) 718 die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE), 719 cmd->cmd_tgt1, get_errstr()); 720 721 process_min_max(resource); 722 723 prop_list_walk(cmd, pool_resource_to_elem(conf, resource)); 724 } 725 726 static void 727 parser_pset_modify(cmd_t *cmd) 728 { 729 parser_resource_modify(cmd, PSET); 730 } 731 732 static void 733 parser_cpu_modify(cmd_t *cmd) 734 { 735 pool_component_t *comp; 736 737 if ((comp = get_cpu(cmd->cmd_tgt1)) == NULL) 738 die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU), 739 cmd->cmd_tgt1, get_errstr()); 740 prop_list_walk(cmd, pool_component_to_elem(conf, comp)); 741 } 742 743 /* 744 * Discover Commands 745 * Invoke the libpool pool_conf_open function so that discovery will be 746 * performed. 747 */ 748 749 /*ARGSUSED*/ 750 static void 751 parser_conf_discover(cmd_t *cmd) 752 { 753 struct utsname utsname; 754 755 if (strcmp(conf_file, pool_dynamic_location()) == 0) 756 return; 757 758 if (uname(&utsname) < 0) 759 die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION), 760 "unknown", get_errstr()); 761 762 if (conf != NULL && pool_conf_status(conf) >= POF_VALID) 763 pool_conf_close(conf); 764 if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != 0) { 765 die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION), 766 utsname.nodename, get_errstr()); 767 } 768 if (pool_conf_export(conf, conf_file, POX_NATIVE) != 0) { 769 die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION), 770 utsname.nodename, get_errstr()); 771 } 772 (void) pool_conf_close(conf); 773 if (pool_conf_open(conf, conf_file, PO_RDWR) != 0) { 774 die(gettext(ERR_CREATE_ELEMENT), gettext(CONFIGURATION), 775 utsname.nodename, get_errstr()); 776 } 777 } 778 779 /* 780 * Associate Commands 781 * Walk the list of specified associations so that the target pool will be 782 * associated with the required resources. 783 */ 784 785 static void 786 parser_pool_associate(cmd_t *cmd) 787 { 788 pool_t *pool; 789 790 if ((pool = pool_get_pool(conf, cmd->cmd_tgt1)) == NULL) 791 die(gettext(ERR_LOCATE_ELEMENT), gettext(POOL), cmd->cmd_tgt1, 792 get_errstr()); 793 assoc_list_walk(cmd, pool); 794 } 795 796 /* 797 * Assign Commands 798 * Walk the list of specified assignations so that the required 799 * components will be assigned to the target resource. 800 */ 801 802 static void 803 parser_resource_xtransfer(cmd_t *cmd) 804 { 805 pool_resource_t *resource; 806 807 if ((resource = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL) 808 die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE), 809 cmd->cmd_tgt1, get_errstr()); 810 transfer_list_walk(cmd, resource); 811 } 812 813 /* 814 * Transfer Commands 815 * Transfer the specified quantity of resource between the src and the tgt. 816 */ 817 818 static void 819 parser_resource_transfer(cmd_t *cmd) 820 { 821 pool_resource_t *src; 822 pool_resource_t *tgt; 823 824 if ((src = pool_get_resource(conf, PSET, cmd->cmd_tgt1)) == NULL) 825 die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE), 826 cmd->cmd_tgt1, get_errstr()); 827 if ((tgt = pool_get_resource(conf, PSET, cmd->cmd_tgt2)) == NULL) 828 die(gettext(ERR_LOCATE_ELEMENT), gettext(RESOURCE), 829 cmd->cmd_tgt2, get_errstr()); 830 if (pool_resource_transfer(conf, src, tgt, cmd->cmd_qty) != PO_SUCCESS) 831 die(gettext(ERR_XFER_QUANTITY), cmd->cmd_qty, 832 cmd->cmd_tgt1, cmd->cmd_tgt2, get_errstr()); 833 } 834 835 /* 836 * arg_parse() puts the parser into command parsing mode. Create a tmpfile 837 * and instruct the parser to read instructions from this location by setting 838 * yyin to the value returned by tmpfile. Write the command into the file. 839 * Then seek back to to the start of the file so that the parser can read 840 * the instructions. 841 */ 842 static void 843 arg_parse(const char *command) 844 { 845 if ((yyin = tmpfile()) == NULL) 846 die(gettext(ERR_CMD_FILE_INIT), strerror(errno)); 847 if (fwrite(command, strlen(command), 1, yyin) != 1) 848 die(gettext(ERR_CMD_FILE_INIT), strerror(errno)); 849 if (fseek(yyin, 0, SEEK_SET) != 0) 850 die(gettext(ERR_CMD_FILE_INIT), strerror(errno)); 851 } 852 853 /* 854 * file_parse() puts the parser into command file parsing mode. Firstly check 855 * to see if the user wishes to parse from standard input, if so do nothing. 856 * Attempt to open the specified file and instruct the parser to read 857 * instructions from this location by setting yyin to the value returned by 858 * fopen. 859 */ 860 static void 861 file_parse(const char *file) 862 { 863 if (strcmp(file, "-") == 0) 864 return; 865 866 if ((yyin = fopen(file, "r")) == NULL) { 867 die(gettext(ERR_CMD_FILE_INIT), strerror(errno)); 868 } 869 } 870 871 /* 872 * free_cmd() releases the resources associated with the supplied cmd parameter. 873 */ 874 static void 875 free_cmd(cmd_t *cmd) 876 { 877 prop_t *prop = cmd->cmd_prop_list; 878 assoc_t *assoc = cmd->cmd_assoc_list; 879 880 free((void *)cmd->cmd_tgt1); 881 free((void *)cmd->cmd_tgt2); 882 while (prop != NULL) { 883 prop_t *tmp = prop; 884 prop = prop->prop_next; 885 pool_value_free(tmp->prop_value); 886 free((void *)tmp->prop_name); 887 free(tmp); 888 } 889 while (assoc != NULL) { 890 assoc_t *tmp = assoc; 891 assoc = assoc->assoc_next; 892 free((void *)tmp->assoc_name); 893 free(tmp); 894 } 895 free(cmd); 896 } 897 898 /* 899 * alloc_cmd() allocates the required resources for a cmd_t. On failure, a 900 * warning is issued and NULL is returned. 901 */ 902 static cmd_t * 903 alloc_cmd(void) 904 { 905 cmd_t *cmd; 906 907 if ((cmd = malloc(sizeof (cmd_t))) == NULL) { 908 warn(gettext(ERR_CMD_LINE_ALLOC)); 909 return (NULL); 910 } 911 912 (void) memset(cmd, 0, sizeof (cmd_t)); 913 914 return (cmd); 915 } 916 917 /* 918 * alloc_prop() allocates the required resources for a prop_t. On failure, a 919 * warning is issued and NULL is returned. The prop_t is initialised with 920 * the prop_op_t parameter. 921 */ 922 static prop_t * 923 alloc_prop(prop_op_t op) 924 { 925 prop_t *prop; 926 927 if ((prop = malloc(sizeof (prop_t))) == NULL) { 928 warn(gettext(ERR_PROP_ALLOC)); 929 return (NULL); 930 } 931 932 (void) memset(prop, 0, sizeof (prop_t)); 933 if ((prop->prop_value = pool_value_alloc()) == NULL) { 934 warn(gettext(ERR_PROP_ALLOC)); 935 free(prop); 936 return (NULL); 937 } 938 prop->prop_op = op; 939 return (prop); 940 } 941 942 /* 943 * alloc_assoc() allocates the required resources for an assoc_t. On failure, a 944 * warning is issued and NULL is returned. The assoc_t is initialised with 945 * the type and name of the association. 946 */ 947 static assoc_t * 948 alloc_assoc(int type, const char *name) 949 { 950 assoc_t *assoc; 951 952 if ((assoc = malloc(sizeof (assoc_t))) == NULL) { 953 warn(gettext(ERR_ASSOC_ALLOC)); 954 return (NULL); 955 } 956 (void) memset(assoc, 0, sizeof (assoc_t)); 957 assoc->assoc_type = type; 958 assoc->assoc_name = name; 959 return (assoc); 960 } 961 962 /* 963 * check_conf_name() ensures the the name of the system in the configuration 964 * which is being manipulated matches the name of the system in the command. 965 * If not, the command is terminated with an appropriate error message. 966 */ 967 static void 968 check_conf_name(cmd_t *cmd) 969 { 970 pool_value_t *pv; 971 const char *name; 972 pool_elem_t *pe; 973 974 if ((pe = pool_conf_to_elem(conf)) == NULL) 975 die(gettext(ERR_GET_ELEMENT_DETAILS), 976 gettext(CONFIGURATION), "unknown", get_errstr()); 977 978 979 if ((pv = pool_value_alloc()) == NULL) { 980 die(gettext(ERR_ALLOC_ELEMENT), gettext(RESOURCE), 981 get_errstr()); 982 } 983 984 if (pool_get_property(conf, pe, SYSTEM_NAME, pv) 985 == POC_INVAL) 986 die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME), 987 get_errstr()); 988 989 if (pool_value_get_string(pv, &name) == PO_FAIL) 990 die(gettext(ERR_GET_PROPERTY), gettext(SYSTEM_NAME), 991 get_errstr()); 992 993 if (strcmp(cmd->cmd_tgt1, name) != 0) { 994 die(gettext(ERR_WRONG_SYSTEM_NAME), cmd->cmd_tgt1); 995 } 996 pool_value_free(pv); 997 } 998 999 /* 1000 * usage() display brief or verbose help for the poolcfg(1) command. 1001 */ 1002 static void 1003 usage(int help) 1004 { 1005 if (help >= 1) 1006 (void) fprintf(stderr, gettext(USAGE1), cmdname, cmdname, 1007 cmdname); 1008 if (help >= 2) 1009 (void) fprintf(stderr, gettext(USAGE2)); 1010 exit(E_USAGE); 1011 } 1012 1013 /* 1014 * prop_list_walk() walks the property manipulation requests and either puts 1015 * or removes the property as appropriate. 1016 */ 1017 static void 1018 prop_list_walk(cmd_t *cmd, pool_elem_t *pe) 1019 { 1020 prop_t *prop; 1021 1022 for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) { 1023 switch (prop->prop_op) { 1024 case po_create: 1025 if (pool_put_property(conf, pe, prop->prop_name, 1026 prop->prop_value) != 0) 1027 die(gettext(ERR_PUT_PROPERTY), 1028 prop->prop_name, get_errstr()); 1029 break; 1030 case po_remove: 1031 if (pool_rm_property(conf, pe, prop->prop_name) != 0) 1032 die(gettext(ERR_REMOVE_PROPERTY), 1033 prop->prop_name, get_errstr()); 1034 break; 1035 } 1036 } 1037 } 1038 1039 /* 1040 * assoc_list_walk() walks the resource association requests and attempts 1041 * to associate the pool with the specified resource. 1042 */ 1043 static void 1044 assoc_list_walk(cmd_t *cmd, pool_t *pool) 1045 { 1046 assoc_t *assoc; 1047 1048 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 1049 assoc = assoc->assoc_next) { 1050 pool_resource_t *resource; 1051 1052 switch (assoc->assoc_type) { 1053 case PCE_PSET: 1054 if ((resource = pool_get_resource(conf, 1055 PSET, assoc->assoc_name)) == NULL) 1056 die(gettext(ERR_LOCATE_ELEMENT), gettext(PSET), 1057 assoc->assoc_name, get_errstr()); 1058 break; 1059 default: 1060 die(gettext(ERR_UNKNOWN_RESOURCE), 1061 assoc->assoc_type); 1062 break; 1063 } 1064 if (pool_associate(conf, pool, resource) != 0) 1065 die(gettext(ERR_ASSOC_RESOURCE), assoc->assoc_name, 1066 get_errstr()); 1067 } 1068 } 1069 1070 /* 1071 * transfer_list_walk() walks the component assign requests and attempts 1072 * to assign the component with the specified resource. 1073 */ 1074 static void 1075 transfer_list_walk(cmd_t *cmd, pool_resource_t *tgt) 1076 { 1077 assoc_t *assoc; 1078 1079 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 1080 assoc = assoc->assoc_next) { 1081 pool_component_t *comp; 1082 pool_resource_t *src; 1083 pool_component_t *xfer[2] = {NULL}; 1084 1085 if ((comp = get_cpu(assoc->assoc_name)) == NULL) 1086 die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU), 1087 assoc->assoc_name, get_errstr()); 1088 if ((src = pool_get_owning_resource(conf, comp)) == NULL) 1089 die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT), 1090 assoc->assoc_name, cmd->cmd_tgt1, get_errstr()); 1091 xfer[0] = comp; 1092 if (pool_resource_xtransfer(conf, src, tgt, xfer) != 1093 PO_SUCCESS) 1094 die(gettext(ERR_XFER_COMPONENT), gettext(COMPONENT), 1095 assoc->assoc_name, cmd->cmd_tgt1, get_errstr()); 1096 } 1097 } 1098 1099 /* 1100 * terminate() is invoked when poolcfg exits. It cleans up 1101 * configurations and closes the parser input stream. 1102 */ 1103 static void 1104 terminate(void) 1105 { 1106 if (conf != NULL) { 1107 (void) pool_conf_close(conf); 1108 pool_conf_free(conf); 1109 } 1110 if (yyin != stdin) 1111 (void) fclose(yyin); 1112 } 1113 1114 /* 1115 * get_cpu() takes the name of a CPU components and attempts to locate 1116 * the element with that name. If the name is not formatted correctly 1117 * (i.e. contains non-numeric characters) then the function terminates 1118 * execution. If the components cannot be uniquely identified by the 1119 * name, then NULL is returned. 1120 */ 1121 static pool_component_t * 1122 get_cpu(const char *name) 1123 { 1124 pool_component_t **components; 1125 uint_t nelem; 1126 int64_t sysid; 1127 pool_value_t *vals[3] = {NULL}; 1128 pool_component_t *ret; 1129 const char *c; 1130 1131 if ((vals[0] = pool_value_alloc()) == NULL) 1132 return (NULL); 1133 if ((vals[1] = pool_value_alloc()) == NULL) { 1134 pool_value_free(vals[0]); 1135 return (NULL); 1136 } 1137 if (pool_value_set_string(vals[0], "cpu") != PO_SUCCESS || 1138 pool_value_set_name(vals[0], "type") != PO_SUCCESS) { 1139 pool_value_free(vals[0]); 1140 pool_value_free(vals[1]); 1141 return (NULL); 1142 } 1143 1144 for (c = name; *c != NULL; c++) { 1145 if (!isdigit(*c)){ 1146 pool_value_free(vals[0]); 1147 pool_value_free(vals[1]); 1148 die(gettext(ERR_LOCATE_ELEMENT), gettext(CPU), 1149 cmd->cmd_tgt1, gettext("CPU id should only contain " 1150 "digits")); 1151 } 1152 } 1153 sysid = strtoll(name, NULL, 0); 1154 if (errno == ERANGE || errno == EINVAL) { 1155 pool_value_free(vals[0]); 1156 pool_value_free(vals[1]); 1157 return (NULL); 1158 } 1159 pool_value_set_int64(vals[1], sysid); 1160 if (pool_value_set_name(vals[1], CPU_SYSID) != PO_SUCCESS) { 1161 pool_value_free(vals[0]); 1162 pool_value_free(vals[1]); 1163 return (NULL); 1164 } 1165 if ((components = pool_query_components(conf, &nelem, vals)) == 1166 NULL) { 1167 pool_value_free(vals[0]); 1168 pool_value_free(vals[1]); 1169 return (NULL); 1170 } 1171 if (nelem != 1) { 1172 free(components); 1173 pool_value_free(vals[0]); 1174 pool_value_free(vals[1]); 1175 return (NULL); 1176 } 1177 pool_value_free(vals[0]); 1178 pool_value_free(vals[1]); 1179 ret = components[0]; 1180 free(components); 1181 return (ret); 1182 } 1183 1184 /* 1185 * process_min_max() ensures that "min" and "max" properties are 1186 * processed correctly by poolcfg. libpool enforces validity 1187 * constraints on these properties and so it's important that changes 1188 * to them are supplied to the library in the correct order. 1189 */ 1190 void 1191 process_min_max(pool_resource_t *resource) 1192 { 1193 prop_t *minprop = NULL; 1194 prop_t *maxprop = NULL; 1195 prop_t *prop; 1196 1197 /* 1198 * Before walking the list of properties, it has to be checked 1199 * to ensure there are no clashes between min and max. If 1200 * there are, then process these properties immediately. 1201 */ 1202 for (prop = cmd->cmd_prop_list; prop != NULL; prop = prop->prop_next) { 1203 const char *pos; 1204 1205 if ((pos = strstr(prop->prop_name, min_suffix)) != NULL) 1206 if (pos == prop->prop_name + strlen(prop->prop_name) 1207 - 4) 1208 minprop = prop; 1209 if ((pos = strstr(prop->prop_name, max_suffix)) != NULL) 1210 if (pos == prop->prop_name + strlen(prop->prop_name) 1211 - 4) 1212 maxprop = prop; 1213 } 1214 if (minprop && maxprop) { 1215 pool_value_t *pv; 1216 uint64_t smin, smax, dmax; 1217 const char *type; 1218 char *prop_name; 1219 pool_elem_t *pe = pool_resource_to_elem(conf, resource); 1220 1221 if ((pv = pool_value_alloc()) == NULL) 1222 die(gettext(ERR_NOMEM)); 1223 1224 (void) pool_get_property(conf, pe, "type", pv); 1225 (void) pool_value_get_string(pv, &type); 1226 1227 if ((prop_name = malloc(strlen(type) + strlen(max_suffix) 1228 + 1)) == NULL) 1229 die(gettext(ERR_NOMEM)); 1230 1231 (void) sprintf(prop_name, "%s%s", type, max_suffix); 1232 (void) pool_get_property(conf, pe, prop_name, pv); 1233 (void) pool_value_get_uint64(pv, &dmax); 1234 1235 (void) pool_value_get_uint64(minprop->prop_value, &smin); 1236 1237 (void) pool_value_get_uint64(maxprop->prop_value, &smax); 1238 if (smin < dmax) { 1239 (void) pool_put_property(conf, pe, 1240 minprop->prop_name, minprop->prop_value); 1241 } else { 1242 (void) pool_put_property(conf, pe, 1243 maxprop->prop_name, maxprop->prop_value); 1244 } 1245 free((void *)prop_name); 1246 pool_value_free(pv); 1247 } 1248 } 1249 static YYCONST yytabelem yyexca[] ={ 1250 -1, 1, 1251 0, -1, 1252 -2, 0, 1253 -1, 2, 1254 0, 1, 1255 257, 1, 1256 258, 1, 1257 259, 1, 1258 260, 1, 1259 261, 1, 1260 262, 1, 1261 263, 1, 1262 264, 1, 1263 -2, 0, 1264 }; 1265 # define YYNPROD 68 1266 # define YYLAST 172 1267 static YYCONST yytabelem yyact[]={ 1268 1269 33, 34, 35, 40, 33, 34, 35, 32, 52, 33, 1270 34, 35, 41, 71, 61, 89, 88, 53, 54, 55, 1271 56, 57, 53, 54, 55, 56, 57, 73, 101, 102, 1272 103, 105, 104, 45, 97, 99, 63, 43, 91, 84, 1273 83, 81, 80, 46, 13, 15, 16, 17, 18, 14, 1274 21, 22, 77, 76, 74, 75, 24, 29, 26, 106, 1275 86, 107, 96, 62, 98, 69, 59, 48, 51, 31, 1276 25, 2, 70, 23, 60, 100, 42, 68, 28, 58, 1277 27, 47, 49, 50, 20, 36, 37, 39, 19, 11, 1278 12, 44, 6, 10, 9, 8, 7, 4, 5, 3, 1279 64, 65, 66, 38, 30, 67, 1, 0, 72, 0, 1280 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 1281 0, 79, 0, 0, 82, 0, 0, 0, 0, 0, 1282 0, 0, 0, 0, 85, 0, 0, 87, 0, 0, 1283 0, 0, 0, 92, 90, 0, 0, 93, 0, 94, 1284 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1286 109, 108 }; 1287 static YYCONST yytabelem yypact[]={ 1288 1289 -213, -213, -200,-10000000,-10000000,-10000000,-10000000, -209,-10000000, -209, 1290 -210,-10000000,-10000000, -281,-10000000, -276, -276, -285, -274,-10000000, 1291 -230, -276, -233,-10000000,-10000000,-10000000, -263,-10000000,-10000000, -273, 1292 -238,-10000000,-10000000,-10000000,-10000000,-10000000, -238, -238, -238,-10000000, 1293 -10000000, -238,-10000000, -275, -238, -260, -211, -216,-10000000,-10000000, 1294 -10000000, -238, -258,-10000000,-10000000,-10000000,-10000000,-10000000, -227,-10000000, 1295 -238,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000, -229,-10000000, 1296 -238,-10000000, -206, -238, -271, -272, -263,-10000000, -232, -238, 1297 -273,-10000000,-10000000, -275,-10000000,-10000000, -238,-10000000, -240, -239, 1298 -10000000, -247,-10000000,-10000000,-10000000,-10000000, -207,-10000000, -204,-10000000, 1299 -10000000,-10000000,-10000000,-10000000,-10000000,-10000000, -239, -240,-10000000,-10000000 }; 1300 static YYCONST yytabelem yypgo[]={ 1301 1302 0, 106, 69, 68, 104, 103, 63, 62, 64, 71, 1303 99, 98, 97, 96, 95, 94, 93, 92, 90, 89, 1304 88, 84, 83, 82, 67, 81, 70, 66, 79, 78, 1305 65, 77, 76, 75, 74, 72 }; 1306 static YYCONST yytabelem yyr1[]={ 1307 1308 0, 1, 1, 1, 9, 9, 10, 10, 12, 12, 1309 12, 12, 12, 12, 11, 11, 13, 13, 14, 15, 1310 15, 16, 16, 19, 19, 21, 21, 20, 20, 17, 1311 18, 5, 5, 4, 4, 2, 2, 2, 6, 7, 1312 8, 33, 33, 33, 33, 33, 22, 24, 24, 25, 1313 25, 23, 26, 28, 28, 27, 34, 29, 31, 31, 1314 32, 30, 35, 3, 3, 3, 3, 3 }; 1315 static YYCONST yytabelem yyr2[]={ 1316 1317 0, 3, 5, 5, 2, 3, 3, 3, 2, 2, 1318 2, 2, 2, 2, 3, 7, 7, 4, 7, 7, 1319 4, 7, 4, 2, 2, 9, 4, 15, 15, 3, 1320 11, 2, 3, 2, 3, 3, 3, 3, 2, 2, 1321 2, 3, 3, 3, 3, 3, 7, 2, 2, 3, 1322 7, 9, 7, 3, 7, 5, 3, 7, 3, 7, 1323 7, 5, 3, 3, 3, 3, 3, 3 }; 1324 static YYCONST yytabelem yychk[]={ 1325 1326 -10000000, -1, -9, -10, -12, -11, -17, -13, -14, -15, 1327 -16, -19, -18, 257, 262, 258, 259, 260, 261, -20, 1328 -21, 263, 264, -9, 256, -26, 267, -26, -29, 267, 1329 -4, -2, 288, 285, 286, 287, -2, -2, -5, -2, 1330 288, 286, -32, 267, -2, 266, 276, -25, -24, -23, 1331 -22, -3, 271, 280, 281, 282, 283, 284, -28, -27, 1332 -34, 287, -6, 274, -6, -6, -6, -6, -31, -30, 1333 -35, 288, -6, 287, 265, 266, 269, 268, -6, -3, 1334 269, 268, -6, 269, 268, -6, 266, -6, 287, 287, 1335 -24, 270, -6, -27, -30, -6, -7, 274, -8, 274, 1336 -33, 275, 276, 277, 279, 278, 266, 265, -8, -7 }; 1337 static YYCONST yytabelem yydef[]={ 1338 1339 0, -2, -2, 4, 5, 6, 7, 8, 9, 10, 1340 11, 12, 13, 14, 29, 0, 0, 0, 0, 23, 1341 24, 0, 0, 2, 3, 17, 0, 20, 22, 0, 1342 0, 33, 34, 35, 36, 37, 0, 0, 0, 31, 1343 32, 0, 26, 0, 0, 0, 0, 0, 49, 47, 1344 48, 0, 0, 63, 64, 65, 66, 67, 0, 53, 1345 0, 56, 15, 38, 16, 18, 19, 21, 0, 58, 1346 0, 62, 0, 0, 0, 0, 0, 52, 0, 0, 1347 0, 57, 55, 0, 60, 61, 0, 25, 0, 0, 1348 50, 0, 46, 54, 59, 30, 0, 39, 0, 40, 1349 51, 41, 42, 43, 44, 45, 0, 0, 27, 28 }; 1350 typedef struct 1351 #ifdef __cplusplus 1352 yytoktype 1353 #endif 1354 { 1355 #ifdef __cplusplus 1356 const 1357 #endif 1358 char *t_name; int t_val; } yytoktype; 1359 #ifndef YYDEBUG 1360 # define YYDEBUG 0 /* don't allow debugging */ 1361 #endif 1362 1363 #if YYDEBUG 1364 1365 yytoktype yytoks[] = 1366 { 1367 "PCC_INFO", 257, 1368 "PCC_CREATE", 258, 1369 "PCC_DESTROY", 259, 1370 "PCC_MODIFY", 260, 1371 "PCC_ASSOC", 261, 1372 "PCC_DISC", 262, 1373 "PCC_RENAME", 263, 1374 "PCC_TRANSFER", 264, 1375 "PCK_FROM", 265, 1376 "PCK_TO", 266, 1377 "PCK_OPENLST", 267, 1378 "PCK_CLOSELST", 268, 1379 "PCK_SEPLST", 269, 1380 "PCK_ASSIGN", 270, 1381 "PCK_UNDEF", 271, 1382 "PCK_COMMAND", 272, 1383 "PCV_FILENAME", 273, 1384 "PCV_SYMBOL", 274, 1385 "PCV_VAL_INT", 275, 1386 "PCV_VAL_UINT", 276, 1387 "PCV_VAL_FLOAT", 277, 1388 "PCV_VAL_STRING", 278, 1389 "PCV_VAL_BOOLEAN", 279, 1390 "PCT_INT", 280, 1391 "PCT_UINT", 281, 1392 "PCT_BOOLEAN", 282, 1393 "PCT_FLOAT", 283, 1394 "PCT_STRING", 284, 1395 "PCE_SYSTEM", 285, 1396 "PCE_POOL", 286, 1397 "PCE_PSET", 287, 1398 "PCE_CPU", 288, 1399 "-unknown-", -1 /* ends search */ 1400 }; 1401 1402 #ifdef __cplusplus 1403 const 1404 #endif 1405 char * yyreds[] = 1406 { 1407 "-no such reduction-", 1408 "commands : command", 1409 "commands : commands command", 1410 "commands : command error", 1411 "command : list_command", 1412 "command : edit_command", 1413 "list_command : info_command", 1414 "list_command : discover_command", 1415 "edit_command : create_command", 1416 "edit_command : destroy_command", 1417 "edit_command : modify_command", 1418 "edit_command : associate_command", 1419 "edit_command : transfer_command", 1420 "edit_command : rename_command", 1421 "info_command : PCC_INFO", 1422 "info_command : PCC_INFO info_entity name", 1423 "create_command : PCC_CREATE entity name", 1424 "create_command : create_command property_list", 1425 "destroy_command : PCC_DESTROY entity name", 1426 "modify_command : PCC_MODIFY modify_entity name", 1427 "modify_command : modify_command property_list", 1428 "associate_command : PCC_ASSOC PCE_POOL name", 1429 "associate_command : associate_command resource_list", 1430 "transfer_command : transfer_qty", 1431 "transfer_command : transfer_components", 1432 "transfer_components : PCC_TRANSFER PCK_TO PCE_PSET name", 1433 "transfer_components : transfer_components component_list", 1434 "transfer_qty : PCC_TRANSFER PCV_VAL_UINT PCK_FROM PCE_PSET src PCK_TO tgt", 1435 "transfer_qty : PCC_TRANSFER PCV_VAL_UINT PCK_TO PCE_PSET tgt PCK_FROM src", 1436 "discover_command : PCC_DISC", 1437 "rename_command : PCC_RENAME entity name PCK_TO name", 1438 "modify_entity : entity", 1439 "modify_entity : PCE_CPU", 1440 "info_entity : entity", 1441 "info_entity : PCE_CPU", 1442 "entity : PCE_SYSTEM", 1443 "entity : PCE_POOL", 1444 "entity : PCE_PSET", 1445 "name : PCV_SYMBOL", 1446 "src : PCV_SYMBOL", 1447 "tgt : PCV_SYMBOL", 1448 "value : PCV_VAL_INT", 1449 "value : PCV_VAL_UINT", 1450 "value : PCV_VAL_FLOAT", 1451 "value : PCV_VAL_BOOLEAN", 1452 "value : PCV_VAL_STRING", 1453 "prop_remove : PCK_UNDEF proptype name", 1454 "prop_op : prop_assign", 1455 "prop_op : prop_remove", 1456 "prop_ops : prop_op", 1457 "prop_ops : prop_ops PCK_SEPLST prop_op", 1458 "prop_assign : proptype name PCK_ASSIGN value", 1459 "property_list : PCK_OPENLST prop_ops PCK_CLOSELST", 1460 "resource_assigns : resource_assign", 1461 "resource_assigns : resource_assigns PCK_SEPLST resource_assign", 1462 "resource_assign : resource name", 1463 "resource : PCE_PSET", 1464 "resource_list : PCK_OPENLST resource_assigns PCK_CLOSELST", 1465 "component_assigns : component_assign", 1466 "component_assigns : component_assigns PCK_SEPLST component_assign", 1467 "component_list : PCK_OPENLST component_assigns PCK_CLOSELST", 1468 "component_assign : component name", 1469 "component : PCE_CPU", 1470 "proptype : PCT_INT", 1471 "proptype : PCT_UINT", 1472 "proptype : PCT_BOOLEAN", 1473 "proptype : PCT_FLOAT", 1474 "proptype : PCT_STRING", 1475 }; 1476 #endif /* YYDEBUG */ 1477 # line 1 "/usr/share/lib/ccs/yaccpar" 1478 /* 1479 * CDDL HEADER START 1480 * 1481 * The contents of this file are subject to the terms of the 1482 * Common Development and Distribution License, Version 1.0 only 1483 * (the "License"). You may not use this file except in compliance 1484 * with the License. 1485 * 1486 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1487 * or http://www.opensolaris.org/os/licensing. 1488 * See the License for the specific language governing permissions 1489 * and limitations under the License. 1490 * 1491 * When distributing Covered Code, include this CDDL HEADER in each 1492 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1493 * If applicable, add the following below this CDDL HEADER, with the 1494 * fields enclosed by brackets "[]" replaced with your own identifying 1495 * information: Portions Copyright [yyyy] [name of copyright owner] 1496 * 1497 * CDDL HEADER END 1498 */ 1499 /* 1500 * Copyright 1993 Sun Microsystems, Inc. All rights reserved. 1501 * Use is subject to license terms. 1502 */ 1503 1504 /* Copyright (c) 1988 AT&T */ 1505 /* All Rights Reserved */ 1506 1507 #pragma ident "%Z%%M% %I% %E% SMI" 1508 1509 /* 1510 ** Skeleton parser driver for yacc output 1511 */ 1512 1513 /* 1514 ** yacc user known macros and defines 1515 */ 1516 #define YYERROR goto yyerrlab 1517 #define YYACCEPT return(0) 1518 #define YYABORT return(1) 1519 #define YYBACKUP( newtoken, newvalue )\ 1520 {\ 1521 if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ 1522 {\ 1523 yyerror( "syntax error - cannot backup" );\ 1524 goto yyerrlab;\ 1525 }\ 1526 yychar = newtoken;\ 1527 yystate = *yyps;\ 1528 yylval = newvalue;\ 1529 goto yynewstate;\ 1530 } 1531 #define YYRECOVERING() (!!yyerrflag) 1532 #define YYNEW(type) malloc(sizeof(type) * yynewmax) 1533 #define YYCOPY(to, from, type) \ 1534 (type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type)) 1535 #define YYENLARGE( from, type) \ 1536 (type *) realloc((char *) from, yynewmax * sizeof(type)) 1537 #ifndef YYDEBUG 1538 # define YYDEBUG 1 /* make debugging available */ 1539 #endif 1540 1541 /* 1542 ** user known globals 1543 */ 1544 int yydebug; /* set to 1 to get debugging */ 1545 1546 /* 1547 ** driver internal defines 1548 */ 1549 #define YYFLAG (-10000000) 1550 1551 /* 1552 ** global variables used by the parser 1553 */ 1554 YYSTYPE *yypv; /* top of value stack */ 1555 int *yyps; /* top of state stack */ 1556 1557 int yystate; /* current state */ 1558 int yytmp; /* extra var (lasts between blocks) */ 1559 1560 int yynerrs; /* number of errors */ 1561 int yyerrflag; /* error recovery flag */ 1562 int yychar; /* current input token number */ 1563 1564 1565 1566 #ifdef YYNMBCHARS 1567 #define YYLEX() yycvtok(yylex()) 1568 /* 1569 ** yycvtok - return a token if i is a wchar_t value that exceeds 255. 1570 ** If i<255, i itself is the token. If i>255 but the neither 1571 ** of the 30th or 31st bit is on, i is already a token. 1572 */ 1573 #if defined(__STDC__) || defined(__cplusplus) 1574 int yycvtok(int i) 1575 #else 1576 int yycvtok(i) int i; 1577 #endif 1578 { 1579 int first = 0; 1580 int last = YYNMBCHARS - 1; 1581 int mid; 1582 wchar_t j; 1583 1584 if(i&0x60000000){/*Must convert to a token. */ 1585 if( yymbchars[last].character < i ){ 1586 return i;/*Giving up*/ 1587 } 1588 while ((last>=first)&&(first>=0)) {/*Binary search loop*/ 1589 mid = (first+last)/2; 1590 j = yymbchars[mid].character; 1591 if( j==i ){/*Found*/ 1592 return yymbchars[mid].tvalue; 1593 }else if( j<i ){ 1594 first = mid + 1; 1595 }else{ 1596 last = mid -1; 1597 } 1598 } 1599 /*No entry in the table.*/ 1600 return i;/* Giving up.*/ 1601 }else{/* i is already a token. */ 1602 return i; 1603 } 1604 } 1605 #else/*!YYNMBCHARS*/ 1606 #define YYLEX() yylex() 1607 #endif/*!YYNMBCHARS*/ 1608 1609 /* 1610 ** yyparse - return 0 if worked, 1 if syntax error not recovered from 1611 */ 1612 #if defined(__STDC__) || defined(__cplusplus) 1613 int yyparse(void) 1614 #else 1615 int yyparse() 1616 #endif 1617 { 1618 register YYSTYPE *yypvt = 0; /* top of value stack for $vars */ 1619 1620 #if defined(__cplusplus) || defined(lint) 1621 /* 1622 hacks to please C++ and lint - goto's inside 1623 switch should never be executed 1624 */ 1625 static int __yaccpar_lint_hack__ = 0; 1626 switch (__yaccpar_lint_hack__) 1627 { 1628 case 1: goto yyerrlab; 1629 case 2: goto yynewstate; 1630 } 1631 #endif 1632 1633 /* 1634 ** Initialize externals - yyparse may be called more than once 1635 */ 1636 yypv = &yyv[-1]; 1637 yyps = &yys[-1]; 1638 yystate = 0; 1639 yytmp = 0; 1640 yynerrs = 0; 1641 yyerrflag = 0; 1642 yychar = -1; 1643 1644 #if YYMAXDEPTH <= 0 1645 if (yymaxdepth <= 0) 1646 { 1647 if ((yymaxdepth = YYEXPAND(0)) <= 0) 1648 { 1649 yyerror("yacc initialization error"); 1650 YYABORT; 1651 } 1652 } 1653 #endif 1654 1655 { 1656 register YYSTYPE *yy_pv; /* top of value stack */ 1657 register int *yy_ps; /* top of state stack */ 1658 register int yy_state; /* current state */ 1659 register int yy_n; /* internal state number info */ 1660 goto yystack; /* moved from 6 lines above to here to please C++ */ 1661 1662 /* 1663 ** get globals into registers. 1664 ** branch to here only if YYBACKUP was called. 1665 */ 1666 yynewstate: 1667 yy_pv = yypv; 1668 yy_ps = yyps; 1669 yy_state = yystate; 1670 goto yy_newstate; 1671 1672 /* 1673 ** get globals into registers. 1674 ** either we just started, or we just finished a reduction 1675 */ 1676 yystack: 1677 yy_pv = yypv; 1678 yy_ps = yyps; 1679 yy_state = yystate; 1680 1681 /* 1682 ** top of for (;;) loop while no reductions done 1683 */ 1684 yy_stack: 1685 /* 1686 ** put a state and value onto the stacks 1687 */ 1688 #if YYDEBUG 1689 /* 1690 ** if debugging, look up token value in list of value vs. 1691 ** name pairs. 0 and negative (-1) are special values. 1692 ** Note: linear search is used since time is not a real 1693 ** consideration while debugging. 1694 */ 1695 if ( yydebug ) 1696 { 1697 register int yy_i; 1698 1699 printf( "State %d, token ", yy_state ); 1700 if ( yychar == 0 ) 1701 printf( "end-of-file\n" ); 1702 else if ( yychar < 0 ) 1703 printf( "-none-\n" ); 1704 else 1705 { 1706 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1707 yy_i++ ) 1708 { 1709 if ( yytoks[yy_i].t_val == yychar ) 1710 break; 1711 } 1712 printf( "%s\n", yytoks[yy_i].t_name ); 1713 } 1714 } 1715 #endif /* YYDEBUG */ 1716 if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ 1717 { 1718 /* 1719 ** reallocate and recover. Note that pointers 1720 ** have to be reset, or bad things will happen 1721 */ 1722 long yyps_index = (yy_ps - yys); 1723 long yypv_index = (yy_pv - yyv); 1724 long yypvt_index = (yypvt - yyv); 1725 int yynewmax; 1726 #ifdef YYEXPAND 1727 yynewmax = YYEXPAND(yymaxdepth); 1728 #else 1729 yynewmax = 2 * yymaxdepth; /* double table size */ 1730 if (yymaxdepth == YYMAXDEPTH) /* first time growth */ 1731 { 1732 char *newyys = (char *)YYNEW(int); 1733 char *newyyv = (char *)YYNEW(YYSTYPE); 1734 if (newyys != 0 && newyyv != 0) 1735 { 1736 yys = YYCOPY(newyys, yys, int); 1737 yyv = YYCOPY(newyyv, yyv, YYSTYPE); 1738 } 1739 else 1740 yynewmax = 0; /* failed */ 1741 } 1742 else /* not first time */ 1743 { 1744 yys = YYENLARGE(yys, int); 1745 yyv = YYENLARGE(yyv, YYSTYPE); 1746 if (yys == 0 || yyv == 0) 1747 yynewmax = 0; /* failed */ 1748 } 1749 #endif 1750 if (yynewmax <= yymaxdepth) /* tables not expanded */ 1751 { 1752 yyerror( "yacc stack overflow" ); 1753 YYABORT; 1754 } 1755 yymaxdepth = yynewmax; 1756 1757 yy_ps = yys + yyps_index; 1758 yy_pv = yyv + yypv_index; 1759 yypvt = yyv + yypvt_index; 1760 } 1761 *yy_ps = yy_state; 1762 *++yy_pv = yyval; 1763 1764 /* 1765 ** we have a new state - find out what to do 1766 */ 1767 yy_newstate: 1768 if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) 1769 goto yydefault; /* simple state */ 1770 #if YYDEBUG 1771 /* 1772 ** if debugging, need to mark whether new token grabbed 1773 */ 1774 yytmp = yychar < 0; 1775 #endif 1776 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1777 yychar = 0; /* reached EOF */ 1778 #if YYDEBUG 1779 if ( yydebug && yytmp ) 1780 { 1781 register int yy_i; 1782 1783 printf( "Received token " ); 1784 if ( yychar == 0 ) 1785 printf( "end-of-file\n" ); 1786 else if ( yychar < 0 ) 1787 printf( "-none-\n" ); 1788 else 1789 { 1790 for ( yy_i = 0; yytoks[yy_i].t_val >= 0; 1791 yy_i++ ) 1792 { 1793 if ( yytoks[yy_i].t_val == yychar ) 1794 break; 1795 } 1796 printf( "%s\n", yytoks[yy_i].t_name ); 1797 } 1798 } 1799 #endif /* YYDEBUG */ 1800 if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) 1801 goto yydefault; 1802 if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ 1803 { 1804 yychar = -1; 1805 yyval = yylval; 1806 yy_state = yy_n; 1807 if ( yyerrflag > 0 ) 1808 yyerrflag--; 1809 goto yy_stack; 1810 } 1811 1812 yydefault: 1813 if ( ( yy_n = yydef[ yy_state ] ) == -2 ) 1814 { 1815 #if YYDEBUG 1816 yytmp = yychar < 0; 1817 #endif 1818 if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) ) 1819 yychar = 0; /* reached EOF */ 1820 #if YYDEBUG 1821 if ( yydebug && yytmp ) 1822 { 1823 register int yy_i; 1824 1825 printf( "Received token " ); 1826 if ( yychar == 0 ) 1827 printf( "end-of-file\n" ); 1828 else if ( yychar < 0 ) 1829 printf( "-none-\n" ); 1830 else 1831 { 1832 for ( yy_i = 0; 1833 yytoks[yy_i].t_val >= 0; 1834 yy_i++ ) 1835 { 1836 if ( yytoks[yy_i].t_val 1837 == yychar ) 1838 { 1839 break; 1840 } 1841 } 1842 printf( "%s\n", yytoks[yy_i].t_name ); 1843 } 1844 } 1845 #endif /* YYDEBUG */ 1846 /* 1847 ** look through exception table 1848 */ 1849 { 1850 register YYCONST int *yyxi = yyexca; 1851 1852 while ( ( *yyxi != -1 ) || 1853 ( yyxi[1] != yy_state ) ) 1854 { 1855 yyxi += 2; 1856 } 1857 while ( ( *(yyxi += 2) >= 0 ) && 1858 ( *yyxi != yychar ) ) 1859 ; 1860 if ( ( yy_n = yyxi[1] ) < 0 ) 1861 YYACCEPT; 1862 } 1863 } 1864 1865 /* 1866 ** check for syntax error 1867 */ 1868 if ( yy_n == 0 ) /* have an error */ 1869 { 1870 /* no worry about speed here! */ 1871 switch ( yyerrflag ) 1872 { 1873 case 0: /* new error */ 1874 yyerror( "syntax error" ); 1875 goto skip_init; 1876 yyerrlab: 1877 /* 1878 ** get globals into registers. 1879 ** we have a user generated syntax type error 1880 */ 1881 yy_pv = yypv; 1882 yy_ps = yyps; 1883 yy_state = yystate; 1884 skip_init: 1885 yynerrs++; 1886 /* FALLTHRU */ 1887 case 1: 1888 case 2: /* incompletely recovered error */ 1889 /* try again... */ 1890 yyerrflag = 3; 1891 /* 1892 ** find state where "error" is a legal 1893 ** shift action 1894 */ 1895 while ( yy_ps >= yys ) 1896 { 1897 yy_n = yypact[ *yy_ps ] + YYERRCODE; 1898 if ( yy_n >= 0 && yy_n < YYLAST && 1899 yychk[yyact[yy_n]] == YYERRCODE) { 1900 /* 1901 ** simulate shift of "error" 1902 */ 1903 yy_state = yyact[ yy_n ]; 1904 goto yy_stack; 1905 } 1906 /* 1907 ** current state has no shift on 1908 ** "error", pop stack 1909 */ 1910 #if YYDEBUG 1911 # define _POP_ "Error recovery pops state %d, uncovers state %d\n" 1912 if ( yydebug ) 1913 printf( _POP_, *yy_ps, 1914 yy_ps[-1] ); 1915 # undef _POP_ 1916 #endif 1917 yy_ps--; 1918 yy_pv--; 1919 } 1920 /* 1921 ** there is no state on stack with "error" as 1922 ** a valid shift. give up. 1923 */ 1924 YYABORT; 1925 case 3: /* no shift yet; eat a token */ 1926 #if YYDEBUG 1927 /* 1928 ** if debugging, look up token in list of 1929 ** pairs. 0 and negative shouldn't occur, 1930 ** but since timing doesn't matter when 1931 ** debugging, it doesn't hurt to leave the 1932 ** tests here. 1933 */ 1934 if ( yydebug ) 1935 { 1936 register int yy_i; 1937 1938 printf( "Error recovery discards " ); 1939 if ( yychar == 0 ) 1940 printf( "token end-of-file\n" ); 1941 else if ( yychar < 0 ) 1942 printf( "token -none-\n" ); 1943 else 1944 { 1945 for ( yy_i = 0; 1946 yytoks[yy_i].t_val >= 0; 1947 yy_i++ ) 1948 { 1949 if ( yytoks[yy_i].t_val 1950 == yychar ) 1951 { 1952 break; 1953 } 1954 } 1955 printf( "token %s\n", 1956 yytoks[yy_i].t_name ); 1957 } 1958 } 1959 #endif /* YYDEBUG */ 1960 if ( yychar == 0 ) /* reached EOF. quit */ 1961 YYABORT; 1962 yychar = -1; 1963 goto yy_newstate; 1964 } 1965 }/* end if ( yy_n == 0 ) */ 1966 /* 1967 ** reduction by production yy_n 1968 ** put stack tops, etc. so things right after switch 1969 */ 1970 #if YYDEBUG 1971 /* 1972 ** if debugging, print the string that is the user's 1973 ** specification of the reduction which is just about 1974 ** to be done. 1975 */ 1976 if ( yydebug ) 1977 printf( "Reduce by (%d) \"%s\"\n", 1978 yy_n, yyreds[ yy_n ] ); 1979 #endif 1980 yytmp = yy_n; /* value to switch over */ 1981 yypvt = yy_pv; /* $vars top of value stack */ 1982 /* 1983 ** Look in goto table for next state 1984 ** Sorry about using yy_state here as temporary 1985 ** register variable, but why not, if it works... 1986 ** If yyr2[ yy_n ] doesn't have the low order bit 1987 ** set, then there is no action to be done for 1988 ** this reduction. So, no saving & unsaving of 1989 ** registers done. The only difference between the 1990 ** code just after the if and the body of the if is 1991 ** the goto yy_stack in the body. This way the test 1992 ** can be made before the choice of what to do is needed. 1993 */ 1994 { 1995 /* length of production doubled with extra bit */ 1996 register int yy_len = yyr2[ yy_n ]; 1997 1998 if ( !( yy_len & 01 ) ) 1999 { 2000 yy_len >>= 1; 2001 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 2002 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 2003 *( yy_ps -= yy_len ) + 1; 2004 if ( yy_state >= YYLAST || 2005 yychk[ yy_state = 2006 yyact[ yy_state ] ] != -yy_n ) 2007 { 2008 yy_state = yyact[ yypgo[ yy_n ] ]; 2009 } 2010 goto yy_stack; 2011 } 2012 yy_len >>= 1; 2013 yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ 2014 yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + 2015 *( yy_ps -= yy_len ) + 1; 2016 if ( yy_state >= YYLAST || 2017 yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) 2018 { 2019 yy_state = yyact[ yypgo[ yy_n ] ]; 2020 } 2021 } 2022 /* save until reenter driver code */ 2023 yystate = yy_state; 2024 yyps = yy_ps; 2025 yypv = yy_pv; 2026 } 2027 /* 2028 ** code supplied by user is placed in this switch 2029 */ 2030 switch( yytmp ) 2031 { 2032 2033 case 1: 2034 # line 244 "poolcfg.y" 2035 { 2036 if (yypvt[-0].cmd->cmd != NULL) 2037 yypvt[-0].cmd->cmd(yypvt[-0].cmd); 2038 free_cmd(yypvt[-0].cmd); 2039 } break; 2040 case 2: 2041 # line 250 "poolcfg.y" 2042 { 2043 if (yypvt[-0].cmd->cmd != NULL) 2044 yypvt[-0].cmd->cmd(yypvt[-0].cmd); 2045 free_cmd(yypvt[-0].cmd); 2046 } break; 2047 case 3: 2048 # line 255 "poolcfg.y" 2049 { YYERROR;} break; 2050 case 5: 2051 # line 259 "poolcfg.y" 2052 { 2053 if (conf_edit_error != POE_OK) { 2054 if (yypvt[-0].cmd->cmd != parser_conf_create && 2055 yypvt[-0].cmd->cmd != parser_conf_discover) { 2056 die(gettext(ERR_CONF_LOAD), conf_file, 2057 get_errstr_err(conf_edit_error, 2058 conf_edit_errno)); 2059 } 2060 } 2061 edited = PO_TRUE; 2062 } break; 2063 case 6: 2064 # line 272 "poolcfg.y" 2065 { 2066 if (conf_list_error != POE_OK) { 2067 if (yypvt[-0].cmd->cmd != parser_conf_create && 2068 yypvt[-0].cmd->cmd != parser_conf_discover) { 2069 die(gettext(ERR_CONF_LOAD), conf_file, 2070 get_errstr_err(conf_list_error, 2071 conf_list_errno)); 2072 } 2073 } 2074 } break; 2075 case 7: 2076 # line 282 "poolcfg.y" 2077 {conf_list_error = conf_edit_error = POE_OK;} break; 2078 case 14: 2079 # line 292 "poolcfg.y" 2080 { 2081 if ((yyval.cmd = alloc_cmd()) == NULL) 2082 YYERROR; 2083 cmd = yyval.cmd; 2084 yyval.cmd->cmd = &parser_conf_info; 2085 } break; 2086 case 15: 2087 # line 299 "poolcfg.y" 2088 { 2089 if ((yyval.cmd = alloc_cmd()) == NULL) 2090 YYERROR; 2091 cmd = yyval.cmd; 2092 switch (yypvt[-1].ival) { 2093 case PCE_SYSTEM: 2094 yyval.cmd->cmd = &parser_conf_info; 2095 break; 2096 case PCE_POOL: 2097 yyval.cmd->cmd = &parser_pool_info; 2098 break; 2099 case PCE_PSET: 2100 yyval.cmd->cmd = &parser_pset_info; 2101 break; 2102 case PCE_CPU: 2103 yyval.cmd->cmd = &parser_cpu_info; 2104 break; 2105 default: 2106 warn(gettext(ERR_UNKNOWN_ENTITY), yypvt[-1].ival); 2107 YYERROR; 2108 } 2109 yyval.cmd->cmd_tgt1 = yypvt[-0].sval; 2110 } break; 2111 case 16: 2112 # line 324 "poolcfg.y" 2113 { 2114 if ((yyval.cmd = alloc_cmd()) == NULL) 2115 YYERROR; 2116 cmd = yyval.cmd; 2117 switch (yypvt[-1].ival) { 2118 case PCE_SYSTEM: 2119 yyval.cmd->cmd = &parser_conf_create; 2120 /* 2121 * When creating a new system element, ensure 2122 * pre-existing errors are ignored. 2123 */ 2124 conf_list_error = conf_edit_error = POE_OK; 2125 break; 2126 case PCE_POOL: 2127 yyval.cmd->cmd = &parser_pool_create; 2128 break; 2129 case PCE_PSET: 2130 yyval.cmd->cmd = &parser_pset_create; 2131 break; 2132 default: 2133 warn(gettext(ERR_UNKNOWN_ENTITY), yypvt[-1].ival); 2134 YYERROR; 2135 } 2136 yyval.cmd->cmd_tgt1 = yypvt[-0].sval; 2137 } break; 2138 case 18: 2139 # line 352 "poolcfg.y" 2140 { 2141 if ((yyval.cmd = alloc_cmd()) == NULL) 2142 YYERROR; 2143 cmd = yyval.cmd; 2144 switch (yypvt[-1].ival) { 2145 case PCE_SYSTEM: 2146 yyval.cmd->cmd = &parser_conf_destroy; 2147 break; 2148 case PCE_POOL: 2149 yyval.cmd->cmd = &parser_pool_destroy; 2150 break; 2151 case PCE_PSET: 2152 yyval.cmd->cmd = &parser_pset_destroy; 2153 break; 2154 default: 2155 warn(gettext(ERR_UNKNOWN_ENTITY), yypvt[-1].ival); 2156 YYERROR; 2157 } 2158 yyval.cmd->cmd_tgt1 = yypvt[-0].sval; 2159 } break; 2160 case 19: 2161 # line 374 "poolcfg.y" 2162 { 2163 if ((yyval.cmd = alloc_cmd()) == NULL) 2164 YYERROR; 2165 cmd = yyval.cmd; 2166 switch (yypvt[-1].ival) { 2167 case PCE_SYSTEM: 2168 yyval.cmd->cmd = &parser_conf_modify; 2169 break; 2170 case PCE_POOL: 2171 yyval.cmd->cmd = &parser_pool_modify; 2172 break; 2173 case PCE_PSET: 2174 yyval.cmd->cmd = &parser_pset_modify; 2175 break; 2176 case PCE_CPU: 2177 yyval.cmd->cmd = &parser_cpu_modify; 2178 break; 2179 default: 2180 warn(gettext(ERR_UNKNOWN_ENTITY), yypvt[-1].ival); 2181 YYERROR; 2182 } 2183 yyval.cmd->cmd_tgt1 = yypvt[-0].sval; 2184 } break; 2185 case 21: 2186 # line 400 "poolcfg.y" 2187 { 2188 if ((yyval.cmd = alloc_cmd()) == NULL) 2189 YYERROR; 2190 cmd = yyval.cmd; 2191 yyval.cmd->cmd = &parser_pool_associate; 2192 cmd->cmd_tgt1 = yypvt[-0].sval; 2193 } break; 2194 case 25: 2195 # line 413 "poolcfg.y" 2196 { 2197 if ((yyval.cmd = alloc_cmd()) == NULL) 2198 YYERROR; 2199 cmd = yyval.cmd; 2200 yyval.cmd->cmd = &parser_resource_xtransfer; 2201 cmd->cmd_tgt1 = yypvt[-0].sval; 2202 } break; 2203 case 27: 2204 # line 423 "poolcfg.y" 2205 { 2206 if ((yyval.cmd = alloc_cmd()) == NULL) 2207 YYERROR; 2208 cmd = yyval.cmd; 2209 yyval.cmd->cmd = &parser_resource_transfer; 2210 cmd->cmd_tgt1 = yypvt[-2].sval; 2211 cmd->cmd_tgt2 = yypvt[-0].sval; 2212 cmd->cmd_qty = yypvt[-5].uval; 2213 } break; 2214 case 28: 2215 # line 433 "poolcfg.y" 2216 { 2217 if ((yyval.cmd = alloc_cmd()) == NULL) 2218 YYERROR; 2219 cmd = yyval.cmd; 2220 yyval.cmd->cmd = &parser_resource_transfer; 2221 cmd->cmd_tgt1 = yypvt[-0].sval; 2222 cmd->cmd_tgt2 = yypvt[-2].sval; 2223 cmd->cmd_qty = yypvt[-5].uval; 2224 } break; 2225 case 29: 2226 # line 444 "poolcfg.y" 2227 { 2228 if ((yyval.cmd = alloc_cmd()) == NULL) 2229 YYERROR; 2230 cmd = yyval.cmd; 2231 yyval.cmd->cmd = &parser_conf_discover; 2232 } break; 2233 case 30: 2234 # line 452 "poolcfg.y" 2235 { 2236 if ((yyval.cmd = alloc_cmd()) == NULL) 2237 YYERROR; 2238 cmd = yyval.cmd; 2239 switch (yypvt[-3].ival) { 2240 case PCE_SYSTEM: 2241 yyval.cmd->cmd = &parser_conf_rename; 2242 break; 2243 case PCE_POOL: 2244 yyval.cmd->cmd = &parser_pool_rename; 2245 break; 2246 case PCE_PSET: 2247 yyval.cmd->cmd = &parser_pset_rename; 2248 break; 2249 default: 2250 warn(gettext(ERR_UNKNOWN_ENTITY), yypvt[-3].ival); 2251 YYERROR; 2252 } 2253 yyval.cmd->cmd_tgt1 = yypvt[-2].sval; 2254 yyval.cmd->cmd_tgt2 = yypvt[-0].sval; 2255 } break; 2256 case 32: 2257 # line 475 "poolcfg.y" 2258 {yyval.ival = PCE_CPU;} break; 2259 case 34: 2260 # line 478 "poolcfg.y" 2261 {yyval.ival = PCE_CPU;} break; 2262 case 35: 2263 # line 480 "poolcfg.y" 2264 {yyval.ival = PCE_SYSTEM;} break; 2265 case 36: 2266 # line 481 "poolcfg.y" 2267 {yyval.ival = PCE_POOL;} break; 2268 case 37: 2269 # line 482 "poolcfg.y" 2270 {yyval.ival = PCE_PSET;} break; 2271 case 41: 2272 # line 490 "poolcfg.y" 2273 { yyval.val.i = yypvt[-0].ival;} break; 2274 case 42: 2275 # line 491 "poolcfg.y" 2276 { yyval.val.u = yypvt[-0].uval;} break; 2277 case 43: 2278 # line 492 "poolcfg.y" 2279 { yyval.val.d = yypvt[-0].dval;} break; 2280 case 44: 2281 # line 493 "poolcfg.y" 2282 { yyval.val.b = yypvt[-0].bval;} break; 2283 case 45: 2284 # line 494 "poolcfg.y" 2285 { yyval.val.s = yypvt[-0].sval;} break; 2286 case 46: 2287 # line 497 "poolcfg.y" 2288 { 2289 if ((yyval.prop = alloc_prop(po_remove)) == NULL) 2290 YYERROR; 2291 yyval.prop->prop_name = yypvt[-0].sval; 2292 } break; 2293 case 49: 2294 # line 507 "poolcfg.y" 2295 { 2296 prop_t *prop = NULL; 2297 prop_t *prev = NULL; 2298 2299 for (prop = cmd->cmd_prop_list; prop != NULL; 2300 prop = prop->prop_next) 2301 prev = prop; /* Find end of list */ 2302 if (prev != NULL) 2303 prev->prop_next = yypvt[-0].prop; 2304 else 2305 cmd->cmd_prop_list = yypvt[-0].prop; 2306 yyval.prop = cmd->cmd_prop_list; 2307 } break; 2308 case 50: 2309 # line 521 "poolcfg.y" 2310 { 2311 prop_t *prop = NULL; 2312 prop_t *prev = NULL; 2313 2314 for (prop = cmd->cmd_prop_list; prop != NULL; 2315 prop = prop->prop_next) 2316 prev = prop; /* Find end of list */ 2317 if (prev != NULL) 2318 prev->prop_next = yypvt[-0].prop; 2319 else 2320 cmd->cmd_prop_list = yypvt[-0].prop; 2321 yyval.prop = cmd->cmd_prop_list; 2322 2323 } break; 2324 case 51: 2325 # line 537 "poolcfg.y" 2326 { 2327 if ((yyval.prop = alloc_prop(po_create)) == NULL) 2328 YYERROR; 2329 yyval.prop->prop_name = yypvt[-2].sval; 2330 switch (yypvt[-3].ival) { 2331 case PCT_INT: 2332 pool_value_set_int64(yyval.prop->prop_value, yypvt[-0].val.i); 2333 break; 2334 case PCT_UINT: 2335 pool_value_set_uint64(yyval.prop->prop_value, yypvt[-0].val.u); 2336 break; 2337 case PCT_BOOLEAN: 2338 pool_value_set_bool(yyval.prop->prop_value, yypvt[-0].val.b); 2339 break; 2340 case PCT_FLOAT: 2341 pool_value_set_double(yyval.prop->prop_value, yypvt[-0].val.d); 2342 break; 2343 case PCT_STRING: 2344 pool_value_set_string(yyval.prop->prop_value, yypvt[-0].val.s); 2345 break; 2346 } 2347 } break; 2348 case 52: 2349 # line 561 "poolcfg.y" 2350 { 2351 yyval.prop = yypvt[-1].prop; 2352 } break; 2353 case 53: 2354 # line 566 "poolcfg.y" 2355 { 2356 assoc_t *assoc = NULL; 2357 assoc_t *prev = NULL; 2358 2359 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 2360 assoc = assoc->assoc_next) 2361 prev = assoc; /* Find end of list */ 2362 if (prev != NULL) 2363 prev->assoc_next = yypvt[-0].assoc; 2364 else 2365 cmd->cmd_assoc_list = yypvt[-0].assoc; 2366 yyval.assoc = cmd->cmd_assoc_list; 2367 } break; 2368 case 54: 2369 # line 581 "poolcfg.y" 2370 { 2371 assoc_t *assoc = NULL; 2372 assoc_t *prev = NULL; 2373 2374 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 2375 assoc = assoc->assoc_next) 2376 prev = assoc; /* Find end of list */ 2377 if (prev != NULL) 2378 prev->assoc_next = yypvt[-0].assoc; 2379 yyval.assoc = yypvt[-0].assoc; 2380 } break; 2381 case 55: 2382 # line 594 "poolcfg.y" 2383 { 2384 if ((yyval.assoc = alloc_assoc(yypvt[-1].ival, yypvt[-0].sval)) == NULL) 2385 YYERROR; 2386 } break; 2387 case 56: 2388 # line 599 "poolcfg.y" 2389 {yyval.ival = PCE_PSET;} break; 2390 case 57: 2391 # line 602 "poolcfg.y" 2392 { 2393 yyval.assoc = yypvt[-1].assoc; 2394 } break; 2395 case 58: 2396 # line 607 "poolcfg.y" 2397 { 2398 assoc_t *assoc = NULL; 2399 assoc_t *prev = NULL; 2400 2401 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 2402 assoc = assoc->assoc_next) 2403 prev = assoc; /* Find end of list */ 2404 if (prev != NULL) 2405 prev->assoc_next = yypvt[-0].assoc; 2406 else 2407 cmd->cmd_assoc_list = yypvt[-0].assoc; 2408 yyval.assoc = cmd->cmd_assoc_list; 2409 } break; 2410 case 59: 2411 # line 622 "poolcfg.y" 2412 { 2413 assoc_t *assoc = NULL; 2414 assoc_t *prev = NULL; 2415 2416 for (assoc = cmd->cmd_assoc_list; assoc != NULL; 2417 assoc = assoc->assoc_next) 2418 prev = assoc; /* Find end of list */ 2419 if (prev != NULL) 2420 prev->assoc_next = yypvt[-0].assoc; 2421 yyval.assoc = yypvt[-0].assoc; 2422 } break; 2423 case 60: 2424 # line 635 "poolcfg.y" 2425 { 2426 yyval.assoc = yypvt[-1].assoc; 2427 } break; 2428 case 61: 2429 # line 640 "poolcfg.y" 2430 { 2431 if ((yyval.assoc = alloc_assoc(yypvt[-1].ival, yypvt[-0].sval)) == NULL) 2432 YYERROR; 2433 } break; 2434 case 62: 2435 # line 645 "poolcfg.y" 2436 {yyval.ival = PCE_CPU;} break; 2437 case 63: 2438 # line 647 "poolcfg.y" 2439 {yyval.ival = PCT_INT;} break; 2440 case 64: 2441 # line 648 "poolcfg.y" 2442 {yyval.ival = PCT_UINT;} break; 2443 case 65: 2444 # line 649 "poolcfg.y" 2445 {yyval.ival = PCT_BOOLEAN;} break; 2446 case 66: 2447 # line 650 "poolcfg.y" 2448 {yyval.ival = PCT_FLOAT;} break; 2449 case 67: 2450 # line 651 "poolcfg.y" 2451 {yyval.ival = PCT_STRING;} break; 2452 # line 556 "/usr/share/lib/ccs/yaccpar" 2453 } 2454 goto yystack; /* reset registers in driver code */ 2455 } 2456 2457