17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5fb03efaaSdp * Common Development and Distribution License (the "License"). 6fb03efaaSdp * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217e362f58Scomay 227c478bd9Sstevel@tonic-gate /* 23fb03efaaSdp * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * zonecfg is a lex/yacc based command interpreter used to manage zone 317c478bd9Sstevel@tonic-gate * configurations. The lexer (see zonecfg_lex.l) builds up tokens, which 327c478bd9Sstevel@tonic-gate * the grammar (see zonecfg_grammar.y) builds up into commands, some of 337c478bd9Sstevel@tonic-gate * which takes resources and/or properties as arguments. See the block 347c478bd9Sstevel@tonic-gate * comments near the end of zonecfg_grammar.y for how the data structures 357c478bd9Sstevel@tonic-gate * which keep track of these resources and properties are built up. 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * The resource/property data structures are inserted into a command 387c478bd9Sstevel@tonic-gate * structure (see zonecfg.h), which also keeps track of command names, 397c478bd9Sstevel@tonic-gate * miscellaneous arguments, and function handlers. The grammar selects 407c478bd9Sstevel@tonic-gate * the appropriate function handler, each of which takes a pointer to a 417c478bd9Sstevel@tonic-gate * command structure as its sole argument, and invokes it. The grammar 427c478bd9Sstevel@tonic-gate * itself is "entered" (a la the Matrix) by yyparse(), which is called 437c478bd9Sstevel@tonic-gate * from read_input(), our main driving function. That in turn is called 447c478bd9Sstevel@tonic-gate * by one of do_interactive(), cmd_file() or one_command_at_a_time(), each 457c478bd9Sstevel@tonic-gate * of which is called from main() depending on how the program was invoked. 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * The rest of this module consists of the various function handlers and 487c478bd9Sstevel@tonic-gate * their helper functions. Some of these functions, particularly the 497c478bd9Sstevel@tonic-gate * X_to_str() functions, which maps command, resource and property numbers 507c478bd9Sstevel@tonic-gate * to strings, are used quite liberally, as doing so results in a better 517c478bd9Sstevel@tonic-gate * program w/rt I18N, reducing the need for translation notes. 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 557c478bd9Sstevel@tonic-gate #include <sys/varargs.h> 567c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #include <errno.h> 59*9acbbeafSnn #include <fcntl.h> 607c478bd9Sstevel@tonic-gate #include <strings.h> 617c478bd9Sstevel@tonic-gate #include <unistd.h> 627c478bd9Sstevel@tonic-gate #include <ctype.h> 637c478bd9Sstevel@tonic-gate #include <stdlib.h> 647c478bd9Sstevel@tonic-gate #include <assert.h> 657c478bd9Sstevel@tonic-gate #include <sys/stat.h> 667c478bd9Sstevel@tonic-gate #include <zone.h> 677c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 687c478bd9Sstevel@tonic-gate #include <netdb.h> 697c478bd9Sstevel@tonic-gate #include <locale.h> 707c478bd9Sstevel@tonic-gate #include <libintl.h> 717c478bd9Sstevel@tonic-gate #include <alloca.h> 727c478bd9Sstevel@tonic-gate #include <signal.h> 73*9acbbeafSnn #include <wait.h> 747c478bd9Sstevel@tonic-gate #include <libtecla.h> 75fa9e4066Sahrens #include <libzfs.h> 76*9acbbeafSnn #include <sys/brand.h> 77*9acbbeafSnn #include <libbrand.h> 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate #include <libzonecfg.h> 807c478bd9Sstevel@tonic-gate #include "zonecfg.h" 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ 837c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ 847c478bd9Sstevel@tonic-gate #endif 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate #define PAGER "/usr/bin/more" 87*9acbbeafSnn #define EXEC_PREFIX "exec " 88*9acbbeafSnn #define EXEC_LEN (strlen(EXEC_PREFIX)) 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate struct help { 917c478bd9Sstevel@tonic-gate uint_t cmd_num; 927c478bd9Sstevel@tonic-gate char *cmd_name; 937c478bd9Sstevel@tonic-gate uint_t flags; 947c478bd9Sstevel@tonic-gate char *short_usage; 957c478bd9Sstevel@tonic-gate }; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate extern int yyparse(void); 987c478bd9Sstevel@tonic-gate extern int lex_lineno; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate #define MAX_LINE_LEN 1024 1017c478bd9Sstevel@tonic-gate #define MAX_CMD_HIST 1024 102*9acbbeafSnn #define MAX_CMD_LEN 1024 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * Each SHELP_ should be a simple string. 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate #define SHELP_ADD "add <resource-type>\n\t(global scope)\n" \ 1097c478bd9Sstevel@tonic-gate "add <property-name> <property-value>\n\t(resource scope)" 1107c478bd9Sstevel@tonic-gate #define SHELP_CANCEL "cancel" 1117c478bd9Sstevel@tonic-gate #define SHELP_COMMIT "commit" 112ee519a1fSgjelinek #define SHELP_CREATE "create [-F] [ -a <path> | -b | -t <template> ]" 1137c478bd9Sstevel@tonic-gate #define SHELP_DELETE "delete [-F]" 1147c478bd9Sstevel@tonic-gate #define SHELP_END "end" 1157c478bd9Sstevel@tonic-gate #define SHELP_EXIT "exit [-F]" 1167c478bd9Sstevel@tonic-gate #define SHELP_EXPORT "export [-f output-file]" 1177c478bd9Sstevel@tonic-gate #define SHELP_HELP "help [commands] [syntax] [usage] [<command-name>]" 1187c478bd9Sstevel@tonic-gate #define SHELP_INFO "info [<resource-type> [property-name=property-value]*]" 1197c478bd9Sstevel@tonic-gate #define SHELP_REMOVE "remove <resource-type> { <property-name>=<property-" \ 120ffbafc53Scomay "value> }\n\t(global scope)\nremove <property-name> <property-value>" \ 1217c478bd9Sstevel@tonic-gate "\n\t(resource scope)" 1227c478bd9Sstevel@tonic-gate #define SHELP_REVERT "revert [-F]" 1237c478bd9Sstevel@tonic-gate #define SHELP_SELECT "select <resource-type> { <property-name>=" \ 1247c478bd9Sstevel@tonic-gate "<property-value> }" 1257c478bd9Sstevel@tonic-gate #define SHELP_SET "set <property-name>=<property-value>" 1267c478bd9Sstevel@tonic-gate #define SHELP_VERIFY "verify" 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate static struct help helptab[] = { 1297c478bd9Sstevel@tonic-gate { CMD_ADD, "add", HELP_RES_PROPS, SHELP_ADD, }, 1307c478bd9Sstevel@tonic-gate { CMD_CANCEL, "cancel", 0, SHELP_CANCEL, }, 1317c478bd9Sstevel@tonic-gate { CMD_COMMIT, "commit", 0, SHELP_COMMIT, }, 1327c478bd9Sstevel@tonic-gate { CMD_CREATE, "create", 0, SHELP_CREATE, }, 1337c478bd9Sstevel@tonic-gate { CMD_DELETE, "delete", 0, SHELP_DELETE, }, 1347c478bd9Sstevel@tonic-gate { CMD_END, "end", 0, SHELP_END, }, 1357c478bd9Sstevel@tonic-gate { CMD_EXIT, "exit", 0, SHELP_EXIT, }, 1367c478bd9Sstevel@tonic-gate { CMD_EXPORT, "export", 0, SHELP_EXPORT, }, 1377c478bd9Sstevel@tonic-gate { CMD_HELP, "help", 0, SHELP_HELP }, 1387c478bd9Sstevel@tonic-gate { CMD_INFO, "info", HELP_RES_PROPS, SHELP_INFO, }, 1397c478bd9Sstevel@tonic-gate { CMD_REMOVE, "remove", HELP_RES_PROPS, SHELP_REMOVE, }, 1407c478bd9Sstevel@tonic-gate { CMD_REVERT, "revert", 0, SHELP_REVERT, }, 1417c478bd9Sstevel@tonic-gate { CMD_SELECT, "select", HELP_RES_PROPS, SHELP_SELECT, }, 1427c478bd9Sstevel@tonic-gate { CMD_SET, "set", HELP_PROPS, SHELP_SET, }, 1437c478bd9Sstevel@tonic-gate { CMD_VERIFY, "verify", 0, SHELP_VERIFY, }, 1447c478bd9Sstevel@tonic-gate { 0 }, 1457c478bd9Sstevel@tonic-gate }; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate #define MAX_RT_STRLEN 16 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* These *must* match the order of the RT_ define's from zonecfg.h */ 1507c478bd9Sstevel@tonic-gate static char *res_types[] = { 1517c478bd9Sstevel@tonic-gate "unknown", 152087719fdSdp "zonename", 1537c478bd9Sstevel@tonic-gate "zonepath", 1547c478bd9Sstevel@tonic-gate "autoboot", 1557c478bd9Sstevel@tonic-gate "pool", 1567c478bd9Sstevel@tonic-gate "fs", 1577c478bd9Sstevel@tonic-gate "inherit-pkg-dir", 1587c478bd9Sstevel@tonic-gate "net", 1597c478bd9Sstevel@tonic-gate "device", 1607c478bd9Sstevel@tonic-gate "rctl", 1617c478bd9Sstevel@tonic-gate "attr", 162fa9e4066Sahrens "dataset", 163ffbafc53Scomay "limitpriv", 1643f2f09c1Sdp "bootargs", 165*9acbbeafSnn "brand", 1667c478bd9Sstevel@tonic-gate NULL 1677c478bd9Sstevel@tonic-gate }; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* These *must* match the order of the PT_ define's from zonecfg.h */ 1707c478bd9Sstevel@tonic-gate static char *prop_types[] = { 1717c478bd9Sstevel@tonic-gate "unknown", 172087719fdSdp "zonename", 1737c478bd9Sstevel@tonic-gate "zonepath", 1747c478bd9Sstevel@tonic-gate "autoboot", 1757c478bd9Sstevel@tonic-gate "pool", 1767c478bd9Sstevel@tonic-gate "dir", 1777c478bd9Sstevel@tonic-gate "special", 1787c478bd9Sstevel@tonic-gate "type", 1797c478bd9Sstevel@tonic-gate "options", 1807c478bd9Sstevel@tonic-gate "address", 1817c478bd9Sstevel@tonic-gate "physical", 1827c478bd9Sstevel@tonic-gate "name", 1837c478bd9Sstevel@tonic-gate "value", 1847c478bd9Sstevel@tonic-gate "match", 1857c478bd9Sstevel@tonic-gate "priv", 1867c478bd9Sstevel@tonic-gate "limit", 1877c478bd9Sstevel@tonic-gate "action", 1887c478bd9Sstevel@tonic-gate "raw", 189ffbafc53Scomay "limitpriv", 1903f2f09c1Sdp "bootargs", 191*9acbbeafSnn "brand", 1927c478bd9Sstevel@tonic-gate NULL 1937c478bd9Sstevel@tonic-gate }; 1947c478bd9Sstevel@tonic-gate 195ffbafc53Scomay /* These *must* match the order of the PROP_VAL_ define's from zonecfg.h */ 1967c478bd9Sstevel@tonic-gate static char *prop_val_types[] = { 1977c478bd9Sstevel@tonic-gate "simple", 1987c478bd9Sstevel@tonic-gate "complex", 1997c478bd9Sstevel@tonic-gate "list", 2007c478bd9Sstevel@tonic-gate }; 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* 2037c478bd9Sstevel@tonic-gate * The various _cmds[] lists below are for command tab-completion. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * remove has a space afterwards because it has qualifiers; the other commands 2087c478bd9Sstevel@tonic-gate * that have qualifiers (add, select and set) don't need a space here because 2097c478bd9Sstevel@tonic-gate * they have their own _cmds[] lists below. 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate static const char *global_scope_cmds[] = { 2127c478bd9Sstevel@tonic-gate "add", 2137c478bd9Sstevel@tonic-gate "commit", 2147c478bd9Sstevel@tonic-gate "create", 2157c478bd9Sstevel@tonic-gate "delete", 2167c478bd9Sstevel@tonic-gate "exit", 2177c478bd9Sstevel@tonic-gate "export", 2187c478bd9Sstevel@tonic-gate "help", 2197c478bd9Sstevel@tonic-gate "info", 2207c478bd9Sstevel@tonic-gate "remove ", 2217c478bd9Sstevel@tonic-gate "revert", 2227c478bd9Sstevel@tonic-gate "select", 2237c478bd9Sstevel@tonic-gate "set", 2247c478bd9Sstevel@tonic-gate "verify", 2257c478bd9Sstevel@tonic-gate NULL 2267c478bd9Sstevel@tonic-gate }; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate static const char *add_cmds[] = { 2297c478bd9Sstevel@tonic-gate "add fs", 2307c478bd9Sstevel@tonic-gate "add inherit-pkg-dir", 2317c478bd9Sstevel@tonic-gate "add net", 2327c478bd9Sstevel@tonic-gate "add device", 2337c478bd9Sstevel@tonic-gate "add rctl", 2347c478bd9Sstevel@tonic-gate "add attr", 235fa9e4066Sahrens "add dataset", 2367c478bd9Sstevel@tonic-gate NULL 2377c478bd9Sstevel@tonic-gate }; 2387c478bd9Sstevel@tonic-gate 2399e7542f4Sdp static const char *remove_cmds[] = { 2409e7542f4Sdp "remove fs ", 2419e7542f4Sdp "remove inherit-pkg-dir ", 2429e7542f4Sdp "remove net ", 2439e7542f4Sdp "remove device ", 2449e7542f4Sdp "remove rctl ", 2459e7542f4Sdp "remove attr ", 2469e7542f4Sdp "remove dataset ", 2479e7542f4Sdp NULL 2489e7542f4Sdp }; 2499e7542f4Sdp 2507c478bd9Sstevel@tonic-gate static const char *select_cmds[] = { 251087719fdSdp "select fs ", 252087719fdSdp "select inherit-pkg-dir ", 253087719fdSdp "select net ", 254087719fdSdp "select device ", 255087719fdSdp "select rctl ", 256087719fdSdp "select attr ", 257fa9e4066Sahrens "select dataset ", 2587c478bd9Sstevel@tonic-gate NULL 2597c478bd9Sstevel@tonic-gate }; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate static const char *set_cmds[] = { 262087719fdSdp "set zonename=", 263087719fdSdp "set zonepath=", 264*9acbbeafSnn "set brand=", 265087719fdSdp "set autoboot=", 266087719fdSdp "set pool=", 267ffbafc53Scomay "set limitpriv=", 2683f2f09c1Sdp "set bootargs=", 2697c478bd9Sstevel@tonic-gate NULL 2707c478bd9Sstevel@tonic-gate }; 2717c478bd9Sstevel@tonic-gate 2729e7542f4Sdp static const char *info_cmds[] = { 2739e7542f4Sdp "info fs ", 2749e7542f4Sdp "info inherit-pkg-dir ", 2759e7542f4Sdp "info net ", 2769e7542f4Sdp "info device ", 2779e7542f4Sdp "info rctl ", 2789e7542f4Sdp "info attr ", 2799e7542f4Sdp "info dataset ", 2809e7542f4Sdp "info zonename", 2819e7542f4Sdp "info zonepath", 2829e7542f4Sdp "info autoboot", 2839e7542f4Sdp "info pool", 2849e7542f4Sdp "info limitpriv", 2859e7542f4Sdp "info bootargs", 2869e7542f4Sdp NULL 2879e7542f4Sdp }; 2889e7542f4Sdp 2897c478bd9Sstevel@tonic-gate static const char *fs_res_scope_cmds[] = { 2907c478bd9Sstevel@tonic-gate "add options ", 2917c478bd9Sstevel@tonic-gate "cancel", 2927c478bd9Sstevel@tonic-gate "end", 2937c478bd9Sstevel@tonic-gate "exit", 2947c478bd9Sstevel@tonic-gate "help", 2957c478bd9Sstevel@tonic-gate "info", 296ffbafc53Scomay "remove options ", 2977c478bd9Sstevel@tonic-gate "set dir=", 2987c478bd9Sstevel@tonic-gate "set raw=", 2997c478bd9Sstevel@tonic-gate "set special=", 3007c478bd9Sstevel@tonic-gate "set type=", 3017c478bd9Sstevel@tonic-gate NULL 3027c478bd9Sstevel@tonic-gate }; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate static const char *net_res_scope_cmds[] = { 3057c478bd9Sstevel@tonic-gate "cancel", 3067c478bd9Sstevel@tonic-gate "end", 3077c478bd9Sstevel@tonic-gate "exit", 3087c478bd9Sstevel@tonic-gate "help", 3097c478bd9Sstevel@tonic-gate "info", 3107c478bd9Sstevel@tonic-gate "set address=", 3117c478bd9Sstevel@tonic-gate "set physical=", 3127c478bd9Sstevel@tonic-gate NULL 3137c478bd9Sstevel@tonic-gate }; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate static const char *ipd_res_scope_cmds[] = { 3167c478bd9Sstevel@tonic-gate "cancel", 3177c478bd9Sstevel@tonic-gate "end", 3187c478bd9Sstevel@tonic-gate "exit", 3197c478bd9Sstevel@tonic-gate "help", 3207c478bd9Sstevel@tonic-gate "info", 3217c478bd9Sstevel@tonic-gate "set dir=", 3227c478bd9Sstevel@tonic-gate NULL 3237c478bd9Sstevel@tonic-gate }; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate static const char *device_res_scope_cmds[] = { 3267c478bd9Sstevel@tonic-gate "cancel", 3277c478bd9Sstevel@tonic-gate "end", 3287c478bd9Sstevel@tonic-gate "exit", 3297c478bd9Sstevel@tonic-gate "help", 3307c478bd9Sstevel@tonic-gate "info", 3317c478bd9Sstevel@tonic-gate "set match=", 3327c478bd9Sstevel@tonic-gate NULL 3337c478bd9Sstevel@tonic-gate }; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate static const char *attr_res_scope_cmds[] = { 3367c478bd9Sstevel@tonic-gate "cancel", 3377c478bd9Sstevel@tonic-gate "end", 3387c478bd9Sstevel@tonic-gate "exit", 3397c478bd9Sstevel@tonic-gate "help", 3407c478bd9Sstevel@tonic-gate "info", 3417c478bd9Sstevel@tonic-gate "set name=", 3427c478bd9Sstevel@tonic-gate "set type=", 3437c478bd9Sstevel@tonic-gate "set value=", 3447c478bd9Sstevel@tonic-gate NULL 3457c478bd9Sstevel@tonic-gate }; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate static const char *rctl_res_scope_cmds[] = { 3487c478bd9Sstevel@tonic-gate "add value ", 3497c478bd9Sstevel@tonic-gate "cancel", 3507c478bd9Sstevel@tonic-gate "end", 3517c478bd9Sstevel@tonic-gate "exit", 3527c478bd9Sstevel@tonic-gate "help", 3537c478bd9Sstevel@tonic-gate "info", 354ffbafc53Scomay "remove value ", 3557c478bd9Sstevel@tonic-gate "set name=", 3567c478bd9Sstevel@tonic-gate NULL 3577c478bd9Sstevel@tonic-gate }; 3587c478bd9Sstevel@tonic-gate 359fa9e4066Sahrens static const char *dataset_res_scope_cmds[] = { 360fa9e4066Sahrens "cancel", 361fa9e4066Sahrens "end", 362fa9e4066Sahrens "exit", 363fa9e4066Sahrens "help", 364fa9e4066Sahrens "info", 365fa9e4066Sahrens "set name=", 366fa9e4066Sahrens NULL 367fa9e4066Sahrens }; 368fa9e4066Sahrens 3697c478bd9Sstevel@tonic-gate /* Global variables */ 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* set early in main(), never modified thereafter, used all over the place */ 3727c478bd9Sstevel@tonic-gate static char *execname; 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* set in main(), used all over the place */ 3757c478bd9Sstevel@tonic-gate static zone_dochandle_t handle; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* used all over the place */ 378087719fdSdp static char zone[ZONENAME_MAX]; 379087719fdSdp static char revert_zone[ZONENAME_MAX]; 3807c478bd9Sstevel@tonic-gate 381*9acbbeafSnn /* global brand operations */ 382*9acbbeafSnn static brand_handle_t *brand; 383*9acbbeafSnn 3847c478bd9Sstevel@tonic-gate /* set in modifying functions, checked in read_input() */ 3857c478bd9Sstevel@tonic-gate static bool need_to_commit = FALSE; 3867c478bd9Sstevel@tonic-gate bool saw_error; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* set in yacc parser, checked in read_input() */ 3897c478bd9Sstevel@tonic-gate bool newline_terminated; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate /* set in main(), checked in lex error handler */ 3927c478bd9Sstevel@tonic-gate bool cmd_file_mode; 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate /* set in exit_func(), checked in read_input() */ 3957c478bd9Sstevel@tonic-gate static bool time_to_exit = FALSE, force_exit = FALSE; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* used in short_usage() and zerr() */ 3987c478bd9Sstevel@tonic-gate static char *cmd_file_name = NULL; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate /* checked in read_input() and other places */ 4017c478bd9Sstevel@tonic-gate static bool ok_to_prompt = FALSE; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate /* set and checked in initialize() */ 4047c478bd9Sstevel@tonic-gate static bool got_handle = FALSE; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate /* initialized in do_interactive(), checked in initialize() */ 4077c478bd9Sstevel@tonic-gate static bool interactive_mode; 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate /* set in main(), checked in multiple places */ 4107c478bd9Sstevel@tonic-gate static bool read_only_mode; 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate static bool global_scope = TRUE; /* scope is outer/global or inner/resource */ 4137c478bd9Sstevel@tonic-gate static int resource_scope; /* should be in the RT_ list from zonecfg.h */ 4147c478bd9Sstevel@tonic-gate static int end_op = -1; /* operation on end is either add or modify */ 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate int num_prop_vals; /* for grammar */ 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate /* 4197c478bd9Sstevel@tonic-gate * These are for keeping track of resources as they are specified as part of 4207c478bd9Sstevel@tonic-gate * the multi-step process. They should be initialized by add_resource() or 4217c478bd9Sstevel@tonic-gate * select_func() and filled in by add_property() or set_func(). 4227c478bd9Sstevel@tonic-gate */ 4237c478bd9Sstevel@tonic-gate static struct zone_fstab old_fstab, in_progress_fstab; 4247c478bd9Sstevel@tonic-gate static struct zone_fstab old_ipdtab, in_progress_ipdtab; 4257c478bd9Sstevel@tonic-gate static struct zone_nwiftab old_nwiftab, in_progress_nwiftab; 4267c478bd9Sstevel@tonic-gate static struct zone_devtab old_devtab, in_progress_devtab; 4277c478bd9Sstevel@tonic-gate static struct zone_rctltab old_rctltab, in_progress_rctltab; 4287c478bd9Sstevel@tonic-gate static struct zone_attrtab old_attrtab, in_progress_attrtab; 429fa9e4066Sahrens static struct zone_dstab old_dstab, in_progress_dstab; 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate static GetLine *gl; /* The gl_get_line() resource object */ 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* Functions begin here */ 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate static bool 4367c478bd9Sstevel@tonic-gate initial_match(const char *line1, const char *line2, int word_end) 4377c478bd9Sstevel@tonic-gate { 4387c478bd9Sstevel@tonic-gate if (word_end <= 0) 4397c478bd9Sstevel@tonic-gate return (TRUE); 4407c478bd9Sstevel@tonic-gate return (strncmp(line1, line2, word_end) == 0); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate static int 4447c478bd9Sstevel@tonic-gate add_stuff(WordCompletion *cpl, const char *line1, const char **list, 4457c478bd9Sstevel@tonic-gate int word_end) 4467c478bd9Sstevel@tonic-gate { 4477c478bd9Sstevel@tonic-gate int i, err; 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate for (i = 0; list[i] != NULL; i++) { 4507c478bd9Sstevel@tonic-gate if (initial_match(line1, list[i], word_end)) { 4517c478bd9Sstevel@tonic-gate err = cpl_add_completion(cpl, line1, 0, word_end, 4527c478bd9Sstevel@tonic-gate list[i] + word_end, "", ""); 4537c478bd9Sstevel@tonic-gate if (err != 0) 4547c478bd9Sstevel@tonic-gate return (err); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate return (0); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate static 4617c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4627c478bd9Sstevel@tonic-gate CPL_MATCH_FN(cmd_cpl_fn) 4637c478bd9Sstevel@tonic-gate { 4647c478bd9Sstevel@tonic-gate if (global_scope) { 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * The MAX/MIN tests below are to make sure we have at least 4677c478bd9Sstevel@tonic-gate * enough characters to distinguish from other prefixes (MAX) 4687c478bd9Sstevel@tonic-gate * but only check MIN(what we have, what we're checking). 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate if (strncmp(line, "add ", MAX(MIN(word_end, 4), 1)) == 0) 4717c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, add_cmds, word_end)); 4727c478bd9Sstevel@tonic-gate if (strncmp(line, "select ", MAX(MIN(word_end, 7), 3)) == 0) 4737c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, select_cmds, word_end)); 4747c478bd9Sstevel@tonic-gate if (strncmp(line, "set ", MAX(MIN(word_end, 4), 3)) == 0) 4757c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, set_cmds, word_end)); 4769e7542f4Sdp if (strncmp(line, "remove ", MAX(MIN(word_end, 7), 1)) == 0) 4779e7542f4Sdp return (add_stuff(cpl, line, remove_cmds, word_end)); 4789e7542f4Sdp if (strncmp(line, "info ", MAX(MIN(word_end, 5), 1)) == 0) 4799e7542f4Sdp return (add_stuff(cpl, line, info_cmds, word_end)); 4807c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, global_scope_cmds, word_end)); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate switch (resource_scope) { 4837c478bd9Sstevel@tonic-gate case RT_FS: 4847c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, fs_res_scope_cmds, word_end)); 4857c478bd9Sstevel@tonic-gate case RT_IPD: 4867c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, ipd_res_scope_cmds, word_end)); 4877c478bd9Sstevel@tonic-gate case RT_NET: 4887c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, net_res_scope_cmds, word_end)); 4897c478bd9Sstevel@tonic-gate case RT_DEVICE: 4907c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, device_res_scope_cmds, word_end)); 4917c478bd9Sstevel@tonic-gate case RT_RCTL: 4927c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, rctl_res_scope_cmds, word_end)); 4937c478bd9Sstevel@tonic-gate case RT_ATTR: 4947c478bd9Sstevel@tonic-gate return (add_stuff(cpl, line, attr_res_scope_cmds, word_end)); 495fa9e4066Sahrens case RT_DATASET: 496fa9e4066Sahrens return (add_stuff(cpl, line, dataset_res_scope_cmds, word_end)); 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate return (0); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /* 5027c478bd9Sstevel@tonic-gate * For the main CMD_func() functions below, several of them call getopt() 5037c478bd9Sstevel@tonic-gate * then check optind against argc to make sure an extra parameter was not 5047c478bd9Sstevel@tonic-gate * passed in. The reason this is not caught in the grammar is that the 5057c478bd9Sstevel@tonic-gate * grammar just checks for a miscellaneous TOKEN, which is *expected* to 5067c478bd9Sstevel@tonic-gate * be "-F" (for example), but could be anything. So (for example) this 5077c478bd9Sstevel@tonic-gate * check will prevent "create bogus". 5087c478bd9Sstevel@tonic-gate */ 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate cmd_t * 5117c478bd9Sstevel@tonic-gate alloc_cmd(void) 5127c478bd9Sstevel@tonic-gate { 5137c478bd9Sstevel@tonic-gate return (calloc(1, sizeof (cmd_t))); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate void 5177c478bd9Sstevel@tonic-gate free_cmd(cmd_t *cmd) 5187c478bd9Sstevel@tonic-gate { 5197c478bd9Sstevel@tonic-gate int i; 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_EQ_PROP_PAIRS; i++) 5227c478bd9Sstevel@tonic-gate if (cmd->cmd_property_ptr[i] != NULL) { 5237c478bd9Sstevel@tonic-gate property_value_ptr_t pp = cmd->cmd_property_ptr[i]; 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate switch (pp->pv_type) { 5267c478bd9Sstevel@tonic-gate case PROP_VAL_SIMPLE: 5277c478bd9Sstevel@tonic-gate free(pp->pv_simple); 5287c478bd9Sstevel@tonic-gate break; 5297c478bd9Sstevel@tonic-gate case PROP_VAL_COMPLEX: 5307c478bd9Sstevel@tonic-gate free_complex(pp->pv_complex); 5317c478bd9Sstevel@tonic-gate break; 5327c478bd9Sstevel@tonic-gate case PROP_VAL_LIST: 5337c478bd9Sstevel@tonic-gate free_list(pp->pv_list); 5347c478bd9Sstevel@tonic-gate break; 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_argc; i++) 5387c478bd9Sstevel@tonic-gate free(cmd->cmd_argv[i]); 5397c478bd9Sstevel@tonic-gate free(cmd); 5407c478bd9Sstevel@tonic-gate } 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate complex_property_ptr_t 5437c478bd9Sstevel@tonic-gate alloc_complex(void) 5447c478bd9Sstevel@tonic-gate { 5457c478bd9Sstevel@tonic-gate return (calloc(1, sizeof (complex_property_t))); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate void 5497c478bd9Sstevel@tonic-gate free_complex(complex_property_ptr_t complex) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate if (complex == NULL) 5527c478bd9Sstevel@tonic-gate return; 5537c478bd9Sstevel@tonic-gate free_complex(complex->cp_next); 5547c478bd9Sstevel@tonic-gate if (complex->cp_value != NULL) 5557c478bd9Sstevel@tonic-gate free(complex->cp_value); 5567c478bd9Sstevel@tonic-gate free(complex); 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate list_property_ptr_t 5607c478bd9Sstevel@tonic-gate alloc_list(void) 5617c478bd9Sstevel@tonic-gate { 5627c478bd9Sstevel@tonic-gate return (calloc(1, sizeof (list_property_t))); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate void 5667c478bd9Sstevel@tonic-gate free_list(list_property_ptr_t list) 5677c478bd9Sstevel@tonic-gate { 5687c478bd9Sstevel@tonic-gate if (list == NULL) 5697c478bd9Sstevel@tonic-gate return; 5707c478bd9Sstevel@tonic-gate if (list->lp_simple != NULL) 5717c478bd9Sstevel@tonic-gate free(list->lp_simple); 5727c478bd9Sstevel@tonic-gate free_complex(list->lp_complex); 5737c478bd9Sstevel@tonic-gate free_list(list->lp_next); 5747c478bd9Sstevel@tonic-gate free(list); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate void 5787c478bd9Sstevel@tonic-gate free_outer_list(list_property_ptr_t list) 5797c478bd9Sstevel@tonic-gate { 5807c478bd9Sstevel@tonic-gate if (list == NULL) 5817c478bd9Sstevel@tonic-gate return; 5827c478bd9Sstevel@tonic-gate free_outer_list(list->lp_next); 5837c478bd9Sstevel@tonic-gate free(list); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate static struct zone_rctlvaltab * 5877c478bd9Sstevel@tonic-gate alloc_rctlvaltab(void) 5887c478bd9Sstevel@tonic-gate { 5897c478bd9Sstevel@tonic-gate return (calloc(1, sizeof (struct zone_rctlvaltab))); 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate static char * 5937c478bd9Sstevel@tonic-gate rt_to_str(int res_type) 5947c478bd9Sstevel@tonic-gate { 5957c478bd9Sstevel@tonic-gate assert(res_type >= RT_MIN && res_type <= RT_MAX); 5967c478bd9Sstevel@tonic-gate return (res_types[res_type]); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate static char * 6007c478bd9Sstevel@tonic-gate pt_to_str(int prop_type) 6017c478bd9Sstevel@tonic-gate { 6027c478bd9Sstevel@tonic-gate assert(prop_type >= PT_MIN && prop_type <= PT_MAX); 6037c478bd9Sstevel@tonic-gate return (prop_types[prop_type]); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate static char * 6077c478bd9Sstevel@tonic-gate pvt_to_str(int pv_type) 6087c478bd9Sstevel@tonic-gate { 6097c478bd9Sstevel@tonic-gate assert(pv_type >= PROP_VAL_MIN && pv_type <= PROP_VAL_MAX); 6107c478bd9Sstevel@tonic-gate return (prop_val_types[pv_type]); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate static char * 6147c478bd9Sstevel@tonic-gate cmd_to_str(int cmd_num) 6157c478bd9Sstevel@tonic-gate { 6167c478bd9Sstevel@tonic-gate assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 6177c478bd9Sstevel@tonic-gate return (helptab[cmd_num].cmd_name); 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate /* 6217c478bd9Sstevel@tonic-gate * This is a separate function rather than a set of define's because of the 6227c478bd9Sstevel@tonic-gate * gettext() wrapping. 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate /* 6267c478bd9Sstevel@tonic-gate * TRANSLATION_NOTE 6277c478bd9Sstevel@tonic-gate * Each string below should have \t follow \n whenever needed; the 6287c478bd9Sstevel@tonic-gate * initial \t and the terminal \n will be provided by the calling function. 6297c478bd9Sstevel@tonic-gate */ 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate static char * 6327c478bd9Sstevel@tonic-gate long_help(int cmd_num) 6337c478bd9Sstevel@tonic-gate { 6347c478bd9Sstevel@tonic-gate static char line[1024]; /* arbitrary large amount */ 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 6377c478bd9Sstevel@tonic-gate switch (cmd_num) { 6387c478bd9Sstevel@tonic-gate case CMD_HELP: 6397c478bd9Sstevel@tonic-gate return (gettext("Prints help message.")); 6407c478bd9Sstevel@tonic-gate case CMD_CREATE: 6417c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 6427c478bd9Sstevel@tonic-gate gettext("Creates a configuration for the " 6437c478bd9Sstevel@tonic-gate "specified zone. %s should be\n\tused to " 6447c478bd9Sstevel@tonic-gate "begin configuring a new zone. If overwriting an " 6457c478bd9Sstevel@tonic-gate "existing\n\tconfiguration, the -F flag can be " 6467c478bd9Sstevel@tonic-gate "used to force the action. If\n\t-t template is " 6477c478bd9Sstevel@tonic-gate "given, creates a configuration identical to the\n" 6487c478bd9Sstevel@tonic-gate "\tspecified template, except that the zone name " 6499e518655Sgjelinek "is changed from\n\ttemplate to zonename. '%s -a' " 6509e518655Sgjelinek "creates a configuration from a\n\tdetached " 6519e518655Sgjelinek "zonepath. '%s -b' results in a blank " 6529e518655Sgjelinek "configuration.\n\t'%s' with no arguments applies " 6539e518655Sgjelinek "the Sun default settings."), 6547c478bd9Sstevel@tonic-gate cmd_to_str(CMD_CREATE), cmd_to_str(CMD_CREATE), 6559e518655Sgjelinek cmd_to_str(CMD_CREATE), cmd_to_str(CMD_CREATE)); 6567c478bd9Sstevel@tonic-gate return (line); 6577c478bd9Sstevel@tonic-gate case CMD_EXIT: 6587c478bd9Sstevel@tonic-gate return (gettext("Exits the program. The -F flag can " 6597c478bd9Sstevel@tonic-gate "be used to force the action.")); 6607c478bd9Sstevel@tonic-gate case CMD_EXPORT: 6617c478bd9Sstevel@tonic-gate return (gettext("Prints configuration to standard " 6627c478bd9Sstevel@tonic-gate "output, or to output-file if\n\tspecified, in " 6637c478bd9Sstevel@tonic-gate "a form suitable for use in a command-file.")); 6647c478bd9Sstevel@tonic-gate case CMD_ADD: 6657c478bd9Sstevel@tonic-gate return (gettext("Add specified resource to " 6667c478bd9Sstevel@tonic-gate "configuration.")); 6677c478bd9Sstevel@tonic-gate case CMD_DELETE: 6687c478bd9Sstevel@tonic-gate return (gettext("Deletes the specified zone. The -F " 6697c478bd9Sstevel@tonic-gate "flag can be used to force the\n\taction.")); 6707c478bd9Sstevel@tonic-gate case CMD_REMOVE: 6717c478bd9Sstevel@tonic-gate return (gettext("Remove specified resource from " 6727c478bd9Sstevel@tonic-gate "configuration. Note that the curly\n\tbraces " 6737c478bd9Sstevel@tonic-gate "('{', '}') mean one or more of whatever " 6747c478bd9Sstevel@tonic-gate "is between them.")); 6757c478bd9Sstevel@tonic-gate case CMD_SELECT: 6767c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 6777c478bd9Sstevel@tonic-gate gettext("Selects a resource to modify. " 6787c478bd9Sstevel@tonic-gate "Resource modification is completed\n\twith the " 6797c478bd9Sstevel@tonic-gate "command \"%s\". The property name/value pairs " 6807c478bd9Sstevel@tonic-gate "must uniquely\n\tidentify a resource. Note that " 6817c478bd9Sstevel@tonic-gate "the curly braces ('{', '}') mean one\n\tor more " 6827c478bd9Sstevel@tonic-gate "of whatever is between them."), 6837c478bd9Sstevel@tonic-gate cmd_to_str(CMD_END)); 6847c478bd9Sstevel@tonic-gate return (line); 6857c478bd9Sstevel@tonic-gate case CMD_SET: 6867c478bd9Sstevel@tonic-gate return (gettext("Sets property values.")); 6877c478bd9Sstevel@tonic-gate case CMD_INFO: 6887c478bd9Sstevel@tonic-gate return (gettext("Displays information about the " 6897c478bd9Sstevel@tonic-gate "current configuration. If resource\n\ttype is " 6907c478bd9Sstevel@tonic-gate "specified, displays only information about " 6917c478bd9Sstevel@tonic-gate "resources of\n\tthe relevant type. If resource " 6927c478bd9Sstevel@tonic-gate "id is specified, displays only\n\tinformation " 6937c478bd9Sstevel@tonic-gate "about that resource.")); 6947c478bd9Sstevel@tonic-gate case CMD_VERIFY: 6957c478bd9Sstevel@tonic-gate return (gettext("Verifies current configuration " 6967c478bd9Sstevel@tonic-gate "for correctness (some resource types\n\thave " 6977c478bd9Sstevel@tonic-gate "required properties).")); 6987c478bd9Sstevel@tonic-gate case CMD_COMMIT: 6997c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 7007c478bd9Sstevel@tonic-gate gettext("Commits current configuration. " 7017c478bd9Sstevel@tonic-gate "Configuration must be committed to\n\tbe used by " 7027c478bd9Sstevel@tonic-gate "%s. Until the configuration is committed, " 7037c478bd9Sstevel@tonic-gate "changes \n\tcan be removed with the %s " 7047c478bd9Sstevel@tonic-gate "command. This operation is\n\tattempted " 7057c478bd9Sstevel@tonic-gate "automatically upon completion of a %s " 7067c478bd9Sstevel@tonic-gate "session."), "zoneadm", cmd_to_str(CMD_REVERT), 7077c478bd9Sstevel@tonic-gate "zonecfg"); 7087c478bd9Sstevel@tonic-gate return (line); 7097c478bd9Sstevel@tonic-gate case CMD_REVERT: 7107c478bd9Sstevel@tonic-gate return (gettext("Reverts configuration back to the " 7117c478bd9Sstevel@tonic-gate "last committed state. The -F flag\n\tcan be " 7127c478bd9Sstevel@tonic-gate "used to force the action.")); 7137c478bd9Sstevel@tonic-gate case CMD_CANCEL: 7147c478bd9Sstevel@tonic-gate return (gettext("Cancels resource/property " 7157c478bd9Sstevel@tonic-gate "specification.")); 7167c478bd9Sstevel@tonic-gate case CMD_END: 7177c478bd9Sstevel@tonic-gate return (gettext("Ends resource/property " 7187c478bd9Sstevel@tonic-gate "specification.")); 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate /* NOTREACHED */ 7217e362f58Scomay return (NULL); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate /* 7257c478bd9Sstevel@tonic-gate * Called with verbose TRUE when help is explicitly requested, FALSE for 7267c478bd9Sstevel@tonic-gate * unexpected errors. 7277c478bd9Sstevel@tonic-gate */ 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate void 7307c478bd9Sstevel@tonic-gate usage(bool verbose, uint_t flags) 7317c478bd9Sstevel@tonic-gate { 7327c478bd9Sstevel@tonic-gate FILE *fp = verbose ? stdout : stderr, *newfp; 7337c478bd9Sstevel@tonic-gate bool need_to_close = FALSE; 7347c478bd9Sstevel@tonic-gate char *pager; 7357c478bd9Sstevel@tonic-gate int i; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate /* don't page error output */ 7387c478bd9Sstevel@tonic-gate if (verbose && interactive_mode) { 7397c478bd9Sstevel@tonic-gate if ((pager = getenv("PAGER")) == NULL) 7407c478bd9Sstevel@tonic-gate pager = PAGER; 7417c478bd9Sstevel@tonic-gate if ((newfp = popen(pager, "w")) != NULL) { 7427c478bd9Sstevel@tonic-gate need_to_close = TRUE; 7437c478bd9Sstevel@tonic-gate fp = newfp; 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate if (flags & HELP_META) { 7477c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("More help is available for the " 7487c478bd9Sstevel@tonic-gate "following:\n")); 7497c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n\tcommands ('%s commands')\n", 7507c478bd9Sstevel@tonic-gate cmd_to_str(CMD_HELP)); 7517c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\tsyntax ('%s syntax')\n", 7527c478bd9Sstevel@tonic-gate cmd_to_str(CMD_HELP)); 7537c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\tusage ('%s usage')\n\n", 7547c478bd9Sstevel@tonic-gate cmd_to_str(CMD_HELP)); 7557c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("You may also obtain help on any " 7567c478bd9Sstevel@tonic-gate "command by typing '%s <command-name>.'\n"), 7577c478bd9Sstevel@tonic-gate cmd_to_str(CMD_HELP)); 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate if (flags & HELP_RES_SCOPE) { 7607c478bd9Sstevel@tonic-gate switch (resource_scope) { 7617c478bd9Sstevel@tonic-gate case RT_FS: 7627c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 7637c478bd9Sstevel@tonic-gate "used to configure a file-system.\n"), 7647c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 7657c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 7667c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 7677c478bd9Sstevel@tonic-gate pt_to_str(PT_DIR), gettext("<path>")); 7687c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 7697c478bd9Sstevel@tonic-gate pt_to_str(PT_SPECIAL), gettext("<path>")); 7707c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 7717c478bd9Sstevel@tonic-gate pt_to_str(PT_RAW), gettext("<raw-device>")); 7727c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 7737c478bd9Sstevel@tonic-gate pt_to_str(PT_TYPE), gettext("<file-system type>")); 7747c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s %s\n", cmd_to_str(CMD_ADD), 7757c478bd9Sstevel@tonic-gate pt_to_str(PT_OPTIONS), 7767c478bd9Sstevel@tonic-gate gettext("<file-system options>")); 777ffbafc53Scomay (void) fprintf(fp, "\t%s %s %s\n", 778ffbafc53Scomay cmd_to_str(CMD_REMOVE), pt_to_str(PT_OPTIONS), 779ffbafc53Scomay gettext("<file-system options>")); 7807c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Consult the file-system " 7817c478bd9Sstevel@tonic-gate "specific manual page, such as mount_ufs(1M), " 7827c478bd9Sstevel@tonic-gate "for\ndetails about file-system options. Note " 7837c478bd9Sstevel@tonic-gate "that any file-system options with an\nembedded " 7847c478bd9Sstevel@tonic-gate "'=' character must be enclosed in double quotes, " 7857c478bd9Sstevel@tonic-gate /*CSTYLED*/ 7867c478bd9Sstevel@tonic-gate "such as \"%s=5\".\n"), MNTOPT_RETRY); 7877c478bd9Sstevel@tonic-gate break; 7887c478bd9Sstevel@tonic-gate case RT_IPD: 7897c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 7907c478bd9Sstevel@tonic-gate "used to configure a directory\ninherited from the " 7917c478bd9Sstevel@tonic-gate "global zone into a non-global zone in read-only " 7927c478bd9Sstevel@tonic-gate "mode.\n"), rt_to_str(resource_scope)); 7937c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 7947c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 7957c478bd9Sstevel@tonic-gate pt_to_str(PT_DIR), gettext("<path>")); 7967c478bd9Sstevel@tonic-gate break; 7977c478bd9Sstevel@tonic-gate case RT_NET: 7987c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 7997c478bd9Sstevel@tonic-gate "used to configure a network interface.\n"), 8007c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 8017c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 8027c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8037c478bd9Sstevel@tonic-gate pt_to_str(PT_ADDRESS), gettext("<IP-address>")); 8047c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8057c478bd9Sstevel@tonic-gate pt_to_str(PT_PHYSICAL), gettext("<interface>")); 8067c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("See ifconfig(1M) for " 8077c478bd9Sstevel@tonic-gate "details of the <interface> string.\n")); 8087c478bd9Sstevel@tonic-gate break; 8097c478bd9Sstevel@tonic-gate case RT_DEVICE: 8107c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 8117c478bd9Sstevel@tonic-gate "used to configure a device node.\n"), 8127c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 8137c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 8147c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8157c478bd9Sstevel@tonic-gate pt_to_str(PT_MATCH), gettext("<device-path>")); 8167c478bd9Sstevel@tonic-gate break; 8177c478bd9Sstevel@tonic-gate case RT_RCTL: 8187c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 8197c478bd9Sstevel@tonic-gate "used to configure a resource control.\n"), 8207c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 8217c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 8227c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8237c478bd9Sstevel@tonic-gate pt_to_str(PT_NAME), gettext("<string>")); 8247c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n", 8257c478bd9Sstevel@tonic-gate cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE), 8267c478bd9Sstevel@tonic-gate pt_to_str(PT_PRIV), gettext("<priv-value>"), 8277c478bd9Sstevel@tonic-gate pt_to_str(PT_LIMIT), gettext("<number>"), 8287c478bd9Sstevel@tonic-gate pt_to_str(PT_ACTION), gettext("<action-value>")); 829ffbafc53Scomay (void) fprintf(fp, "\t%s %s (%s=%s,%s=%s,%s=%s)\n", 830ffbafc53Scomay cmd_to_str(CMD_REMOVE), pt_to_str(PT_VALUE), 831ffbafc53Scomay pt_to_str(PT_PRIV), gettext("<priv-value>"), 832ffbafc53Scomay pt_to_str(PT_LIMIT), gettext("<number>"), 833ffbafc53Scomay pt_to_str(PT_ACTION), gettext("<action-value>")); 8347c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s\n\t%s := privileged\n" 8357c478bd9Sstevel@tonic-gate "\t%s := none | deny\n", gettext("Where"), 8367c478bd9Sstevel@tonic-gate gettext("<priv-value>"), gettext("<action-value>")); 8377c478bd9Sstevel@tonic-gate break; 8387c478bd9Sstevel@tonic-gate case RT_ATTR: 8397c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("The '%s' resource scope is " 8407c478bd9Sstevel@tonic-gate "used to configure a generic attribute.\n"), 8417c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 8427c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("Valid commands:\n")); 8437c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8447c478bd9Sstevel@tonic-gate pt_to_str(PT_NAME), gettext("<name>")); 8457c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=boolean\n", 8467c478bd9Sstevel@tonic-gate cmd_to_str(CMD_SET), pt_to_str(PT_TYPE)); 8477c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=true | false\n", 8487c478bd9Sstevel@tonic-gate cmd_to_str(CMD_SET), pt_to_str(PT_VALUE)); 8497c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("or\n")); 8507c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=int\n", cmd_to_str(CMD_SET), 8517c478bd9Sstevel@tonic-gate pt_to_str(PT_TYPE)); 8527c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8537c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE), gettext("<integer>")); 8547c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("or\n")); 8557c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=string\n", 8567c478bd9Sstevel@tonic-gate cmd_to_str(CMD_SET), pt_to_str(PT_TYPE)); 8577c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8587c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE), gettext("<string>")); 8597c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("or\n")); 8607c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=uint\n", 8617c478bd9Sstevel@tonic-gate cmd_to_str(CMD_SET), pt_to_str(PT_TYPE)); 8627c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 8637c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE), gettext("<unsigned integer>")); 8647c478bd9Sstevel@tonic-gate break; 865fa9e4066Sahrens case RT_DATASET: 866fa9e4066Sahrens (void) fprintf(fp, gettext("The '%s' resource scope is " 867fa9e4066Sahrens "used to export ZFS datasets.\n"), 868fa9e4066Sahrens rt_to_str(resource_scope)); 869fa9e4066Sahrens (void) fprintf(fp, gettext("Valid commands:\n")); 870fa9e4066Sahrens (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), 871fa9e4066Sahrens pt_to_str(PT_NAME), gettext("<name>")); 872fa9e4066Sahrens break; 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("And from any resource scope, you " 8757c478bd9Sstevel@tonic-gate "can:\n")); 8767c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_END), 8777c478bd9Sstevel@tonic-gate gettext("(to conclude this operation)")); 8787c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_CANCEL), 8797c478bd9Sstevel@tonic-gate gettext("(to cancel this operation)")); 8807c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", cmd_to_str(CMD_EXIT), 8817c478bd9Sstevel@tonic-gate gettext("(to exit the zonecfg utility)")); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate if (flags & HELP_USAGE) { 8847c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\t%s %s\n", gettext("usage"), 8857c478bd9Sstevel@tonic-gate execname, cmd_to_str(CMD_HELP)); 8867c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s -z <zone>\t\t\t(%s)\n", 8877c478bd9Sstevel@tonic-gate execname, gettext("interactive")); 8887c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s -z <zone> <command>\n", execname); 8897c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s -z <zone> -f <command-file>\n", 8907c478bd9Sstevel@tonic-gate execname); 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate if (flags & HELP_SUBCMDS) { 8937c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n\n", gettext("Commands")); 8947c478bd9Sstevel@tonic-gate for (i = 0; i <= CMD_MAX; i++) { 8957c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s\n", helptab[i].short_usage); 8967c478bd9Sstevel@tonic-gate if (verbose) 8977c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\n\n", long_help(i)); 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate if (flags & HELP_SYNTAX) { 9017c478bd9Sstevel@tonic-gate if (!verbose) 9027c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 9037c478bd9Sstevel@tonic-gate (void) fprintf(fp, "<zone> := [A-Za-z0-9][A-Za-z0-9_.-]*\n"); 9047c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("\t(except the reserved words " 9057c478bd9Sstevel@tonic-gate "'%s' and anything starting with '%s')\n"), "global", 9067c478bd9Sstevel@tonic-gate "SUNW"); 9077c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9087c478bd9Sstevel@tonic-gate gettext("\tName must be less than %d characters.\n"), 9097c478bd9Sstevel@tonic-gate ZONENAME_MAX); 9107c478bd9Sstevel@tonic-gate if (verbose) 9117c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\n"); 9127c478bd9Sstevel@tonic-gate } 9137c478bd9Sstevel@tonic-gate if (flags & HELP_NETADDR) { 9147c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("\n<net-addr> :=")); 9157c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9167c478bd9Sstevel@tonic-gate gettext("\t<IPv4-address>[/<IPv4-prefix-length>] |\n")); 9177c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9187c478bd9Sstevel@tonic-gate gettext("\t\t<IPv6-address>/<IPv6-prefix-length> |\n")); 9197c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9207c478bd9Sstevel@tonic-gate gettext("\t\t<hostname>[/<IPv4-prefix-length>]\n")); 9217c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("See inet(3SOCKET) for IPv4 and " 9227c478bd9Sstevel@tonic-gate "IPv6 address syntax.\n")); 9237c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("<IPv4-prefix-length> := [0-32]\n")); 9247c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9257c478bd9Sstevel@tonic-gate gettext("<IPv6-prefix-length> := [0-128]\n")); 9267c478bd9Sstevel@tonic-gate (void) fprintf(fp, 9277c478bd9Sstevel@tonic-gate gettext("<hostname> := [A-Za-z0-9][A-Za-z0-9-.]*\n")); 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate if (flags & HELP_RESOURCES) { 9309e7542f4Sdp (void) fprintf(fp, "<%s> := %s | %s | %s | %s | %s | %s |\n\t" 9319e7542f4Sdp "%s\n\n", 9327c478bd9Sstevel@tonic-gate gettext("resource type"), rt_to_str(RT_FS), 9337c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD), rt_to_str(RT_NET), rt_to_str(RT_DEVICE), 9349e7542f4Sdp rt_to_str(RT_RCTL), rt_to_str(RT_ATTR), 9359e7542f4Sdp rt_to_str(RT_DATASET)); 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate if (flags & HELP_PROPS) { 9387c478bd9Sstevel@tonic-gate (void) fprintf(fp, gettext("For resource type ... there are " 9397c478bd9Sstevel@tonic-gate "property types ...:\n")); 940087719fdSdp (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 941087719fdSdp pt_to_str(PT_ZONENAME)); 9427c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 9437c478bd9Sstevel@tonic-gate pt_to_str(PT_ZONEPATH)); 944*9acbbeafSnn (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 945*9acbbeafSnn pt_to_str(PT_BRAND)); 9467c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 9477c478bd9Sstevel@tonic-gate pt_to_str(PT_AUTOBOOT)); 9483f2f09c1Sdp (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 9493f2f09c1Sdp pt_to_str(PT_BOOTARGS)); 9507c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 9517c478bd9Sstevel@tonic-gate pt_to_str(PT_POOL)); 952ffbafc53Scomay (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), 953ffbafc53Scomay pt_to_str(PT_LIMITPRIV)); 9547c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s\n", rt_to_str(RT_FS), 9557c478bd9Sstevel@tonic-gate pt_to_str(PT_DIR), pt_to_str(PT_SPECIAL), 9567c478bd9Sstevel@tonic-gate pt_to_str(PT_RAW), pt_to_str(PT_TYPE), 9577c478bd9Sstevel@tonic-gate pt_to_str(PT_OPTIONS)); 9587c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_IPD), 9597c478bd9Sstevel@tonic-gate pt_to_str(PT_DIR)); 9607c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_NET), 9617c478bd9Sstevel@tonic-gate pt_to_str(PT_ADDRESS), pt_to_str(PT_PHYSICAL)); 9627c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE), 9637c478bd9Sstevel@tonic-gate pt_to_str(PT_MATCH)); 9647c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL), 9657c478bd9Sstevel@tonic-gate pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); 9667c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR), 9677c478bd9Sstevel@tonic-gate pt_to_str(PT_NAME), pt_to_str(PT_TYPE), 9687c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE)); 969fa9e4066Sahrens (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET), 970fa9e4066Sahrens pt_to_str(PT_NAME)); 9717c478bd9Sstevel@tonic-gate } 9727c478bd9Sstevel@tonic-gate if (need_to_close) 9737c478bd9Sstevel@tonic-gate (void) pclose(fp); 9747c478bd9Sstevel@tonic-gate } 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate /* PRINTFLIKE1 */ 9777c478bd9Sstevel@tonic-gate static void 9787c478bd9Sstevel@tonic-gate zerr(const char *fmt, ...) 9797c478bd9Sstevel@tonic-gate { 9807c478bd9Sstevel@tonic-gate va_list alist; 9817c478bd9Sstevel@tonic-gate static int last_lineno; 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate /* lex_lineno has already been incremented in the lexer; compensate */ 9847c478bd9Sstevel@tonic-gate if (cmd_file_mode && lex_lineno > last_lineno) { 9857c478bd9Sstevel@tonic-gate if (strcmp(cmd_file_name, "-") == 0) 9867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("On line %d:\n"), 9877c478bd9Sstevel@tonic-gate lex_lineno - 1); 9887c478bd9Sstevel@tonic-gate else 9897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("On line %d of %s:\n"), 9907c478bd9Sstevel@tonic-gate lex_lineno - 1, cmd_file_name); 9917c478bd9Sstevel@tonic-gate last_lineno = lex_lineno; 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate va_start(alist, fmt); 9947c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, fmt, alist); 9957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 9967c478bd9Sstevel@tonic-gate va_end(alist); 9977c478bd9Sstevel@tonic-gate } 9987c478bd9Sstevel@tonic-gate 9997c478bd9Sstevel@tonic-gate static void 10007c478bd9Sstevel@tonic-gate zone_perror(char *prefix, int err, bool set_saw) 10017c478bd9Sstevel@tonic-gate { 10027c478bd9Sstevel@tonic-gate zerr("%s: %s", prefix, zonecfg_strerror(err)); 10037c478bd9Sstevel@tonic-gate if (set_saw) 10047c478bd9Sstevel@tonic-gate saw_error = TRUE; 10057c478bd9Sstevel@tonic-gate } 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate /* 10087c478bd9Sstevel@tonic-gate * zone_perror() expects a single string, but for remove and select 10097c478bd9Sstevel@tonic-gate * we have both the command and the resource type, so this wrapper 10107c478bd9Sstevel@tonic-gate * function serves the same purpose in a slightly different way. 10117c478bd9Sstevel@tonic-gate */ 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate static void 10147c478bd9Sstevel@tonic-gate z_cmd_rt_perror(int cmd_num, int res_num, int err, bool set_saw) 10157c478bd9Sstevel@tonic-gate { 10167c478bd9Sstevel@tonic-gate zerr("%s %s: %s", cmd_to_str(cmd_num), rt_to_str(res_num), 10177c478bd9Sstevel@tonic-gate zonecfg_strerror(err)); 10187c478bd9Sstevel@tonic-gate if (set_saw) 10197c478bd9Sstevel@tonic-gate saw_error = TRUE; 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate /* returns Z_OK if successful, Z_foo from <libzonecfg.h> otherwise */ 10237c478bd9Sstevel@tonic-gate static int 10247c478bd9Sstevel@tonic-gate initialize(bool handle_expected) 10257c478bd9Sstevel@tonic-gate { 10267c478bd9Sstevel@tonic-gate int err; 1027*9acbbeafSnn char brandname[MAXNAMELEN]; 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate if (zonecfg_check_handle(handle) != Z_OK) { 10307c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_handle(zone, handle)) == Z_OK) { 10317c478bd9Sstevel@tonic-gate got_handle = TRUE; 1032*9acbbeafSnn if (zonecfg_get_brand(handle, brandname, 1033*9acbbeafSnn sizeof (brandname)) != Z_OK) { 1034*9acbbeafSnn zerr("Zone %s is inconsistent: missing " 1035*9acbbeafSnn "brand attribute", zone); 1036*9acbbeafSnn exit(Z_ERR); 1037*9acbbeafSnn } 1038*9acbbeafSnn if ((brand = brand_open(brandname)) == NULL) { 1039*9acbbeafSnn zerr("Zone %s uses non-existent brand \"%s\"." 1040*9acbbeafSnn " Unable to continue", zone, brandname); 1041*9acbbeafSnn exit(Z_ERR); 1042*9acbbeafSnn } 10437c478bd9Sstevel@tonic-gate } else { 10447c478bd9Sstevel@tonic-gate zone_perror(zone, err, handle_expected || got_handle); 10457c478bd9Sstevel@tonic-gate if (err == Z_NO_ZONE && !got_handle && 10467c478bd9Sstevel@tonic-gate interactive_mode && !read_only_mode) 10477c478bd9Sstevel@tonic-gate (void) printf(gettext("Use '%s' to begin " 10487c478bd9Sstevel@tonic-gate "configuring a new zone.\n"), 10497c478bd9Sstevel@tonic-gate cmd_to_str(CMD_CREATE)); 10507c478bd9Sstevel@tonic-gate return (err); 10517c478bd9Sstevel@tonic-gate } 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate return (Z_OK); 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate 1056087719fdSdp static bool 1057087719fdSdp state_atleast(zone_state_t state) 1058087719fdSdp { 1059087719fdSdp zone_state_t state_num; 1060087719fdSdp int err; 1061087719fdSdp 1062087719fdSdp if ((err = zone_get_state(zone, &state_num)) != Z_OK) { 1063087719fdSdp /* all states are greater than "non-existent" */ 1064087719fdSdp if (err == Z_NO_ZONE) 1065087719fdSdp return (B_FALSE); 1066087719fdSdp zerr(gettext("Unexpectedly failed to determine state " 1067087719fdSdp "of zone %s: %s"), zone, zonecfg_strerror(err)); 1068087719fdSdp exit(Z_ERR); 1069087719fdSdp } 1070087719fdSdp return (state_num >= state); 1071087719fdSdp } 1072087719fdSdp 10737c478bd9Sstevel@tonic-gate /* 10747c478bd9Sstevel@tonic-gate * short_usage() is for bad syntax: getopt() issues, too many arguments, etc. 10757c478bd9Sstevel@tonic-gate */ 10767c478bd9Sstevel@tonic-gate 10777c478bd9Sstevel@tonic-gate void 10787c478bd9Sstevel@tonic-gate short_usage(int command) 10797c478bd9Sstevel@tonic-gate { 10807c478bd9Sstevel@tonic-gate /* lex_lineno has already been incremented in the lexer; compensate */ 10817c478bd9Sstevel@tonic-gate if (cmd_file_mode) { 10827c478bd9Sstevel@tonic-gate if (strcmp(cmd_file_name, "-") == 0) 10837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10847c478bd9Sstevel@tonic-gate gettext("syntax error on line %d\n"), 10857c478bd9Sstevel@tonic-gate lex_lineno - 1); 10867c478bd9Sstevel@tonic-gate else 10877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 10887c478bd9Sstevel@tonic-gate gettext("syntax error on line %d of %s\n"), 10897c478bd9Sstevel@tonic-gate lex_lineno - 1, cmd_file_name); 10907c478bd9Sstevel@tonic-gate } 10917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s:\n%s\n", gettext("usage"), 10927c478bd9Sstevel@tonic-gate helptab[command].short_usage); 10937c478bd9Sstevel@tonic-gate saw_error = TRUE; 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate /* 10977c478bd9Sstevel@tonic-gate * long_usage() is for bad semantics: e.g., wrong property type for a given 10987c478bd9Sstevel@tonic-gate * resource type. It is also used by longer_usage() below. 10997c478bd9Sstevel@tonic-gate */ 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate void 11027c478bd9Sstevel@tonic-gate long_usage(uint_t cmd_num, bool set_saw) 11037c478bd9Sstevel@tonic-gate { 11047c478bd9Sstevel@tonic-gate (void) fprintf(set_saw ? stderr : stdout, "%s:\n%s\n", gettext("usage"), 11057c478bd9Sstevel@tonic-gate helptab[cmd_num].short_usage); 11067c478bd9Sstevel@tonic-gate (void) fprintf(set_saw ? stderr : stdout, "\t%s\n", long_help(cmd_num)); 11077c478bd9Sstevel@tonic-gate if (set_saw) 11087c478bd9Sstevel@tonic-gate saw_error = TRUE; 11097c478bd9Sstevel@tonic-gate } 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate /* 11127c478bd9Sstevel@tonic-gate * longer_usage() is for 'help foo' and 'foo -?': call long_usage() and also 11137c478bd9Sstevel@tonic-gate * any extra usage() flags as appropriate for whatever command. 11147c478bd9Sstevel@tonic-gate */ 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate void 11177c478bd9Sstevel@tonic-gate longer_usage(uint_t cmd_num) 11187c478bd9Sstevel@tonic-gate { 11197c478bd9Sstevel@tonic-gate long_usage(cmd_num, FALSE); 11207c478bd9Sstevel@tonic-gate if (helptab[cmd_num].flags != 0) { 11217c478bd9Sstevel@tonic-gate (void) printf("\n"); 11227c478bd9Sstevel@tonic-gate usage(TRUE, helptab[cmd_num].flags); 11237c478bd9Sstevel@tonic-gate } 11247c478bd9Sstevel@tonic-gate } 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate /* 11277c478bd9Sstevel@tonic-gate * scope_usage() is simply used when a command is called from the wrong scope. 11287c478bd9Sstevel@tonic-gate */ 11297c478bd9Sstevel@tonic-gate 11307c478bd9Sstevel@tonic-gate static void 11317c478bd9Sstevel@tonic-gate scope_usage(uint_t cmd_num) 11327c478bd9Sstevel@tonic-gate { 11337c478bd9Sstevel@tonic-gate zerr(gettext("The %s command only makes sense in the %s scope."), 11347c478bd9Sstevel@tonic-gate cmd_to_str(cmd_num), 11357c478bd9Sstevel@tonic-gate global_scope ? gettext("resource") : gettext("global")); 11367c478bd9Sstevel@tonic-gate saw_error = TRUE; 11377c478bd9Sstevel@tonic-gate } 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate /* 11407c478bd9Sstevel@tonic-gate * On input, TRUE => yes, FALSE => no. 11417c478bd9Sstevel@tonic-gate * On return, TRUE => 1, FALSE => no, could not ask => -1. 11427c478bd9Sstevel@tonic-gate */ 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate static int 11457c478bd9Sstevel@tonic-gate ask_yesno(bool default_answer, const char *question) 11467c478bd9Sstevel@tonic-gate { 11477c478bd9Sstevel@tonic-gate char line[64]; /* should be enough to answer yes or no */ 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate if (!ok_to_prompt) { 11507c478bd9Sstevel@tonic-gate saw_error = TRUE; 11517c478bd9Sstevel@tonic-gate return (-1); 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate for (;;) { 1154087719fdSdp if (printf("%s (%s)? ", question, 1155087719fdSdp default_answer ? "[y]/n" : "y/[n]") < 0) 1156087719fdSdp return (-1); 1157087719fdSdp if (fgets(line, sizeof (line), stdin) == NULL) 1158087719fdSdp return (-1); 1159087719fdSdp 1160087719fdSdp if (line[0] == '\n') 11617c478bd9Sstevel@tonic-gate return (default_answer ? 1 : 0); 11627c478bd9Sstevel@tonic-gate if (tolower(line[0]) == 'y') 11637c478bd9Sstevel@tonic-gate return (1); 11647c478bd9Sstevel@tonic-gate if (tolower(line[0]) == 'n') 11657c478bd9Sstevel@tonic-gate return (0); 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate } 11687c478bd9Sstevel@tonic-gate 11697c478bd9Sstevel@tonic-gate /* 11707c478bd9Sstevel@tonic-gate * Prints warning if zone already exists. 11717c478bd9Sstevel@tonic-gate * In interactive mode, prompts if we should continue anyway and returns Z_OK 11727c478bd9Sstevel@tonic-gate * if so, Z_ERR if not. In non-interactive mode, exits with Z_ERR. 11737c478bd9Sstevel@tonic-gate * 11747c478bd9Sstevel@tonic-gate * Note that if a zone exists and its state is >= INSTALLED, an error message 11757c478bd9Sstevel@tonic-gate * will be printed and this function will return Z_ERR regardless of mode. 11767c478bd9Sstevel@tonic-gate */ 11777c478bd9Sstevel@tonic-gate 11787c478bd9Sstevel@tonic-gate static int 11797c478bd9Sstevel@tonic-gate check_if_zone_already_exists(bool force) 11807c478bd9Sstevel@tonic-gate { 11817c478bd9Sstevel@tonic-gate char line[ZONENAME_MAX + 128]; /* enough to ask a question */ 11827c478bd9Sstevel@tonic-gate zone_dochandle_t tmphandle; 11837c478bd9Sstevel@tonic-gate int res, answer; 11847c478bd9Sstevel@tonic-gate 11857c478bd9Sstevel@tonic-gate if ((tmphandle = zonecfg_init_handle()) == NULL) { 11867c478bd9Sstevel@tonic-gate zone_perror(execname, Z_NOMEM, TRUE); 11877c478bd9Sstevel@tonic-gate exit(Z_ERR); 11887c478bd9Sstevel@tonic-gate } 11897c478bd9Sstevel@tonic-gate res = zonecfg_get_handle(zone, tmphandle); 11907c478bd9Sstevel@tonic-gate zonecfg_fini_handle(tmphandle); 1191087719fdSdp if (res != Z_OK) 11927c478bd9Sstevel@tonic-gate return (Z_OK); 1193087719fdSdp 1194087719fdSdp if (state_atleast(ZONE_STATE_INSTALLED)) { 11957c478bd9Sstevel@tonic-gate zerr(gettext("Zone %s already installed; %s not allowed."), 11967c478bd9Sstevel@tonic-gate zone, cmd_to_str(CMD_CREATE)); 11977c478bd9Sstevel@tonic-gate return (Z_ERR); 11987c478bd9Sstevel@tonic-gate } 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate if (force) { 12017c478bd9Sstevel@tonic-gate (void) printf(gettext("Zone %s already exists; overwriting.\n"), 12027c478bd9Sstevel@tonic-gate zone); 12037c478bd9Sstevel@tonic-gate return (Z_OK); 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 12067c478bd9Sstevel@tonic-gate gettext("Zone %s already exists; %s anyway"), zone, 12077c478bd9Sstevel@tonic-gate cmd_to_str(CMD_CREATE)); 12087c478bd9Sstevel@tonic-gate if ((answer = ask_yesno(FALSE, line)) == -1) { 12097c478bd9Sstevel@tonic-gate zerr(gettext("Zone exists, input not from terminal and -F not " 12107c478bd9Sstevel@tonic-gate "specified:\n%s command ignored, exiting."), 12117c478bd9Sstevel@tonic-gate cmd_to_str(CMD_CREATE)); 12127c478bd9Sstevel@tonic-gate exit(Z_ERR); 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate return (answer == 1 ? Z_OK : Z_ERR); 12157c478bd9Sstevel@tonic-gate } 12167c478bd9Sstevel@tonic-gate 12177c478bd9Sstevel@tonic-gate static bool 12187c478bd9Sstevel@tonic-gate zone_is_read_only(int cmd_num) 12197c478bd9Sstevel@tonic-gate { 12207c478bd9Sstevel@tonic-gate if (strncmp(zone, "SUNW", 4) == 0) { 12217c478bd9Sstevel@tonic-gate zerr(gettext("%s: zones beginning with SUNW are read-only."), 12227c478bd9Sstevel@tonic-gate zone); 12237c478bd9Sstevel@tonic-gate saw_error = TRUE; 12247c478bd9Sstevel@tonic-gate return (TRUE); 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate if (read_only_mode) { 12277c478bd9Sstevel@tonic-gate zerr(gettext("%s: cannot %s in read-only mode."), zone, 12287c478bd9Sstevel@tonic-gate cmd_to_str(cmd_num)); 12297c478bd9Sstevel@tonic-gate saw_error = TRUE; 12307c478bd9Sstevel@tonic-gate return (TRUE); 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate return (FALSE); 12337c478bd9Sstevel@tonic-gate } 12347c478bd9Sstevel@tonic-gate 12357c478bd9Sstevel@tonic-gate /* 12367c478bd9Sstevel@tonic-gate * Create a new configuration. 12377c478bd9Sstevel@tonic-gate */ 12387c478bd9Sstevel@tonic-gate void 12397c478bd9Sstevel@tonic-gate create_func(cmd_t *cmd) 12407c478bd9Sstevel@tonic-gate { 12417c478bd9Sstevel@tonic-gate int err, arg; 12427c478bd9Sstevel@tonic-gate char zone_template[ZONENAME_MAX]; 1243ee519a1fSgjelinek char attach_path[MAXPATHLEN]; 12447c478bd9Sstevel@tonic-gate zone_dochandle_t tmphandle; 12457c478bd9Sstevel@tonic-gate bool force = FALSE; 1246ee519a1fSgjelinek bool attach = FALSE; 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate assert(cmd != NULL); 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate /* This is the default if no arguments are given. */ 12517c478bd9Sstevel@tonic-gate (void) strlcpy(zone_template, "SUNWdefault", sizeof (zone_template)); 12527c478bd9Sstevel@tonic-gate 12537c478bd9Sstevel@tonic-gate optind = 0; 1254*9acbbeafSnn while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:")) 1255*9acbbeafSnn != EOF) { 12567c478bd9Sstevel@tonic-gate switch (arg) { 12577c478bd9Sstevel@tonic-gate case '?': 12587c478bd9Sstevel@tonic-gate if (optopt == '?') 12597c478bd9Sstevel@tonic-gate longer_usage(CMD_CREATE); 12607c478bd9Sstevel@tonic-gate else 12617c478bd9Sstevel@tonic-gate short_usage(CMD_CREATE); 12627c478bd9Sstevel@tonic-gate return; 1263ee519a1fSgjelinek case 'a': 1264ee519a1fSgjelinek (void) strlcpy(attach_path, optarg, 1265ee519a1fSgjelinek sizeof (attach_path)); 1266ee519a1fSgjelinek attach = TRUE; 1267ee519a1fSgjelinek break; 12687c478bd9Sstevel@tonic-gate case 'b': 12697c478bd9Sstevel@tonic-gate (void) strlcpy(zone_template, "SUNWblank", 12707c478bd9Sstevel@tonic-gate sizeof (zone_template)); 12717c478bd9Sstevel@tonic-gate break; 12727c478bd9Sstevel@tonic-gate case 'F': 12737c478bd9Sstevel@tonic-gate force = TRUE; 12747c478bd9Sstevel@tonic-gate break; 12757c478bd9Sstevel@tonic-gate case 't': 12767c478bd9Sstevel@tonic-gate (void) strlcpy(zone_template, optarg, 12777c478bd9Sstevel@tonic-gate sizeof (zone_template)); 12787c478bd9Sstevel@tonic-gate break; 12797c478bd9Sstevel@tonic-gate default: 12807c478bd9Sstevel@tonic-gate short_usage(CMD_CREATE); 12817c478bd9Sstevel@tonic-gate return; 12827c478bd9Sstevel@tonic-gate } 12837c478bd9Sstevel@tonic-gate } 12847c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 12857c478bd9Sstevel@tonic-gate short_usage(CMD_CREATE); 12867c478bd9Sstevel@tonic-gate return; 12877c478bd9Sstevel@tonic-gate } 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_CREATE)) 12907c478bd9Sstevel@tonic-gate return; 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate if (check_if_zone_already_exists(force) != Z_OK) 12937c478bd9Sstevel@tonic-gate return; 12947c478bd9Sstevel@tonic-gate 12957c478bd9Sstevel@tonic-gate /* 12967c478bd9Sstevel@tonic-gate * Get a temporary handle first. If that fails, the old handle 12977c478bd9Sstevel@tonic-gate * will not be lost. Then finish whichever one we don't need, 12987c478bd9Sstevel@tonic-gate * to avoid leaks. Then get the handle for zone_template, and 12997c478bd9Sstevel@tonic-gate * set the name to zone: this "copy, rename" method is how 13007c478bd9Sstevel@tonic-gate * create -[b|t] works. 13017c478bd9Sstevel@tonic-gate */ 13027c478bd9Sstevel@tonic-gate if ((tmphandle = zonecfg_init_handle()) == NULL) { 13037c478bd9Sstevel@tonic-gate zone_perror(execname, Z_NOMEM, TRUE); 13047c478bd9Sstevel@tonic-gate exit(Z_ERR); 13057c478bd9Sstevel@tonic-gate } 1306ee519a1fSgjelinek 1307ee519a1fSgjelinek if (attach) 1308ee519a1fSgjelinek err = zonecfg_get_attach_handle(attach_path, zone, B_FALSE, 1309ee519a1fSgjelinek tmphandle); 1310ee519a1fSgjelinek else 1311ee519a1fSgjelinek err = zonecfg_get_template_handle(zone_template, zone, 1312ee519a1fSgjelinek tmphandle); 1313ee519a1fSgjelinek 1314ee519a1fSgjelinek if (err != Z_OK) { 13157c478bd9Sstevel@tonic-gate zonecfg_fini_handle(tmphandle); 1316ee519a1fSgjelinek if (attach && err == Z_NO_ZONE) 1317ee519a1fSgjelinek (void) fprintf(stderr, gettext("invalid path to " 1318ee519a1fSgjelinek "detached zone\n")); 1319ee519a1fSgjelinek else if (attach && err == Z_INVALID_DOCUMENT) 1320ee519a1fSgjelinek (void) fprintf(stderr, gettext("Cannot attach to an " 1321ee519a1fSgjelinek "earlier release of the operating system\n")); 1322ee519a1fSgjelinek else 1323ee519a1fSgjelinek zone_perror(zone_template, err, TRUE); 13247c478bd9Sstevel@tonic-gate return; 13257c478bd9Sstevel@tonic-gate } 1326087719fdSdp 1327087719fdSdp need_to_commit = TRUE; 13287c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 13297c478bd9Sstevel@tonic-gate handle = tmphandle; 1330087719fdSdp got_handle = TRUE; 13317c478bd9Sstevel@tonic-gate } 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate /* 13347c478bd9Sstevel@tonic-gate * This malloc()'s memory, which must be freed by the caller. 13357c478bd9Sstevel@tonic-gate */ 13367c478bd9Sstevel@tonic-gate static char * 13377c478bd9Sstevel@tonic-gate quoteit(char *instr) 13387c478bd9Sstevel@tonic-gate { 13397c478bd9Sstevel@tonic-gate char *outstr; 13407c478bd9Sstevel@tonic-gate size_t outstrsize = strlen(instr) + 3; /* 2 quotes + '\0' */ 13417c478bd9Sstevel@tonic-gate 13427c478bd9Sstevel@tonic-gate if ((outstr = malloc(outstrsize)) == NULL) { 13437c478bd9Sstevel@tonic-gate zone_perror(zone, Z_NOMEM, FALSE); 13447c478bd9Sstevel@tonic-gate exit(Z_ERR); 13457c478bd9Sstevel@tonic-gate } 13467c478bd9Sstevel@tonic-gate if (strchr(instr, ' ') == NULL) { 13477c478bd9Sstevel@tonic-gate (void) strlcpy(outstr, instr, outstrsize); 13487c478bd9Sstevel@tonic-gate return (outstr); 13497c478bd9Sstevel@tonic-gate } 13507c478bd9Sstevel@tonic-gate (void) snprintf(outstr, outstrsize, "\"%s\"", instr); 13517c478bd9Sstevel@tonic-gate return (outstr); 13527c478bd9Sstevel@tonic-gate } 13537c478bd9Sstevel@tonic-gate 13547c478bd9Sstevel@tonic-gate static void 13557c478bd9Sstevel@tonic-gate export_prop(FILE *of, int prop_num, char *prop_id) 13567c478bd9Sstevel@tonic-gate { 13577c478bd9Sstevel@tonic-gate char *quote_str; 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate if (strlen(prop_id) == 0) 13607c478bd9Sstevel@tonic-gate return; 13617c478bd9Sstevel@tonic-gate quote_str = quoteit(prop_id); 13627c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 13637c478bd9Sstevel@tonic-gate pt_to_str(prop_num), quote_str); 13647c478bd9Sstevel@tonic-gate free(quote_str); 13657c478bd9Sstevel@tonic-gate } 13667c478bd9Sstevel@tonic-gate 13677c478bd9Sstevel@tonic-gate void 13687c478bd9Sstevel@tonic-gate export_func(cmd_t *cmd) 13697c478bd9Sstevel@tonic-gate { 13707c478bd9Sstevel@tonic-gate struct zone_nwiftab nwiftab; 13717c478bd9Sstevel@tonic-gate struct zone_fstab fstab; 13727c478bd9Sstevel@tonic-gate struct zone_devtab devtab; 13737c478bd9Sstevel@tonic-gate struct zone_attrtab attrtab; 13747c478bd9Sstevel@tonic-gate struct zone_rctltab rctltab; 1375fa9e4066Sahrens struct zone_dstab dstab; 13767c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valptr; 13777c478bd9Sstevel@tonic-gate int err, arg; 13787c478bd9Sstevel@tonic-gate char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN]; 13793f2f09c1Sdp char bootargs[BOOTARGS_MAX]; 1380*9acbbeafSnn char brand[MAXNAMELEN]; 1381ffbafc53Scomay char *limitpriv; 13827c478bd9Sstevel@tonic-gate FILE *of; 13837c478bd9Sstevel@tonic-gate boolean_t autoboot; 13847c478bd9Sstevel@tonic-gate bool need_to_close = FALSE; 13857c478bd9Sstevel@tonic-gate 13867c478bd9Sstevel@tonic-gate assert(cmd != NULL); 13877c478bd9Sstevel@tonic-gate 13887c478bd9Sstevel@tonic-gate outfile[0] = '\0'; 13897c478bd9Sstevel@tonic-gate optind = 0; 13907c478bd9Sstevel@tonic-gate while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?f:")) != EOF) { 13917c478bd9Sstevel@tonic-gate switch (arg) { 13927c478bd9Sstevel@tonic-gate case '?': 13937c478bd9Sstevel@tonic-gate if (optopt == '?') 13947c478bd9Sstevel@tonic-gate longer_usage(CMD_EXPORT); 13957c478bd9Sstevel@tonic-gate else 13967c478bd9Sstevel@tonic-gate short_usage(CMD_EXPORT); 13977c478bd9Sstevel@tonic-gate return; 13987c478bd9Sstevel@tonic-gate case 'f': 13997c478bd9Sstevel@tonic-gate (void) strlcpy(outfile, optarg, sizeof (outfile)); 14007c478bd9Sstevel@tonic-gate break; 14017c478bd9Sstevel@tonic-gate default: 14027c478bd9Sstevel@tonic-gate short_usage(CMD_EXPORT); 14037c478bd9Sstevel@tonic-gate return; 14047c478bd9Sstevel@tonic-gate } 14057c478bd9Sstevel@tonic-gate } 14067c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 14077c478bd9Sstevel@tonic-gate short_usage(CMD_EXPORT); 14087c478bd9Sstevel@tonic-gate return; 14097c478bd9Sstevel@tonic-gate } 14107c478bd9Sstevel@tonic-gate if (strlen(outfile) == 0) { 14117c478bd9Sstevel@tonic-gate of = stdout; 14127c478bd9Sstevel@tonic-gate } else { 14137c478bd9Sstevel@tonic-gate if ((of = fopen(outfile, "w")) == NULL) { 14147c478bd9Sstevel@tonic-gate zerr(gettext("opening file %s: %s"), 14157c478bd9Sstevel@tonic-gate outfile, strerror(errno)); 14167c478bd9Sstevel@tonic-gate goto done; 14177c478bd9Sstevel@tonic-gate } 14187c478bd9Sstevel@tonic-gate setbuf(of, NULL); 14197c478bd9Sstevel@tonic-gate need_to_close = TRUE; 14207c478bd9Sstevel@tonic-gate } 14217c478bd9Sstevel@tonic-gate 14227c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 14237c478bd9Sstevel@tonic-gate goto done; 14247c478bd9Sstevel@tonic-gate 14257c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s -b\n", cmd_to_str(CMD_CREATE)); 14267c478bd9Sstevel@tonic-gate 14277c478bd9Sstevel@tonic-gate if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) == Z_OK && 14287c478bd9Sstevel@tonic-gate strlen(zonepath) > 0) 14297c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 14307c478bd9Sstevel@tonic-gate pt_to_str(PT_ZONEPATH), zonepath); 14317c478bd9Sstevel@tonic-gate 1432*9acbbeafSnn if ((zone_get_brand(zone, brand, sizeof (brand)) == Z_OK) && 1433*9acbbeafSnn (strcmp(brand, NATIVE_BRAND_NAME) != 0)) 1434*9acbbeafSnn (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 1435*9acbbeafSnn pt_to_str(PT_BRAND), brand); 1436*9acbbeafSnn 14377c478bd9Sstevel@tonic-gate if (zonecfg_get_autoboot(handle, &autoboot) == Z_OK) 14387c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 14397c478bd9Sstevel@tonic-gate pt_to_str(PT_AUTOBOOT), autoboot ? "true" : "false"); 14407c478bd9Sstevel@tonic-gate 14413f2f09c1Sdp if (zonecfg_get_bootargs(handle, bootargs, sizeof (bootargs)) == Z_OK && 14423f2f09c1Sdp strlen(bootargs) > 0) { 14433f2f09c1Sdp (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 14443f2f09c1Sdp pt_to_str(PT_BOOTARGS), bootargs); 14453f2f09c1Sdp } 14463f2f09c1Sdp 14477c478bd9Sstevel@tonic-gate if (zonecfg_get_pool(handle, pool, sizeof (pool)) == Z_OK && 14487c478bd9Sstevel@tonic-gate strlen(pool) > 0) 14497c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 14507c478bd9Sstevel@tonic-gate pt_to_str(PT_POOL), pool); 14517c478bd9Sstevel@tonic-gate 1452ffbafc53Scomay if (zonecfg_get_limitpriv(handle, &limitpriv) == Z_OK && 1453ffbafc53Scomay strlen(limitpriv) > 0) { 1454ffbafc53Scomay (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), 1455ffbafc53Scomay pt_to_str(PT_LIMITPRIV), limitpriv); 1456ffbafc53Scomay free(limitpriv); 1457ffbafc53Scomay } 1458ffbafc53Scomay 14593f2f09c1Sdp 14607c478bd9Sstevel@tonic-gate if ((err = zonecfg_setipdent(handle)) != Z_OK) { 14617c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 14627c478bd9Sstevel@tonic-gate goto done; 14637c478bd9Sstevel@tonic-gate } 14647c478bd9Sstevel@tonic-gate while (zonecfg_getipdent(handle, &fstab) == Z_OK) { 14657c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 14667c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD)); 14677c478bd9Sstevel@tonic-gate export_prop(of, PT_DIR, fstab.zone_fs_dir); 14687c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 14697c478bd9Sstevel@tonic-gate } 14707c478bd9Sstevel@tonic-gate (void) zonecfg_endipdent(handle); 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate if ((err = zonecfg_setfsent(handle)) != Z_OK) { 14737c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 14747c478bd9Sstevel@tonic-gate goto done; 14757c478bd9Sstevel@tonic-gate } 14767c478bd9Sstevel@tonic-gate while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 14777c478bd9Sstevel@tonic-gate zone_fsopt_t *optptr; 14787c478bd9Sstevel@tonic-gate 14797c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 14807c478bd9Sstevel@tonic-gate rt_to_str(RT_FS)); 14817c478bd9Sstevel@tonic-gate export_prop(of, PT_DIR, fstab.zone_fs_dir); 14827c478bd9Sstevel@tonic-gate export_prop(of, PT_SPECIAL, fstab.zone_fs_special); 14837c478bd9Sstevel@tonic-gate export_prop(of, PT_RAW, fstab.zone_fs_raw); 14847c478bd9Sstevel@tonic-gate export_prop(of, PT_TYPE, fstab.zone_fs_type); 14857c478bd9Sstevel@tonic-gate for (optptr = fstab.zone_fs_options; optptr != NULL; 14867c478bd9Sstevel@tonic-gate optptr = optptr->zone_fsopt_next) { 14877c478bd9Sstevel@tonic-gate /* 14887c478bd9Sstevel@tonic-gate * Simple property values with embedded equal signs 14897c478bd9Sstevel@tonic-gate * need to be quoted to prevent the lexer from 14907c478bd9Sstevel@tonic-gate * mis-parsing them as complex name=value pairs. 14917c478bd9Sstevel@tonic-gate */ 14927c478bd9Sstevel@tonic-gate if (strchr(optptr->zone_fsopt_opt, '=')) 14937c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s \"%s\"\n", 14947c478bd9Sstevel@tonic-gate cmd_to_str(CMD_ADD), 14957c478bd9Sstevel@tonic-gate pt_to_str(PT_OPTIONS), 14967c478bd9Sstevel@tonic-gate optptr->zone_fsopt_opt); 14977c478bd9Sstevel@tonic-gate else 14987c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s %s\n", 14997c478bd9Sstevel@tonic-gate cmd_to_str(CMD_ADD), 15007c478bd9Sstevel@tonic-gate pt_to_str(PT_OPTIONS), 15017c478bd9Sstevel@tonic-gate optptr->zone_fsopt_opt); 15027c478bd9Sstevel@tonic-gate } 15037c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 15047c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(fstab.zone_fs_options); 15057c478bd9Sstevel@tonic-gate } 15067c478bd9Sstevel@tonic-gate (void) zonecfg_endfsent(handle); 15077c478bd9Sstevel@tonic-gate 15087c478bd9Sstevel@tonic-gate if ((err = zonecfg_setnwifent(handle)) != Z_OK) { 15097c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 15107c478bd9Sstevel@tonic-gate goto done; 15117c478bd9Sstevel@tonic-gate } 15127c478bd9Sstevel@tonic-gate while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) { 15137c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 15147c478bd9Sstevel@tonic-gate rt_to_str(RT_NET)); 15157c478bd9Sstevel@tonic-gate export_prop(of, PT_ADDRESS, nwiftab.zone_nwif_address); 15167c478bd9Sstevel@tonic-gate export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical); 15177c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 15187c478bd9Sstevel@tonic-gate } 15197c478bd9Sstevel@tonic-gate (void) zonecfg_endnwifent(handle); 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate if ((err = zonecfg_setdevent(handle)) != Z_OK) { 15227c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 15237c478bd9Sstevel@tonic-gate goto done; 15247c478bd9Sstevel@tonic-gate } 15257c478bd9Sstevel@tonic-gate while (zonecfg_getdevent(handle, &devtab) == Z_OK) { 15267c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 15277c478bd9Sstevel@tonic-gate rt_to_str(RT_DEVICE)); 15287c478bd9Sstevel@tonic-gate export_prop(of, PT_MATCH, devtab.zone_dev_match); 15297c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 15307c478bd9Sstevel@tonic-gate } 15317c478bd9Sstevel@tonic-gate (void) zonecfg_enddevent(handle); 15327c478bd9Sstevel@tonic-gate 15337c478bd9Sstevel@tonic-gate if ((err = zonecfg_setrctlent(handle)) != Z_OK) { 15347c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 15357c478bd9Sstevel@tonic-gate goto done; 15367c478bd9Sstevel@tonic-gate } 15377c478bd9Sstevel@tonic-gate while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { 15387c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s rctl\n", cmd_to_str(CMD_ADD)); 15397c478bd9Sstevel@tonic-gate export_prop(of, PT_NAME, rctltab.zone_rctl_name); 15407c478bd9Sstevel@tonic-gate for (valptr = rctltab.zone_rctl_valptr; valptr != NULL; 15417c478bd9Sstevel@tonic-gate valptr = valptr->zone_rctlval_next) { 15427c478bd9Sstevel@tonic-gate fprintf(of, "%s %s (%s=%s,%s=%s,%s=%s)\n", 15437c478bd9Sstevel@tonic-gate cmd_to_str(CMD_ADD), pt_to_str(PT_VALUE), 15447c478bd9Sstevel@tonic-gate pt_to_str(PT_PRIV), valptr->zone_rctlval_priv, 15457c478bd9Sstevel@tonic-gate pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit, 15467c478bd9Sstevel@tonic-gate pt_to_str(PT_ACTION), valptr->zone_rctlval_action); 15477c478bd9Sstevel@tonic-gate } 15487c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 15497c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 15507c478bd9Sstevel@tonic-gate } 15517c478bd9Sstevel@tonic-gate (void) zonecfg_endrctlent(handle); 15527c478bd9Sstevel@tonic-gate 15537c478bd9Sstevel@tonic-gate if ((err = zonecfg_setattrent(handle)) != Z_OK) { 15547c478bd9Sstevel@tonic-gate zone_perror(zone, err, FALSE); 15557c478bd9Sstevel@tonic-gate goto done; 15567c478bd9Sstevel@tonic-gate } 15577c478bd9Sstevel@tonic-gate while (zonecfg_getattrent(handle, &attrtab) == Z_OK) { 15587c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 15597c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR)); 15607c478bd9Sstevel@tonic-gate export_prop(of, PT_NAME, attrtab.zone_attr_name); 15617c478bd9Sstevel@tonic-gate export_prop(of, PT_TYPE, attrtab.zone_attr_type); 15627c478bd9Sstevel@tonic-gate export_prop(of, PT_VALUE, attrtab.zone_attr_value); 15637c478bd9Sstevel@tonic-gate (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 15647c478bd9Sstevel@tonic-gate } 15657c478bd9Sstevel@tonic-gate (void) zonecfg_endattrent(handle); 15667c478bd9Sstevel@tonic-gate 1567fa9e4066Sahrens if ((err = zonecfg_setdsent(handle)) != Z_OK) { 1568fa9e4066Sahrens zone_perror(zone, err, FALSE); 1569fa9e4066Sahrens goto done; 1570fa9e4066Sahrens } 1571fa9e4066Sahrens while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 1572fa9e4066Sahrens (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), 1573fa9e4066Sahrens rt_to_str(RT_DATASET)); 1574fa9e4066Sahrens export_prop(of, PT_NAME, dstab.zone_dataset_name); 1575fa9e4066Sahrens (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); 1576fa9e4066Sahrens } 1577fa9e4066Sahrens (void) zonecfg_enddsent(handle); 1578fa9e4066Sahrens 15797c478bd9Sstevel@tonic-gate done: 15807c478bd9Sstevel@tonic-gate if (need_to_close) 15817c478bd9Sstevel@tonic-gate (void) fclose(of); 15827c478bd9Sstevel@tonic-gate } 15837c478bd9Sstevel@tonic-gate 15847c478bd9Sstevel@tonic-gate void 15857c478bd9Sstevel@tonic-gate exit_func(cmd_t *cmd) 15867c478bd9Sstevel@tonic-gate { 15877c478bd9Sstevel@tonic-gate int arg, answer; 15887c478bd9Sstevel@tonic-gate 15897c478bd9Sstevel@tonic-gate optind = 0; 15907c478bd9Sstevel@tonic-gate while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) { 15917c478bd9Sstevel@tonic-gate switch (arg) { 15927c478bd9Sstevel@tonic-gate case '?': 15937c478bd9Sstevel@tonic-gate longer_usage(CMD_EXIT); 15947c478bd9Sstevel@tonic-gate return; 15957c478bd9Sstevel@tonic-gate case 'F': 15967c478bd9Sstevel@tonic-gate force_exit = TRUE; 15977c478bd9Sstevel@tonic-gate break; 15987c478bd9Sstevel@tonic-gate default: 15997c478bd9Sstevel@tonic-gate short_usage(CMD_EXIT); 16007c478bd9Sstevel@tonic-gate return; 16017c478bd9Sstevel@tonic-gate } 16027c478bd9Sstevel@tonic-gate } 16037c478bd9Sstevel@tonic-gate if (optind < cmd->cmd_argc) { 16047c478bd9Sstevel@tonic-gate short_usage(CMD_EXIT); 16057c478bd9Sstevel@tonic-gate return; 16067c478bd9Sstevel@tonic-gate } 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate if (global_scope || force_exit) { 16097c478bd9Sstevel@tonic-gate time_to_exit = TRUE; 16107c478bd9Sstevel@tonic-gate return; 16117c478bd9Sstevel@tonic-gate } 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate answer = ask_yesno(FALSE, "Resource incomplete; really quit"); 16147c478bd9Sstevel@tonic-gate if (answer == -1) { 16157c478bd9Sstevel@tonic-gate zerr(gettext("Resource incomplete, input " 16167c478bd9Sstevel@tonic-gate "not from terminal and -F not specified:\n%s command " 16177c478bd9Sstevel@tonic-gate "ignored, but exiting anyway."), cmd_to_str(CMD_EXIT)); 16187c478bd9Sstevel@tonic-gate exit(Z_ERR); 16197c478bd9Sstevel@tonic-gate } else if (answer == 1) { 16207c478bd9Sstevel@tonic-gate time_to_exit = TRUE; 16217c478bd9Sstevel@tonic-gate } 16227c478bd9Sstevel@tonic-gate /* (answer == 0) => just return */ 16237c478bd9Sstevel@tonic-gate } 16247c478bd9Sstevel@tonic-gate 16257c478bd9Sstevel@tonic-gate static int 16267c478bd9Sstevel@tonic-gate validate_zonepath_syntax(char *path) 16277c478bd9Sstevel@tonic-gate { 16287c478bd9Sstevel@tonic-gate if (path[0] != '/') { 16297c478bd9Sstevel@tonic-gate zerr(gettext("%s is not an absolute path."), path); 16307c478bd9Sstevel@tonic-gate return (Z_ERR); 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate if (strcmp(path, "/") == 0) { 16337c478bd9Sstevel@tonic-gate zerr(gettext("/ is not allowed as a %s."), 16347c478bd9Sstevel@tonic-gate pt_to_str(PT_ZONEPATH)); 16357c478bd9Sstevel@tonic-gate return (Z_ERR); 16367c478bd9Sstevel@tonic-gate } 16377c478bd9Sstevel@tonic-gate return (Z_OK); 16387c478bd9Sstevel@tonic-gate } 16397c478bd9Sstevel@tonic-gate 16407c478bd9Sstevel@tonic-gate static void 16417c478bd9Sstevel@tonic-gate add_resource(cmd_t *cmd) 16427c478bd9Sstevel@tonic-gate { 16437c478bd9Sstevel@tonic-gate int type; 16447c478bd9Sstevel@tonic-gate 16457c478bd9Sstevel@tonic-gate if ((type = cmd->cmd_res_type) == RT_UNKNOWN) { 16467c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 16477c478bd9Sstevel@tonic-gate goto bad; 16487c478bd9Sstevel@tonic-gate } 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate switch (type) { 16517c478bd9Sstevel@tonic-gate case RT_FS: 16527c478bd9Sstevel@tonic-gate bzero(&in_progress_fstab, sizeof (in_progress_fstab)); 16537c478bd9Sstevel@tonic-gate return; 16547c478bd9Sstevel@tonic-gate case RT_IPD: 1655087719fdSdp if (state_atleast(ZONE_STATE_INSTALLED)) { 16567c478bd9Sstevel@tonic-gate zerr(gettext("Zone %s already installed; %s %s not " 16577c478bd9Sstevel@tonic-gate "allowed."), zone, cmd_to_str(CMD_ADD), 16587c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD)); 16597c478bd9Sstevel@tonic-gate goto bad; 16607c478bd9Sstevel@tonic-gate } 16617c478bd9Sstevel@tonic-gate bzero(&in_progress_ipdtab, sizeof (in_progress_ipdtab)); 16627c478bd9Sstevel@tonic-gate return; 16637c478bd9Sstevel@tonic-gate case RT_NET: 16647c478bd9Sstevel@tonic-gate bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab)); 16657c478bd9Sstevel@tonic-gate return; 16667c478bd9Sstevel@tonic-gate case RT_DEVICE: 16677c478bd9Sstevel@tonic-gate bzero(&in_progress_devtab, sizeof (in_progress_devtab)); 16687c478bd9Sstevel@tonic-gate return; 16697c478bd9Sstevel@tonic-gate case RT_RCTL: 16707c478bd9Sstevel@tonic-gate bzero(&in_progress_rctltab, sizeof (in_progress_rctltab)); 16717c478bd9Sstevel@tonic-gate return; 16727c478bd9Sstevel@tonic-gate case RT_ATTR: 16737c478bd9Sstevel@tonic-gate bzero(&in_progress_attrtab, sizeof (in_progress_attrtab)); 16747c478bd9Sstevel@tonic-gate return; 1675fa9e4066Sahrens case RT_DATASET: 1676fa9e4066Sahrens bzero(&in_progress_dstab, sizeof (in_progress_dstab)); 1677fa9e4066Sahrens return; 16787c478bd9Sstevel@tonic-gate default: 16797c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, TRUE); 16807c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 16817c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 16827c478bd9Sstevel@tonic-gate } 16837c478bd9Sstevel@tonic-gate bad: 16847c478bd9Sstevel@tonic-gate global_scope = TRUE; 16857c478bd9Sstevel@tonic-gate end_op = -1; 16867c478bd9Sstevel@tonic-gate } 16877c478bd9Sstevel@tonic-gate 16887c478bd9Sstevel@tonic-gate static void 16897c478bd9Sstevel@tonic-gate do_complex_rctl_val(complex_property_ptr_t cp) 16907c478bd9Sstevel@tonic-gate { 16917c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *rctlvaltab; 16927c478bd9Sstevel@tonic-gate complex_property_ptr_t cx; 16937c478bd9Sstevel@tonic-gate bool seen_priv = FALSE, seen_limit = FALSE, seen_action = FALSE; 16947c478bd9Sstevel@tonic-gate rctlblk_t *rctlblk; 16957c478bd9Sstevel@tonic-gate int err; 16967c478bd9Sstevel@tonic-gate 16977c478bd9Sstevel@tonic-gate if ((rctlvaltab = alloc_rctlvaltab()) == NULL) { 16987c478bd9Sstevel@tonic-gate zone_perror(zone, Z_NOMEM, TRUE); 16997c478bd9Sstevel@tonic-gate exit(Z_ERR); 17007c478bd9Sstevel@tonic-gate } 17017c478bd9Sstevel@tonic-gate for (cx = cp; cx != NULL; cx = cx->cp_next) { 17027c478bd9Sstevel@tonic-gate switch (cx->cp_type) { 17037c478bd9Sstevel@tonic-gate case PT_PRIV: 17047c478bd9Sstevel@tonic-gate if (seen_priv) { 17057c478bd9Sstevel@tonic-gate zerr(gettext("%s already specified"), 17067c478bd9Sstevel@tonic-gate pt_to_str(PT_PRIV)); 17077c478bd9Sstevel@tonic-gate goto bad; 17087c478bd9Sstevel@tonic-gate } 17097c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_priv, 17107c478bd9Sstevel@tonic-gate cx->cp_value, 17117c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_priv)); 17127c478bd9Sstevel@tonic-gate seen_priv = TRUE; 17137c478bd9Sstevel@tonic-gate break; 17147c478bd9Sstevel@tonic-gate case PT_LIMIT: 17157c478bd9Sstevel@tonic-gate if (seen_limit) { 17167c478bd9Sstevel@tonic-gate zerr(gettext("%s already specified"), 17177c478bd9Sstevel@tonic-gate pt_to_str(PT_LIMIT)); 17187c478bd9Sstevel@tonic-gate goto bad; 17197c478bd9Sstevel@tonic-gate } 17207c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_limit, 17217c478bd9Sstevel@tonic-gate cx->cp_value, 17227c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_limit)); 17237c478bd9Sstevel@tonic-gate seen_limit = TRUE; 17247c478bd9Sstevel@tonic-gate break; 17257c478bd9Sstevel@tonic-gate case PT_ACTION: 17267c478bd9Sstevel@tonic-gate if (seen_action) { 17277c478bd9Sstevel@tonic-gate zerr(gettext("%s already specified"), 17287c478bd9Sstevel@tonic-gate pt_to_str(PT_ACTION)); 17297c478bd9Sstevel@tonic-gate goto bad; 17307c478bd9Sstevel@tonic-gate } 17317c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_action, 17327c478bd9Sstevel@tonic-gate cx->cp_value, 17337c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_action)); 17347c478bd9Sstevel@tonic-gate seen_action = TRUE; 17357c478bd9Sstevel@tonic-gate break; 17367c478bd9Sstevel@tonic-gate default: 17377c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(PT_VALUE), 17387c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 17397c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 17407c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 17417c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctlvaltab); 17427c478bd9Sstevel@tonic-gate return; 17437c478bd9Sstevel@tonic-gate } 17447c478bd9Sstevel@tonic-gate } 17457c478bd9Sstevel@tonic-gate if (!seen_priv) 17467c478bd9Sstevel@tonic-gate zerr(gettext("%s not specified"), pt_to_str(PT_PRIV)); 17477c478bd9Sstevel@tonic-gate if (!seen_limit) 17487c478bd9Sstevel@tonic-gate zerr(gettext("%s not specified"), pt_to_str(PT_LIMIT)); 17497c478bd9Sstevel@tonic-gate if (!seen_action) 17507c478bd9Sstevel@tonic-gate zerr(gettext("%s not specified"), pt_to_str(PT_ACTION)); 17517c478bd9Sstevel@tonic-gate if (!seen_priv || !seen_limit || !seen_action) 17527c478bd9Sstevel@tonic-gate goto bad; 17537c478bd9Sstevel@tonic-gate rctlvaltab->zone_rctlval_next = NULL; 17547c478bd9Sstevel@tonic-gate rctlblk = alloca(rctlblk_size()); 17557c478bd9Sstevel@tonic-gate /* 17567c478bd9Sstevel@tonic-gate * Make sure the rctl value looks roughly correct; we won't know if 17577c478bd9Sstevel@tonic-gate * it's truly OK until we verify the configuration on the target 17587c478bd9Sstevel@tonic-gate * system. 17597c478bd9Sstevel@tonic-gate */ 17607c478bd9Sstevel@tonic-gate if (zonecfg_construct_rctlblk(rctlvaltab, rctlblk) != Z_OK || 17617c478bd9Sstevel@tonic-gate !zonecfg_valid_rctlblk(rctlblk)) { 17627c478bd9Sstevel@tonic-gate zerr(gettext("Invalid %s %s specification"), rt_to_str(RT_RCTL), 17637c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE)); 17647c478bd9Sstevel@tonic-gate goto bad; 17657c478bd9Sstevel@tonic-gate } 17667c478bd9Sstevel@tonic-gate err = zonecfg_add_rctl_value(&in_progress_rctltab, rctlvaltab); 17677c478bd9Sstevel@tonic-gate if (err != Z_OK) 17687c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(PT_VALUE), err, TRUE); 17697c478bd9Sstevel@tonic-gate return; 17707c478bd9Sstevel@tonic-gate 17717c478bd9Sstevel@tonic-gate bad: 17727c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctlvaltab); 17737c478bd9Sstevel@tonic-gate } 17747c478bd9Sstevel@tonic-gate 17757c478bd9Sstevel@tonic-gate static void 17767c478bd9Sstevel@tonic-gate add_property(cmd_t *cmd) 17777c478bd9Sstevel@tonic-gate { 17787c478bd9Sstevel@tonic-gate char *prop_id; 17797c478bd9Sstevel@tonic-gate int err, res_type, prop_type; 17807c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 17817c478bd9Sstevel@tonic-gate list_property_ptr_t l; 17827c478bd9Sstevel@tonic-gate 17837c478bd9Sstevel@tonic-gate res_type = resource_scope; 17847c478bd9Sstevel@tonic-gate prop_type = cmd->cmd_prop_name[0]; 17857c478bd9Sstevel@tonic-gate if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) { 17867c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 17877c478bd9Sstevel@tonic-gate return; 17887c478bd9Sstevel@tonic-gate } 17897c478bd9Sstevel@tonic-gate 17907c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs != 1) { 17917c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 17927c478bd9Sstevel@tonic-gate return; 17937c478bd9Sstevel@tonic-gate } 17947c478bd9Sstevel@tonic-gate 17957c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 17967c478bd9Sstevel@tonic-gate return; 17977c478bd9Sstevel@tonic-gate 17987c478bd9Sstevel@tonic-gate switch (res_type) { 17997c478bd9Sstevel@tonic-gate case RT_FS: 18007c478bd9Sstevel@tonic-gate if (prop_type != PT_OPTIONS) { 18017c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 18027c478bd9Sstevel@tonic-gate TRUE); 18037c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 18047c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 18057c478bd9Sstevel@tonic-gate return; 18067c478bd9Sstevel@tonic-gate } 18077c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[0]; 18087c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE && 18097c478bd9Sstevel@tonic-gate pp->pv_type != PROP_VAL_LIST) { 18107c478bd9Sstevel@tonic-gate zerr(gettext("A %s or %s value was expected here."), 18117c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_SIMPLE), 18127c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_LIST)); 18137c478bd9Sstevel@tonic-gate saw_error = TRUE; 18147c478bd9Sstevel@tonic-gate return; 18157c478bd9Sstevel@tonic-gate } 18167c478bd9Sstevel@tonic-gate if (pp->pv_type == PROP_VAL_SIMPLE) { 18177c478bd9Sstevel@tonic-gate if (pp->pv_simple == NULL) { 18187c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 18197c478bd9Sstevel@tonic-gate return; 18207c478bd9Sstevel@tonic-gate } 18217c478bd9Sstevel@tonic-gate prop_id = pp->pv_simple; 18227c478bd9Sstevel@tonic-gate err = zonecfg_add_fs_option(&in_progress_fstab, 18237c478bd9Sstevel@tonic-gate prop_id); 18247c478bd9Sstevel@tonic-gate if (err != Z_OK) 18257c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), err, TRUE); 18267c478bd9Sstevel@tonic-gate } else { 18277c478bd9Sstevel@tonic-gate list_property_ptr_t list; 18287c478bd9Sstevel@tonic-gate 18297c478bd9Sstevel@tonic-gate for (list = pp->pv_list; list != NULL; 18307c478bd9Sstevel@tonic-gate list = list->lp_next) { 18317c478bd9Sstevel@tonic-gate prop_id = list->lp_simple; 18327c478bd9Sstevel@tonic-gate if (prop_id == NULL) 18337c478bd9Sstevel@tonic-gate break; 18347c478bd9Sstevel@tonic-gate err = zonecfg_add_fs_option( 18357c478bd9Sstevel@tonic-gate &in_progress_fstab, prop_id); 18367c478bd9Sstevel@tonic-gate if (err != Z_OK) 18377c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), err, 18387c478bd9Sstevel@tonic-gate TRUE); 18397c478bd9Sstevel@tonic-gate } 18407c478bd9Sstevel@tonic-gate } 18417c478bd9Sstevel@tonic-gate return; 18427c478bd9Sstevel@tonic-gate case RT_RCTL: 18437c478bd9Sstevel@tonic-gate if (prop_type != PT_VALUE) { 18447c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 18457c478bd9Sstevel@tonic-gate TRUE); 18467c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 18477c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 18487c478bd9Sstevel@tonic-gate return; 18497c478bd9Sstevel@tonic-gate } 18507c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[0]; 18517c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_COMPLEX && 18527c478bd9Sstevel@tonic-gate pp->pv_type != PROP_VAL_LIST) { 18537c478bd9Sstevel@tonic-gate zerr(gettext("A %s or %s value was expected here."), 18547c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_COMPLEX), 18557c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_LIST)); 18567c478bd9Sstevel@tonic-gate saw_error = TRUE; 18577c478bd9Sstevel@tonic-gate return; 18587c478bd9Sstevel@tonic-gate } 18597c478bd9Sstevel@tonic-gate if (pp->pv_type == PROP_VAL_COMPLEX) { 18607c478bd9Sstevel@tonic-gate do_complex_rctl_val(pp->pv_complex); 18617c478bd9Sstevel@tonic-gate return; 18627c478bd9Sstevel@tonic-gate } 18637c478bd9Sstevel@tonic-gate for (l = pp->pv_list; l != NULL; l = l->lp_next) 18647c478bd9Sstevel@tonic-gate do_complex_rctl_val(l->lp_complex); 18657c478bd9Sstevel@tonic-gate return; 18667c478bd9Sstevel@tonic-gate default: 18677c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, TRUE); 18687c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 18697c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 18707c478bd9Sstevel@tonic-gate return; 18717c478bd9Sstevel@tonic-gate } 18727c478bd9Sstevel@tonic-gate } 18737c478bd9Sstevel@tonic-gate 18747c478bd9Sstevel@tonic-gate void 18757c478bd9Sstevel@tonic-gate add_func(cmd_t *cmd) 18767c478bd9Sstevel@tonic-gate { 18777c478bd9Sstevel@tonic-gate int arg; 18787c478bd9Sstevel@tonic-gate 18797c478bd9Sstevel@tonic-gate assert(cmd != NULL); 18807c478bd9Sstevel@tonic-gate 18817c478bd9Sstevel@tonic-gate optind = 0; 18827c478bd9Sstevel@tonic-gate if ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) { 18837c478bd9Sstevel@tonic-gate switch (arg) { 18847c478bd9Sstevel@tonic-gate case '?': 18857c478bd9Sstevel@tonic-gate longer_usage(CMD_ADD); 18867c478bd9Sstevel@tonic-gate return; 18877c478bd9Sstevel@tonic-gate default: 18887c478bd9Sstevel@tonic-gate short_usage(CMD_ADD); 18897c478bd9Sstevel@tonic-gate return; 18907c478bd9Sstevel@tonic-gate } 18917c478bd9Sstevel@tonic-gate } 18927c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 18937c478bd9Sstevel@tonic-gate short_usage(CMD_ADD); 18947c478bd9Sstevel@tonic-gate return; 18957c478bd9Sstevel@tonic-gate } 18967c478bd9Sstevel@tonic-gate 18977c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_ADD)) 18987c478bd9Sstevel@tonic-gate return; 18997c478bd9Sstevel@tonic-gate 19007c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 19017c478bd9Sstevel@tonic-gate return; 19027c478bd9Sstevel@tonic-gate if (global_scope) { 19037c478bd9Sstevel@tonic-gate global_scope = FALSE; 19047c478bd9Sstevel@tonic-gate resource_scope = cmd->cmd_res_type; 19057c478bd9Sstevel@tonic-gate end_op = CMD_ADD; 19067c478bd9Sstevel@tonic-gate add_resource(cmd); 19077c478bd9Sstevel@tonic-gate } else 19087c478bd9Sstevel@tonic-gate add_property(cmd); 19097c478bd9Sstevel@tonic-gate } 19107c478bd9Sstevel@tonic-gate 1911087719fdSdp /* 1912087719fdSdp * This routine has an unusual implementation, because it tries very 1913087719fdSdp * hard to succeed in the face of a variety of failure modes. 1914087719fdSdp * The most common and most vexing occurs when the index file and 1915087719fdSdp * the /etc/zones/<zonename.xml> file are not both present. In 1916087719fdSdp * this case, delete must eradicate as much of the zone state as is left 1917087719fdSdp * so that the user can later create a new zone with the same name. 1918087719fdSdp */ 19197c478bd9Sstevel@tonic-gate void 19207c478bd9Sstevel@tonic-gate delete_func(cmd_t *cmd) 19217c478bd9Sstevel@tonic-gate { 19227c478bd9Sstevel@tonic-gate int err, arg, answer; 19237c478bd9Sstevel@tonic-gate char line[ZONENAME_MAX + 128]; /* enough to ask a question */ 19247c478bd9Sstevel@tonic-gate bool force = FALSE; 19257c478bd9Sstevel@tonic-gate 19267c478bd9Sstevel@tonic-gate optind = 0; 19277c478bd9Sstevel@tonic-gate while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) { 19287c478bd9Sstevel@tonic-gate switch (arg) { 19297c478bd9Sstevel@tonic-gate case '?': 19307c478bd9Sstevel@tonic-gate longer_usage(CMD_DELETE); 19317c478bd9Sstevel@tonic-gate return; 19327c478bd9Sstevel@tonic-gate case 'F': 19337c478bd9Sstevel@tonic-gate force = TRUE; 19347c478bd9Sstevel@tonic-gate break; 19357c478bd9Sstevel@tonic-gate default: 19367c478bd9Sstevel@tonic-gate short_usage(CMD_DELETE); 19377c478bd9Sstevel@tonic-gate return; 19387c478bd9Sstevel@tonic-gate } 19397c478bd9Sstevel@tonic-gate } 19407c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 19417c478bd9Sstevel@tonic-gate short_usage(CMD_DELETE); 19427c478bd9Sstevel@tonic-gate return; 19437c478bd9Sstevel@tonic-gate } 19447c478bd9Sstevel@tonic-gate 19457c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_DELETE)) 19467c478bd9Sstevel@tonic-gate return; 19477c478bd9Sstevel@tonic-gate 19487c478bd9Sstevel@tonic-gate if (!force) { 1949087719fdSdp /* 1950087719fdSdp * Initialize sets up the global called "handle" and warns the 1951087719fdSdp * user if the zone is not configured. In force mode, we don't 1952087719fdSdp * trust that evaluation, and hence skip it. (We don't need the 1953087719fdSdp * handle to be loaded anyway, since zonecfg_destroy is done by 1954087719fdSdp * zonename). However, we also have to take care to emulate the 1955087719fdSdp * messages spit out by initialize; see below. 1956087719fdSdp */ 1957087719fdSdp if (initialize(TRUE) != Z_OK) 1958087719fdSdp return; 1959087719fdSdp 19607c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 19617c478bd9Sstevel@tonic-gate gettext("Are you sure you want to delete zone %s"), zone); 19627c478bd9Sstevel@tonic-gate if ((answer = ask_yesno(FALSE, line)) == -1) { 1963087719fdSdp zerr(gettext("Input not from terminal and -F not " 1964087719fdSdp "specified:\n%s command ignored, exiting."), 1965087719fdSdp cmd_to_str(CMD_DELETE)); 19667c478bd9Sstevel@tonic-gate exit(Z_ERR); 19677c478bd9Sstevel@tonic-gate } 19687c478bd9Sstevel@tonic-gate if (answer != 1) 19697c478bd9Sstevel@tonic-gate return; 19707c478bd9Sstevel@tonic-gate } 19717c478bd9Sstevel@tonic-gate 1972087719fdSdp if ((err = zonecfg_destroy(zone, force)) != Z_OK) { 1973087719fdSdp if ((err == Z_BAD_ZONE_STATE) && !force) { 1974087719fdSdp zerr(gettext("Zone %s not in %s state; %s not " 1975087719fdSdp "allowed. Use -F to force %s."), 1976087719fdSdp zone, zone_state_str(ZONE_STATE_CONFIGURED), 1977087719fdSdp cmd_to_str(CMD_DELETE), cmd_to_str(CMD_DELETE)); 1978087719fdSdp } else { 1979087719fdSdp zone_perror(zone, err, TRUE); 1980087719fdSdp } 19817c478bd9Sstevel@tonic-gate } 19827c478bd9Sstevel@tonic-gate need_to_commit = FALSE; 1983087719fdSdp 1984087719fdSdp /* 1985087719fdSdp * Emulate initialize's messaging; if there wasn't a valid handle to 1986087719fdSdp * begin with, then user had typed delete (or delete -F) multiple 1987087719fdSdp * times. So we emit a message. 1988087719fdSdp * 1989087719fdSdp * We only do this in the 'force' case because normally, initialize() 1990087719fdSdp * takes care of this for us. 1991087719fdSdp */ 1992087719fdSdp if (force && zonecfg_check_handle(handle) != Z_OK && interactive_mode) 1993087719fdSdp (void) printf(gettext("Use '%s' to begin " 1994087719fdSdp "configuring a new zone.\n"), cmd_to_str(CMD_CREATE)); 19957c478bd9Sstevel@tonic-gate 19967c478bd9Sstevel@tonic-gate /* 19977c478bd9Sstevel@tonic-gate * Time for a new handle: finish the old one off first 19987c478bd9Sstevel@tonic-gate * then get a new one properly to avoid leaks. 19997c478bd9Sstevel@tonic-gate */ 2000087719fdSdp if (got_handle) { 2001087719fdSdp zonecfg_fini_handle(handle); 2002087719fdSdp if ((handle = zonecfg_init_handle()) == NULL) { 2003087719fdSdp zone_perror(execname, Z_NOMEM, TRUE); 2004087719fdSdp exit(Z_ERR); 2005087719fdSdp } 2006087719fdSdp if ((err = zonecfg_get_handle(zone, handle)) != Z_OK) { 2007087719fdSdp /* If there was no zone before, that's OK */ 2008087719fdSdp if (err != Z_NO_ZONE) 2009087719fdSdp zone_perror(zone, err, TRUE); 2010087719fdSdp got_handle = FALSE; 2011087719fdSdp } 20127c478bd9Sstevel@tonic-gate } 20137c478bd9Sstevel@tonic-gate } 20147c478bd9Sstevel@tonic-gate 20157c478bd9Sstevel@tonic-gate static int 20167c478bd9Sstevel@tonic-gate fill_in_fstab(cmd_t *cmd, struct zone_fstab *fstab, bool fill_in_only) 20177c478bd9Sstevel@tonic-gate { 20187c478bd9Sstevel@tonic-gate int err, i; 20197c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 20207c478bd9Sstevel@tonic-gate 20217c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 20227c478bd9Sstevel@tonic-gate return (err); 20237c478bd9Sstevel@tonic-gate 2024e193d1e6Svp bzero(fstab, sizeof (*fstab)); 20257c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 20267c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 20277c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 20287c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 20297c478bd9Sstevel@tonic-gate saw_error = TRUE; 20307c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 20317c478bd9Sstevel@tonic-gate } 20327c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 20337c478bd9Sstevel@tonic-gate case PT_DIR: 20347c478bd9Sstevel@tonic-gate (void) strlcpy(fstab->zone_fs_dir, pp->pv_simple, 20357c478bd9Sstevel@tonic-gate sizeof (fstab->zone_fs_dir)); 20367c478bd9Sstevel@tonic-gate break; 20377c478bd9Sstevel@tonic-gate case PT_SPECIAL: 20387c478bd9Sstevel@tonic-gate (void) strlcpy(fstab->zone_fs_special, pp->pv_simple, 20397c478bd9Sstevel@tonic-gate sizeof (fstab->zone_fs_special)); 20407c478bd9Sstevel@tonic-gate break; 20417c478bd9Sstevel@tonic-gate case PT_RAW: 20427c478bd9Sstevel@tonic-gate (void) strlcpy(fstab->zone_fs_raw, pp->pv_simple, 20437c478bd9Sstevel@tonic-gate sizeof (fstab->zone_fs_raw)); 20447c478bd9Sstevel@tonic-gate break; 20457c478bd9Sstevel@tonic-gate case PT_TYPE: 20467c478bd9Sstevel@tonic-gate (void) strlcpy(fstab->zone_fs_type, pp->pv_simple, 20477c478bd9Sstevel@tonic-gate sizeof (fstab->zone_fs_type)); 20487c478bd9Sstevel@tonic-gate break; 20497c478bd9Sstevel@tonic-gate default: 20507c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 20517c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 20527c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 20537c478bd9Sstevel@tonic-gate } 20547c478bd9Sstevel@tonic-gate } 20557c478bd9Sstevel@tonic-gate if (fill_in_only) 20567c478bd9Sstevel@tonic-gate return (Z_OK); 20577c478bd9Sstevel@tonic-gate return (zonecfg_lookup_filesystem(handle, fstab)); 20587c478bd9Sstevel@tonic-gate } 20597c478bd9Sstevel@tonic-gate 20607c478bd9Sstevel@tonic-gate static int 20617c478bd9Sstevel@tonic-gate fill_in_ipdtab(cmd_t *cmd, struct zone_fstab *ipdtab, bool fill_in_only) 20627c478bd9Sstevel@tonic-gate { 20637c478bd9Sstevel@tonic-gate int err, i; 20647c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 20657c478bd9Sstevel@tonic-gate 20667c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 20677c478bd9Sstevel@tonic-gate return (err); 20687c478bd9Sstevel@tonic-gate 2069e193d1e6Svp bzero(ipdtab, sizeof (*ipdtab)); 20707c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 20717c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 20727c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 20737c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 20747c478bd9Sstevel@tonic-gate saw_error = TRUE; 20757c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 20767c478bd9Sstevel@tonic-gate } 20777c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 20787c478bd9Sstevel@tonic-gate case PT_DIR: 20797c478bd9Sstevel@tonic-gate (void) strlcpy(ipdtab->zone_fs_dir, pp->pv_simple, 20807c478bd9Sstevel@tonic-gate sizeof (ipdtab->zone_fs_dir)); 20817c478bd9Sstevel@tonic-gate break; 20827c478bd9Sstevel@tonic-gate default: 20837c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 20847c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 20857c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 20867c478bd9Sstevel@tonic-gate } 20877c478bd9Sstevel@tonic-gate } 20887c478bd9Sstevel@tonic-gate if (fill_in_only) 20897c478bd9Sstevel@tonic-gate return (Z_OK); 20907c478bd9Sstevel@tonic-gate return (zonecfg_lookup_ipd(handle, ipdtab)); 20917c478bd9Sstevel@tonic-gate } 20927c478bd9Sstevel@tonic-gate 20937c478bd9Sstevel@tonic-gate static int 20947c478bd9Sstevel@tonic-gate fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab, bool fill_in_only) 20957c478bd9Sstevel@tonic-gate { 20967c478bd9Sstevel@tonic-gate int err, i; 20977c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 20987c478bd9Sstevel@tonic-gate 20997c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 21007c478bd9Sstevel@tonic-gate return (err); 21017c478bd9Sstevel@tonic-gate 2102e193d1e6Svp bzero(nwiftab, sizeof (*nwiftab)); 21037c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 21047c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 21057c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 21067c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 21077c478bd9Sstevel@tonic-gate saw_error = TRUE; 21087c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21097c478bd9Sstevel@tonic-gate } 21107c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 21117c478bd9Sstevel@tonic-gate case PT_ADDRESS: 21127c478bd9Sstevel@tonic-gate (void) strlcpy(nwiftab->zone_nwif_address, 21137c478bd9Sstevel@tonic-gate pp->pv_simple, sizeof (nwiftab->zone_nwif_address)); 21147c478bd9Sstevel@tonic-gate break; 21157c478bd9Sstevel@tonic-gate case PT_PHYSICAL: 21167c478bd9Sstevel@tonic-gate (void) strlcpy(nwiftab->zone_nwif_physical, 21177c478bd9Sstevel@tonic-gate pp->pv_simple, 21187c478bd9Sstevel@tonic-gate sizeof (nwiftab->zone_nwif_physical)); 21197c478bd9Sstevel@tonic-gate break; 21207c478bd9Sstevel@tonic-gate default: 21217c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 21227c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 21237c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21247c478bd9Sstevel@tonic-gate } 21257c478bd9Sstevel@tonic-gate } 21267c478bd9Sstevel@tonic-gate if (fill_in_only) 21277c478bd9Sstevel@tonic-gate return (Z_OK); 21287c478bd9Sstevel@tonic-gate err = zonecfg_lookup_nwif(handle, nwiftab); 21297c478bd9Sstevel@tonic-gate return (err); 21307c478bd9Sstevel@tonic-gate } 21317c478bd9Sstevel@tonic-gate 21327c478bd9Sstevel@tonic-gate static int 21337c478bd9Sstevel@tonic-gate fill_in_devtab(cmd_t *cmd, struct zone_devtab *devtab, bool fill_in_only) 21347c478bd9Sstevel@tonic-gate { 21357c478bd9Sstevel@tonic-gate int err, i; 21367c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 21377c478bd9Sstevel@tonic-gate 21387c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 21397c478bd9Sstevel@tonic-gate return (err); 21407c478bd9Sstevel@tonic-gate 2141e193d1e6Svp bzero(devtab, sizeof (*devtab)); 21427c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 21437c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 21447c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 21457c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 21467c478bd9Sstevel@tonic-gate saw_error = TRUE; 21477c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21487c478bd9Sstevel@tonic-gate } 21497c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 21507c478bd9Sstevel@tonic-gate case PT_MATCH: 21517c478bd9Sstevel@tonic-gate (void) strlcpy(devtab->zone_dev_match, pp->pv_simple, 21527c478bd9Sstevel@tonic-gate sizeof (devtab->zone_dev_match)); 21537c478bd9Sstevel@tonic-gate break; 21547c478bd9Sstevel@tonic-gate default: 21557c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 21567c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 21577c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21587c478bd9Sstevel@tonic-gate } 21597c478bd9Sstevel@tonic-gate } 21607c478bd9Sstevel@tonic-gate if (fill_in_only) 21617c478bd9Sstevel@tonic-gate return (Z_OK); 21627c478bd9Sstevel@tonic-gate err = zonecfg_lookup_dev(handle, devtab); 21637c478bd9Sstevel@tonic-gate return (err); 21647c478bd9Sstevel@tonic-gate } 21657c478bd9Sstevel@tonic-gate 21667c478bd9Sstevel@tonic-gate static int 21677c478bd9Sstevel@tonic-gate fill_in_rctltab(cmd_t *cmd, struct zone_rctltab *rctltab, bool fill_in_only) 21687c478bd9Sstevel@tonic-gate { 21697c478bd9Sstevel@tonic-gate int err, i; 21707c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 21717c478bd9Sstevel@tonic-gate 21727c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 21737c478bd9Sstevel@tonic-gate return (err); 21747c478bd9Sstevel@tonic-gate 2175e193d1e6Svp bzero(rctltab, sizeof (*rctltab)); 21767c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 21777c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 21787c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 21797c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 21807c478bd9Sstevel@tonic-gate saw_error = TRUE; 21817c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21827c478bd9Sstevel@tonic-gate } 21837c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 21847c478bd9Sstevel@tonic-gate case PT_NAME: 21857c478bd9Sstevel@tonic-gate (void) strlcpy(rctltab->zone_rctl_name, pp->pv_simple, 21867c478bd9Sstevel@tonic-gate sizeof (rctltab->zone_rctl_name)); 21877c478bd9Sstevel@tonic-gate break; 21887c478bd9Sstevel@tonic-gate default: 21897c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 21907c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 21917c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 21927c478bd9Sstevel@tonic-gate } 21937c478bd9Sstevel@tonic-gate } 21947c478bd9Sstevel@tonic-gate if (fill_in_only) 21957c478bd9Sstevel@tonic-gate return (Z_OK); 21967c478bd9Sstevel@tonic-gate err = zonecfg_lookup_rctl(handle, rctltab); 21977c478bd9Sstevel@tonic-gate return (err); 21987c478bd9Sstevel@tonic-gate } 21997c478bd9Sstevel@tonic-gate 22007c478bd9Sstevel@tonic-gate static int 22017c478bd9Sstevel@tonic-gate fill_in_attrtab(cmd_t *cmd, struct zone_attrtab *attrtab, bool fill_in_only) 22027c478bd9Sstevel@tonic-gate { 22037c478bd9Sstevel@tonic-gate int err, i; 22047c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 22057c478bd9Sstevel@tonic-gate 22067c478bd9Sstevel@tonic-gate if ((err = initialize(TRUE)) != Z_OK) 22077c478bd9Sstevel@tonic-gate return (err); 22087c478bd9Sstevel@tonic-gate 2209e193d1e6Svp bzero(attrtab, sizeof (*attrtab)); 22107c478bd9Sstevel@tonic-gate for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 22117c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[i]; 22127c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 22137c478bd9Sstevel@tonic-gate zerr(gettext("A simple value was expected here.")); 22147c478bd9Sstevel@tonic-gate saw_error = TRUE; 22157c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 22167c478bd9Sstevel@tonic-gate } 22177c478bd9Sstevel@tonic-gate switch (cmd->cmd_prop_name[i]) { 22187c478bd9Sstevel@tonic-gate case PT_NAME: 22197c478bd9Sstevel@tonic-gate (void) strlcpy(attrtab->zone_attr_name, pp->pv_simple, 22207c478bd9Sstevel@tonic-gate sizeof (attrtab->zone_attr_name)); 22217c478bd9Sstevel@tonic-gate break; 22227c478bd9Sstevel@tonic-gate case PT_TYPE: 22237c478bd9Sstevel@tonic-gate (void) strlcpy(attrtab->zone_attr_type, pp->pv_simple, 22247c478bd9Sstevel@tonic-gate sizeof (attrtab->zone_attr_type)); 22257c478bd9Sstevel@tonic-gate break; 22267c478bd9Sstevel@tonic-gate case PT_VALUE: 22277c478bd9Sstevel@tonic-gate (void) strlcpy(attrtab->zone_attr_value, pp->pv_simple, 22287c478bd9Sstevel@tonic-gate sizeof (attrtab->zone_attr_value)); 22297c478bd9Sstevel@tonic-gate break; 22307c478bd9Sstevel@tonic-gate default: 22317c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 22327c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 22337c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 22347c478bd9Sstevel@tonic-gate } 22357c478bd9Sstevel@tonic-gate } 22367c478bd9Sstevel@tonic-gate if (fill_in_only) 22377c478bd9Sstevel@tonic-gate return (Z_OK); 22387c478bd9Sstevel@tonic-gate err = zonecfg_lookup_attr(handle, attrtab); 22397c478bd9Sstevel@tonic-gate return (err); 22407c478bd9Sstevel@tonic-gate } 22417c478bd9Sstevel@tonic-gate 2242fa9e4066Sahrens static int 2243fa9e4066Sahrens fill_in_dstab(cmd_t *cmd, struct zone_dstab *dstab, bool fill_in_only) 2244fa9e4066Sahrens { 2245fa9e4066Sahrens int err, i; 2246fa9e4066Sahrens property_value_ptr_t pp; 2247fa9e4066Sahrens 2248fa9e4066Sahrens if ((err = initialize(TRUE)) != Z_OK) 2249fa9e4066Sahrens return (err); 2250fa9e4066Sahrens 2251fa9e4066Sahrens dstab->zone_dataset_name[0] = '\0'; 2252fa9e4066Sahrens for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) { 2253fa9e4066Sahrens pp = cmd->cmd_property_ptr[i]; 2254fa9e4066Sahrens if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) { 2255fa9e4066Sahrens zerr(gettext("A simple value was expected here.")); 2256fa9e4066Sahrens saw_error = TRUE; 2257fa9e4066Sahrens return (Z_INSUFFICIENT_SPEC); 2258fa9e4066Sahrens } 2259fa9e4066Sahrens switch (cmd->cmd_prop_name[i]) { 2260fa9e4066Sahrens case PT_NAME: 2261fa9e4066Sahrens (void) strlcpy(dstab->zone_dataset_name, pp->pv_simple, 2262fa9e4066Sahrens sizeof (dstab->zone_dataset_name)); 2263fa9e4066Sahrens break; 2264fa9e4066Sahrens default: 2265fa9e4066Sahrens zone_perror(pt_to_str(cmd->cmd_prop_name[i]), 2266fa9e4066Sahrens Z_NO_PROPERTY_TYPE, TRUE); 2267fa9e4066Sahrens return (Z_INSUFFICIENT_SPEC); 2268fa9e4066Sahrens } 2269fa9e4066Sahrens } 2270fa9e4066Sahrens if (fill_in_only) 2271fa9e4066Sahrens return (Z_OK); 2272fa9e4066Sahrens return (zonecfg_lookup_ds(handle, dstab)); 2273fa9e4066Sahrens } 2274fa9e4066Sahrens 22757c478bd9Sstevel@tonic-gate static void 22767c478bd9Sstevel@tonic-gate remove_resource(cmd_t *cmd) 22777c478bd9Sstevel@tonic-gate { 22787c478bd9Sstevel@tonic-gate int err, type; 22797c478bd9Sstevel@tonic-gate struct zone_fstab fstab; 22807c478bd9Sstevel@tonic-gate struct zone_nwiftab nwiftab; 22817c478bd9Sstevel@tonic-gate struct zone_devtab devtab; 22827c478bd9Sstevel@tonic-gate struct zone_attrtab attrtab; 22837c478bd9Sstevel@tonic-gate struct zone_rctltab rctltab; 2284fa9e4066Sahrens struct zone_dstab dstab; 22857c478bd9Sstevel@tonic-gate 22867c478bd9Sstevel@tonic-gate if ((type = cmd->cmd_res_type) == RT_UNKNOWN) { 22877c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 22887c478bd9Sstevel@tonic-gate return; 22897c478bd9Sstevel@tonic-gate } 22907c478bd9Sstevel@tonic-gate 22917c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 22927c478bd9Sstevel@tonic-gate return; 22937c478bd9Sstevel@tonic-gate 22947c478bd9Sstevel@tonic-gate switch (type) { 22957c478bd9Sstevel@tonic-gate case RT_FS: 22967c478bd9Sstevel@tonic-gate if ((err = fill_in_fstab(cmd, &fstab, FALSE)) != Z_OK) { 22977c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, TRUE); 22987c478bd9Sstevel@tonic-gate return; 22997c478bd9Sstevel@tonic-gate } 23007c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK) 23017c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, TRUE); 23027c478bd9Sstevel@tonic-gate else 23037c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23047c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(fstab.zone_fs_options); 23057c478bd9Sstevel@tonic-gate return; 23067c478bd9Sstevel@tonic-gate case RT_IPD: 2307087719fdSdp if (state_atleast(ZONE_STATE_INSTALLED)) { 23087c478bd9Sstevel@tonic-gate zerr(gettext("Zone %s already installed; %s %s not " 23097c478bd9Sstevel@tonic-gate "allowed."), zone, cmd_to_str(CMD_REMOVE), 23107c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD)); 23117c478bd9Sstevel@tonic-gate return; 23127c478bd9Sstevel@tonic-gate } 23137c478bd9Sstevel@tonic-gate if ((err = fill_in_ipdtab(cmd, &fstab, FALSE)) != Z_OK) { 23147c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_IPD, err, TRUE); 23157c478bd9Sstevel@tonic-gate return; 23167c478bd9Sstevel@tonic-gate } 23177c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_ipd(handle, &fstab)) != Z_OK) 23187c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_IPD, err, TRUE); 23197c478bd9Sstevel@tonic-gate else 23207c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23217c478bd9Sstevel@tonic-gate return; 23227c478bd9Sstevel@tonic-gate case RT_NET: 23237c478bd9Sstevel@tonic-gate if ((err = fill_in_nwiftab(cmd, &nwiftab, FALSE)) != Z_OK) { 23247c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, TRUE); 23257c478bd9Sstevel@tonic-gate return; 23267c478bd9Sstevel@tonic-gate } 23277c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK) 23287c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, TRUE); 23297c478bd9Sstevel@tonic-gate else 23307c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23317c478bd9Sstevel@tonic-gate return; 23327c478bd9Sstevel@tonic-gate case RT_DEVICE: 23337c478bd9Sstevel@tonic-gate if ((err = fill_in_devtab(cmd, &devtab, FALSE)) != Z_OK) { 23347c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, TRUE); 23357c478bd9Sstevel@tonic-gate return; 23367c478bd9Sstevel@tonic-gate } 23377c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK) 23387c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, TRUE); 23397c478bd9Sstevel@tonic-gate else 23407c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23417c478bd9Sstevel@tonic-gate return; 23427c478bd9Sstevel@tonic-gate case RT_RCTL: 23437c478bd9Sstevel@tonic-gate if ((err = fill_in_rctltab(cmd, &rctltab, FALSE)) != Z_OK) { 23447c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, TRUE); 23457c478bd9Sstevel@tonic-gate return; 23467c478bd9Sstevel@tonic-gate } 23477c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK) 23487c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, TRUE); 23497c478bd9Sstevel@tonic-gate else 23507c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23517c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 23527c478bd9Sstevel@tonic-gate return; 23537c478bd9Sstevel@tonic-gate case RT_ATTR: 23547c478bd9Sstevel@tonic-gate if ((err = fill_in_attrtab(cmd, &attrtab, FALSE)) != Z_OK) { 23557c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, TRUE); 23567c478bd9Sstevel@tonic-gate return; 23577c478bd9Sstevel@tonic-gate } 23587c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK) 23597c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, TRUE); 23607c478bd9Sstevel@tonic-gate else 23617c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 23627c478bd9Sstevel@tonic-gate return; 2363fa9e4066Sahrens case RT_DATASET: 2364fa9e4066Sahrens if ((err = fill_in_dstab(cmd, &dstab, FALSE)) != Z_OK) { 2365fa9e4066Sahrens z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, TRUE); 2366fa9e4066Sahrens return; 2367fa9e4066Sahrens } 2368fa9e4066Sahrens if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK) 2369fa9e4066Sahrens z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, TRUE); 2370fa9e4066Sahrens else 2371fa9e4066Sahrens need_to_commit = TRUE; 2372fa9e4066Sahrens return; 23737c478bd9Sstevel@tonic-gate default: 23747c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, TRUE); 23757c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 23767c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 23777c478bd9Sstevel@tonic-gate return; 23787c478bd9Sstevel@tonic-gate } 23797c478bd9Sstevel@tonic-gate } 23807c478bd9Sstevel@tonic-gate 23817c478bd9Sstevel@tonic-gate static void 23827c478bd9Sstevel@tonic-gate remove_property(cmd_t *cmd) 23837c478bd9Sstevel@tonic-gate { 23847c478bd9Sstevel@tonic-gate char *prop_id; 23857c478bd9Sstevel@tonic-gate int err, res_type, prop_type; 23867c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 23877c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *rctlvaltab; 23887c478bd9Sstevel@tonic-gate complex_property_ptr_t cx; 23897c478bd9Sstevel@tonic-gate 23907c478bd9Sstevel@tonic-gate res_type = resource_scope; 23917c478bd9Sstevel@tonic-gate prop_type = cmd->cmd_prop_name[0]; 23927c478bd9Sstevel@tonic-gate if (res_type == RT_UNKNOWN || prop_type == PT_UNKNOWN) { 23937c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 23947c478bd9Sstevel@tonic-gate return; 23957c478bd9Sstevel@tonic-gate } 23967c478bd9Sstevel@tonic-gate 23977c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs != 1) { 23987c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 23997c478bd9Sstevel@tonic-gate return; 24007c478bd9Sstevel@tonic-gate } 24017c478bd9Sstevel@tonic-gate 24027c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 24037c478bd9Sstevel@tonic-gate return; 24047c478bd9Sstevel@tonic-gate 24057c478bd9Sstevel@tonic-gate switch (res_type) { 24067c478bd9Sstevel@tonic-gate case RT_FS: 24077c478bd9Sstevel@tonic-gate if (prop_type != PT_OPTIONS) { 24087c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 24097c478bd9Sstevel@tonic-gate TRUE); 24107c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 24117c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 24127c478bd9Sstevel@tonic-gate return; 24137c478bd9Sstevel@tonic-gate } 24147c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[0]; 24157c478bd9Sstevel@tonic-gate if (pp->pv_type == PROP_VAL_COMPLEX) { 24167c478bd9Sstevel@tonic-gate zerr(gettext("A %s or %s value was expected here."), 24177c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_SIMPLE), 24187c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_LIST)); 24197c478bd9Sstevel@tonic-gate saw_error = TRUE; 24207c478bd9Sstevel@tonic-gate return; 24217c478bd9Sstevel@tonic-gate } 24227c478bd9Sstevel@tonic-gate if (pp->pv_type == PROP_VAL_SIMPLE) { 24237c478bd9Sstevel@tonic-gate if (pp->pv_simple == NULL) { 24247c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 24257c478bd9Sstevel@tonic-gate return; 24267c478bd9Sstevel@tonic-gate } 24277c478bd9Sstevel@tonic-gate prop_id = pp->pv_simple; 24287c478bd9Sstevel@tonic-gate err = zonecfg_remove_fs_option(&in_progress_fstab, 24297c478bd9Sstevel@tonic-gate prop_id); 24307c478bd9Sstevel@tonic-gate if (err != Z_OK) 24317c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), err, TRUE); 24327c478bd9Sstevel@tonic-gate } else { 24337c478bd9Sstevel@tonic-gate list_property_ptr_t list; 24347c478bd9Sstevel@tonic-gate 24357c478bd9Sstevel@tonic-gate for (list = pp->pv_list; list != NULL; 24367c478bd9Sstevel@tonic-gate list = list->lp_next) { 24377c478bd9Sstevel@tonic-gate prop_id = list->lp_simple; 24387c478bd9Sstevel@tonic-gate if (prop_id == NULL) 24397c478bd9Sstevel@tonic-gate break; 24407c478bd9Sstevel@tonic-gate err = zonecfg_remove_fs_option( 24417c478bd9Sstevel@tonic-gate &in_progress_fstab, prop_id); 24427c478bd9Sstevel@tonic-gate if (err != Z_OK) 24437c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), err, 24447c478bd9Sstevel@tonic-gate TRUE); 24457c478bd9Sstevel@tonic-gate } 24467c478bd9Sstevel@tonic-gate } 24477c478bd9Sstevel@tonic-gate return; 24487c478bd9Sstevel@tonic-gate case RT_RCTL: 24497c478bd9Sstevel@tonic-gate if (prop_type != PT_VALUE) { 24507c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 24517c478bd9Sstevel@tonic-gate TRUE); 24527c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 24537c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 24547c478bd9Sstevel@tonic-gate return; 24557c478bd9Sstevel@tonic-gate } 24567c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[0]; 24577c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_COMPLEX) { 24587c478bd9Sstevel@tonic-gate zerr(gettext("A %s value was expected here."), 24597c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_COMPLEX)); 24607c478bd9Sstevel@tonic-gate saw_error = TRUE; 24617c478bd9Sstevel@tonic-gate return; 24627c478bd9Sstevel@tonic-gate } 24637c478bd9Sstevel@tonic-gate if ((rctlvaltab = alloc_rctlvaltab()) == NULL) { 24647c478bd9Sstevel@tonic-gate zone_perror(zone, Z_NOMEM, TRUE); 24657c478bd9Sstevel@tonic-gate exit(Z_ERR); 24667c478bd9Sstevel@tonic-gate } 24677c478bd9Sstevel@tonic-gate for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) { 24687c478bd9Sstevel@tonic-gate switch (cx->cp_type) { 24697c478bd9Sstevel@tonic-gate case PT_PRIV: 24707c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_priv, 24717c478bd9Sstevel@tonic-gate cx->cp_value, 24727c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_priv)); 24737c478bd9Sstevel@tonic-gate break; 24747c478bd9Sstevel@tonic-gate case PT_LIMIT: 24757c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_limit, 24767c478bd9Sstevel@tonic-gate cx->cp_value, 24777c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_limit)); 24787c478bd9Sstevel@tonic-gate break; 24797c478bd9Sstevel@tonic-gate case PT_ACTION: 24807c478bd9Sstevel@tonic-gate (void) strlcpy(rctlvaltab->zone_rctlval_action, 24817c478bd9Sstevel@tonic-gate cx->cp_value, 24827c478bd9Sstevel@tonic-gate sizeof (rctlvaltab->zone_rctlval_action)); 24837c478bd9Sstevel@tonic-gate break; 24847c478bd9Sstevel@tonic-gate default: 24857c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), 24867c478bd9Sstevel@tonic-gate Z_NO_PROPERTY_TYPE, TRUE); 24877c478bd9Sstevel@tonic-gate long_usage(CMD_ADD, TRUE); 24887c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 24897c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctlvaltab); 24907c478bd9Sstevel@tonic-gate return; 24917c478bd9Sstevel@tonic-gate } 24927c478bd9Sstevel@tonic-gate } 24937c478bd9Sstevel@tonic-gate rctlvaltab->zone_rctlval_next = NULL; 24947c478bd9Sstevel@tonic-gate err = zonecfg_remove_rctl_value(&in_progress_rctltab, 24957c478bd9Sstevel@tonic-gate rctlvaltab); 24967c478bd9Sstevel@tonic-gate if (err != Z_OK) 24977c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), err, TRUE); 24987c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctlvaltab); 24997c478bd9Sstevel@tonic-gate return; 25007c478bd9Sstevel@tonic-gate default: 25017c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, TRUE); 25027c478bd9Sstevel@tonic-gate long_usage(CMD_REMOVE, TRUE); 25037c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 25047c478bd9Sstevel@tonic-gate return; 25057c478bd9Sstevel@tonic-gate } 25067c478bd9Sstevel@tonic-gate } 25077c478bd9Sstevel@tonic-gate 25087c478bd9Sstevel@tonic-gate void 25097c478bd9Sstevel@tonic-gate remove_func(cmd_t *cmd) 25107c478bd9Sstevel@tonic-gate { 25117c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_REMOVE)) 25127c478bd9Sstevel@tonic-gate return; 25137c478bd9Sstevel@tonic-gate 25147c478bd9Sstevel@tonic-gate assert(cmd != NULL); 25157c478bd9Sstevel@tonic-gate 25167c478bd9Sstevel@tonic-gate if (global_scope) 25177c478bd9Sstevel@tonic-gate remove_resource(cmd); 25187c478bd9Sstevel@tonic-gate else 25197c478bd9Sstevel@tonic-gate remove_property(cmd); 25207c478bd9Sstevel@tonic-gate } 25217c478bd9Sstevel@tonic-gate 25227c478bd9Sstevel@tonic-gate void 25237c478bd9Sstevel@tonic-gate select_func(cmd_t *cmd) 25247c478bd9Sstevel@tonic-gate { 25257c478bd9Sstevel@tonic-gate int type, err; 25267c478bd9Sstevel@tonic-gate 25277c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_SELECT)) 25287c478bd9Sstevel@tonic-gate return; 25297c478bd9Sstevel@tonic-gate 25307c478bd9Sstevel@tonic-gate assert(cmd != NULL); 25317c478bd9Sstevel@tonic-gate 25327c478bd9Sstevel@tonic-gate if (global_scope) { 25337c478bd9Sstevel@tonic-gate global_scope = FALSE; 25347c478bd9Sstevel@tonic-gate resource_scope = cmd->cmd_res_type; 25357c478bd9Sstevel@tonic-gate end_op = CMD_SELECT; 25367c478bd9Sstevel@tonic-gate } else { 25377c478bd9Sstevel@tonic-gate scope_usage(CMD_SELECT); 25387c478bd9Sstevel@tonic-gate return; 25397c478bd9Sstevel@tonic-gate } 25407c478bd9Sstevel@tonic-gate 25417c478bd9Sstevel@tonic-gate if ((type = cmd->cmd_res_type) == RT_UNKNOWN) { 25427c478bd9Sstevel@tonic-gate long_usage(CMD_SELECT, TRUE); 25437c478bd9Sstevel@tonic-gate return; 25447c478bd9Sstevel@tonic-gate } 25457c478bd9Sstevel@tonic-gate 25467c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 25477c478bd9Sstevel@tonic-gate return; 25487c478bd9Sstevel@tonic-gate 25497c478bd9Sstevel@tonic-gate switch (type) { 25507c478bd9Sstevel@tonic-gate case RT_FS: 25517c478bd9Sstevel@tonic-gate if ((err = fill_in_fstab(cmd, &old_fstab, FALSE)) != Z_OK) { 25527c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_FS, err, TRUE); 25537c478bd9Sstevel@tonic-gate global_scope = TRUE; 25547c478bd9Sstevel@tonic-gate } 25557c478bd9Sstevel@tonic-gate bcopy(&old_fstab, &in_progress_fstab, 25567c478bd9Sstevel@tonic-gate sizeof (struct zone_fstab)); 25577c478bd9Sstevel@tonic-gate return; 25587c478bd9Sstevel@tonic-gate case RT_IPD: 2559087719fdSdp if (state_atleast(ZONE_STATE_INCOMPLETE)) { 25607c478bd9Sstevel@tonic-gate zerr(gettext("Zone %s not in %s state; %s %s not " 25617c478bd9Sstevel@tonic-gate "allowed."), zone, 25627c478bd9Sstevel@tonic-gate zone_state_str(ZONE_STATE_CONFIGURED), 25637c478bd9Sstevel@tonic-gate cmd_to_str(CMD_SELECT), rt_to_str(RT_IPD)); 25647c478bd9Sstevel@tonic-gate global_scope = TRUE; 25657c478bd9Sstevel@tonic-gate end_op = -1; 25667c478bd9Sstevel@tonic-gate return; 25677c478bd9Sstevel@tonic-gate } 25687c478bd9Sstevel@tonic-gate if ((err = fill_in_ipdtab(cmd, &old_ipdtab, FALSE)) != Z_OK) { 25697c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_IPD, err, TRUE); 25707c478bd9Sstevel@tonic-gate global_scope = TRUE; 25717c478bd9Sstevel@tonic-gate } 25727c478bd9Sstevel@tonic-gate bcopy(&old_ipdtab, &in_progress_ipdtab, 25737c478bd9Sstevel@tonic-gate sizeof (struct zone_fstab)); 25747c478bd9Sstevel@tonic-gate return; 25757c478bd9Sstevel@tonic-gate case RT_NET: 25767c478bd9Sstevel@tonic-gate if ((err = fill_in_nwiftab(cmd, &old_nwiftab, FALSE)) != Z_OK) { 25777c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_NET, err, TRUE); 25787c478bd9Sstevel@tonic-gate global_scope = TRUE; 25797c478bd9Sstevel@tonic-gate } 25807c478bd9Sstevel@tonic-gate bcopy(&old_nwiftab, &in_progress_nwiftab, 25817c478bd9Sstevel@tonic-gate sizeof (struct zone_nwiftab)); 25827c478bd9Sstevel@tonic-gate return; 25837c478bd9Sstevel@tonic-gate case RT_DEVICE: 25847c478bd9Sstevel@tonic-gate if ((err = fill_in_devtab(cmd, &old_devtab, FALSE)) != Z_OK) { 25857c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_DEVICE, err, TRUE); 25867c478bd9Sstevel@tonic-gate global_scope = TRUE; 25877c478bd9Sstevel@tonic-gate } 25887c478bd9Sstevel@tonic-gate bcopy(&old_devtab, &in_progress_devtab, 25897c478bd9Sstevel@tonic-gate sizeof (struct zone_devtab)); 25907c478bd9Sstevel@tonic-gate return; 25917c478bd9Sstevel@tonic-gate case RT_RCTL: 25927c478bd9Sstevel@tonic-gate if ((err = fill_in_rctltab(cmd, &old_rctltab, FALSE)) != Z_OK) { 25937c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_RCTL, err, TRUE); 25947c478bd9Sstevel@tonic-gate global_scope = TRUE; 25957c478bd9Sstevel@tonic-gate } 25967c478bd9Sstevel@tonic-gate bcopy(&old_rctltab, &in_progress_rctltab, 25977c478bd9Sstevel@tonic-gate sizeof (struct zone_rctltab)); 25987c478bd9Sstevel@tonic-gate return; 25997c478bd9Sstevel@tonic-gate case RT_ATTR: 26007c478bd9Sstevel@tonic-gate if ((err = fill_in_attrtab(cmd, &old_attrtab, FALSE)) != Z_OK) { 26017c478bd9Sstevel@tonic-gate z_cmd_rt_perror(CMD_SELECT, RT_ATTR, err, TRUE); 26027c478bd9Sstevel@tonic-gate global_scope = TRUE; 26037c478bd9Sstevel@tonic-gate } 26047c478bd9Sstevel@tonic-gate bcopy(&old_attrtab, &in_progress_attrtab, 26057c478bd9Sstevel@tonic-gate sizeof (struct zone_attrtab)); 26067c478bd9Sstevel@tonic-gate return; 2607fa9e4066Sahrens case RT_DATASET: 2608fa9e4066Sahrens if ((err = fill_in_dstab(cmd, &old_dstab, FALSE)) != Z_OK) { 2609fa9e4066Sahrens z_cmd_rt_perror(CMD_SELECT, RT_DATASET, err, TRUE); 2610fa9e4066Sahrens global_scope = TRUE; 2611fa9e4066Sahrens } 2612fa9e4066Sahrens bcopy(&old_dstab, &in_progress_dstab, 2613fa9e4066Sahrens sizeof (struct zone_dstab)); 2614fa9e4066Sahrens return; 26157c478bd9Sstevel@tonic-gate default: 26167c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, TRUE); 26177c478bd9Sstevel@tonic-gate long_usage(CMD_SELECT, TRUE); 26187c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 26197c478bd9Sstevel@tonic-gate return; 26207c478bd9Sstevel@tonic-gate } 26217c478bd9Sstevel@tonic-gate } 26227c478bd9Sstevel@tonic-gate 26237c478bd9Sstevel@tonic-gate /* 26247c478bd9Sstevel@tonic-gate * Network "addresses" can be one of the following forms: 26257c478bd9Sstevel@tonic-gate * <IPv4 address> 26267c478bd9Sstevel@tonic-gate * <IPv4 address>/<prefix length> 26277c478bd9Sstevel@tonic-gate * <IPv6 address>/<prefix length> 26287c478bd9Sstevel@tonic-gate * <host name> 26297c478bd9Sstevel@tonic-gate * <host name>/<prefix length> 26307c478bd9Sstevel@tonic-gate * In other words, the "/" followed by a prefix length is allowed but not 26317c478bd9Sstevel@tonic-gate * required for IPv4 addresses and host names, and required for IPv6 addresses. 26327c478bd9Sstevel@tonic-gate * If a prefix length is given, it must be in the allowable range: 0 to 32 for 26337c478bd9Sstevel@tonic-gate * IPv4 addresses and host names, 0 to 128 for IPv6 addresses. 26347c478bd9Sstevel@tonic-gate * Host names must start with an alpha-numeric character, and all subsequent 26357c478bd9Sstevel@tonic-gate * characters must be either alpha-numeric or "-". 26367c478bd9Sstevel@tonic-gate */ 26377c478bd9Sstevel@tonic-gate 26387c478bd9Sstevel@tonic-gate static int 26397c478bd9Sstevel@tonic-gate validate_net_address_syntax(char *address) 26407c478bd9Sstevel@tonic-gate { 26417c478bd9Sstevel@tonic-gate char *slashp, part1[MAXHOSTNAMELEN]; 26427c478bd9Sstevel@tonic-gate struct in6_addr in6; 26437c478bd9Sstevel@tonic-gate struct in_addr in4; 26447c478bd9Sstevel@tonic-gate int prefixlen, i; 26457c478bd9Sstevel@tonic-gate 26467c478bd9Sstevel@tonic-gate /* 26477c478bd9Sstevel@tonic-gate * Copy the part before any '/' into part1 or copy the whole 26487c478bd9Sstevel@tonic-gate * thing if there is no '/'. 26497c478bd9Sstevel@tonic-gate */ 26507c478bd9Sstevel@tonic-gate if ((slashp = strchr(address, '/')) != NULL) { 26517c478bd9Sstevel@tonic-gate *slashp = '\0'; 26527c478bd9Sstevel@tonic-gate (void) strlcpy(part1, address, sizeof (part1)); 26537c478bd9Sstevel@tonic-gate *slashp = '/'; 26547c478bd9Sstevel@tonic-gate prefixlen = atoi(++slashp); 26557c478bd9Sstevel@tonic-gate } else { 26567c478bd9Sstevel@tonic-gate (void) strlcpy(part1, address, sizeof (part1)); 26577c478bd9Sstevel@tonic-gate } 26587c478bd9Sstevel@tonic-gate 26597c478bd9Sstevel@tonic-gate if (inet_pton(AF_INET6, part1, &in6) == 1) { 26607c478bd9Sstevel@tonic-gate if (slashp == NULL) { 26617c478bd9Sstevel@tonic-gate zerr(gettext("%s: IPv6 addresses " 26627c478bd9Sstevel@tonic-gate "require /prefix-length suffix."), address); 26637c478bd9Sstevel@tonic-gate return (Z_ERR); 26647c478bd9Sstevel@tonic-gate } 26657c478bd9Sstevel@tonic-gate if (prefixlen < 0 || prefixlen > 128) { 26667c478bd9Sstevel@tonic-gate zerr(gettext("%s: IPv6 address " 26677c478bd9Sstevel@tonic-gate "prefix lengths must be 0 - 128."), address); 26687c478bd9Sstevel@tonic-gate return (Z_ERR); 26697c478bd9Sstevel@tonic-gate } 26707c478bd9Sstevel@tonic-gate return (Z_OK); 26717c478bd9Sstevel@tonic-gate } 26727c478bd9Sstevel@tonic-gate 26737c478bd9Sstevel@tonic-gate /* At this point, any /prefix must be for IPv4. */ 26747c478bd9Sstevel@tonic-gate if (slashp != NULL) { 26757c478bd9Sstevel@tonic-gate if (prefixlen < 0 || prefixlen > 32) { 26767c478bd9Sstevel@tonic-gate zerr(gettext("%s: IPv4 address " 26777c478bd9Sstevel@tonic-gate "prefix lengths must be 0 - 32."), address); 26787c478bd9Sstevel@tonic-gate return (Z_ERR); 26797c478bd9Sstevel@tonic-gate } 26807c478bd9Sstevel@tonic-gate } 26817c478bd9Sstevel@tonic-gate if (inet_pton(AF_INET, part1, &in4) == 1) 26827c478bd9Sstevel@tonic-gate return (Z_OK); 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate /* address may also be a host name */ 26857c478bd9Sstevel@tonic-gate if (!isalnum(part1[0])) { 26867c478bd9Sstevel@tonic-gate zerr(gettext("%s: bogus host name or network address syntax"), 26877c478bd9Sstevel@tonic-gate part1); 26887c478bd9Sstevel@tonic-gate saw_error = TRUE; 26897c478bd9Sstevel@tonic-gate usage(FALSE, HELP_NETADDR); 26907c478bd9Sstevel@tonic-gate return (Z_ERR); 26917c478bd9Sstevel@tonic-gate } 26927c478bd9Sstevel@tonic-gate for (i = 1; part1[i]; i++) 26937c478bd9Sstevel@tonic-gate if (!isalnum(part1[i]) && part1[i] != '-' && part1[i] != '.') { 26947c478bd9Sstevel@tonic-gate zerr(gettext("%s: bogus host name or " 26957c478bd9Sstevel@tonic-gate "network address syntax"), part1); 26967c478bd9Sstevel@tonic-gate saw_error = TRUE; 26977c478bd9Sstevel@tonic-gate usage(FALSE, HELP_NETADDR); 26987c478bd9Sstevel@tonic-gate return (Z_ERR); 26997c478bd9Sstevel@tonic-gate } 27007c478bd9Sstevel@tonic-gate return (Z_OK); 27017c478bd9Sstevel@tonic-gate } 27027c478bd9Sstevel@tonic-gate 27037c478bd9Sstevel@tonic-gate static int 27047c478bd9Sstevel@tonic-gate validate_net_physical_syntax(char *ifname) 27057c478bd9Sstevel@tonic-gate { 27067c478bd9Sstevel@tonic-gate if (strchr(ifname, ':') == NULL) 27077c478bd9Sstevel@tonic-gate return (Z_OK); 27087c478bd9Sstevel@tonic-gate zerr(gettext("%s: physical interface name required; " 27097c478bd9Sstevel@tonic-gate "logical interface name not allowed"), ifname); 27107c478bd9Sstevel@tonic-gate return (Z_ERR); 27117c478bd9Sstevel@tonic-gate } 27127c478bd9Sstevel@tonic-gate 27137c478bd9Sstevel@tonic-gate static boolean_t 27147c478bd9Sstevel@tonic-gate valid_fs_type(const char *type) 27157c478bd9Sstevel@tonic-gate { 27167c478bd9Sstevel@tonic-gate /* 27177c478bd9Sstevel@tonic-gate * Is this a valid path component? 27187c478bd9Sstevel@tonic-gate */ 27197c478bd9Sstevel@tonic-gate if (strlen(type) + 1 > MAXNAMELEN) 27207c478bd9Sstevel@tonic-gate return (B_FALSE); 27217c478bd9Sstevel@tonic-gate /* 27227c478bd9Sstevel@tonic-gate * Make sure a bad value for "type" doesn't make 27237c478bd9Sstevel@tonic-gate * /usr/lib/fs/<type>/mount turn into something else. 27247c478bd9Sstevel@tonic-gate */ 27257c478bd9Sstevel@tonic-gate if (strchr(type, '/') != NULL || type[0] == '\0' || 27267c478bd9Sstevel@tonic-gate strcmp(type, ".") == 0 || strcmp(type, "..") == 0) 2727087719fdSdp return (B_FALSE); 27287c478bd9Sstevel@tonic-gate /* 27297c478bd9Sstevel@tonic-gate * More detailed verification happens later by zoneadm(1m). 27307c478bd9Sstevel@tonic-gate */ 27317c478bd9Sstevel@tonic-gate return (B_TRUE); 27327c478bd9Sstevel@tonic-gate } 27337c478bd9Sstevel@tonic-gate 27347c478bd9Sstevel@tonic-gate void 27357c478bd9Sstevel@tonic-gate set_func(cmd_t *cmd) 27367c478bd9Sstevel@tonic-gate { 27377c478bd9Sstevel@tonic-gate char *prop_id; 2738555afedfScarlsonj int arg, err, res_type, prop_type; 27397c478bd9Sstevel@tonic-gate property_value_ptr_t pp; 27407c478bd9Sstevel@tonic-gate boolean_t autoboot; 2741555afedfScarlsonj boolean_t force_set = FALSE; 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_SET)) 27447c478bd9Sstevel@tonic-gate return; 27457c478bd9Sstevel@tonic-gate 27467c478bd9Sstevel@tonic-gate assert(cmd != NULL); 27477c478bd9Sstevel@tonic-gate 2748555afedfScarlsonj optind = opterr = 0; 2749555afedfScarlsonj while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) { 2750555afedfScarlsonj switch (arg) { 2751555afedfScarlsonj case 'F': 2752555afedfScarlsonj force_set = TRUE; 2753555afedfScarlsonj break; 2754555afedfScarlsonj default: 2755555afedfScarlsonj if (optopt == '?') 2756555afedfScarlsonj longer_usage(CMD_SET); 2757555afedfScarlsonj else 2758555afedfScarlsonj short_usage(CMD_SET); 2759555afedfScarlsonj return; 2760555afedfScarlsonj } 2761555afedfScarlsonj } 2762555afedfScarlsonj 27637c478bd9Sstevel@tonic-gate prop_type = cmd->cmd_prop_name[0]; 27647c478bd9Sstevel@tonic-gate if (global_scope) { 2765087719fdSdp if (prop_type == PT_ZONENAME) { 2766087719fdSdp res_type = RT_ZONENAME; 2767087719fdSdp } else if (prop_type == PT_ZONEPATH) { 27687c478bd9Sstevel@tonic-gate res_type = RT_ZONEPATH; 27697c478bd9Sstevel@tonic-gate } else if (prop_type == PT_AUTOBOOT) { 27707c478bd9Sstevel@tonic-gate res_type = RT_AUTOBOOT; 2771*9acbbeafSnn } else if (prop_type == PT_BRAND) { 2772*9acbbeafSnn res_type = RT_BRAND; 27737c478bd9Sstevel@tonic-gate } else if (prop_type == PT_POOL) { 27747c478bd9Sstevel@tonic-gate res_type = RT_POOL; 2775ffbafc53Scomay } else if (prop_type == PT_LIMITPRIV) { 2776ffbafc53Scomay res_type = RT_LIMITPRIV; 27773f2f09c1Sdp } else if (prop_type == PT_BOOTARGS) { 27783f2f09c1Sdp res_type = RT_BOOTARGS; 27797c478bd9Sstevel@tonic-gate } else { 27807c478bd9Sstevel@tonic-gate zerr(gettext("Cannot set a resource-specific property " 27817c478bd9Sstevel@tonic-gate "from the global scope.")); 27827c478bd9Sstevel@tonic-gate saw_error = TRUE; 27837c478bd9Sstevel@tonic-gate return; 27847c478bd9Sstevel@tonic-gate } 27857c478bd9Sstevel@tonic-gate } else { 27867c478bd9Sstevel@tonic-gate res_type = resource_scope; 27877c478bd9Sstevel@tonic-gate } 27887c478bd9Sstevel@tonic-gate 2789555afedfScarlsonj if (force_set) { 2790555afedfScarlsonj if (res_type != RT_ZONEPATH) { 2791555afedfScarlsonj zerr(gettext("Only zonepath setting can be forced.")); 2792555afedfScarlsonj saw_error = TRUE; 2793555afedfScarlsonj return; 2794555afedfScarlsonj } 2795555afedfScarlsonj if (!zonecfg_in_alt_root()) { 2796555afedfScarlsonj zerr(gettext("Zonepath is changeable only in an " 2797555afedfScarlsonj "alternate root.")); 2798555afedfScarlsonj saw_error = TRUE; 2799555afedfScarlsonj return; 2800555afedfScarlsonj } 2801555afedfScarlsonj } 2802555afedfScarlsonj 28037c478bd9Sstevel@tonic-gate pp = cmd->cmd_property_ptr[0]; 28047c478bd9Sstevel@tonic-gate /* 28057c478bd9Sstevel@tonic-gate * A nasty expression but not that complicated: 28067c478bd9Sstevel@tonic-gate * 1. fs options are simple or list (tested below) 28077c478bd9Sstevel@tonic-gate * 2. rctl value's are complex or list (tested below) 28087c478bd9Sstevel@tonic-gate * Anything else should be simple. 28097c478bd9Sstevel@tonic-gate */ 28107c478bd9Sstevel@tonic-gate if (!(res_type == RT_FS && prop_type == PT_OPTIONS) && 28117c478bd9Sstevel@tonic-gate !(res_type == RT_RCTL && prop_type == PT_VALUE) && 28127c478bd9Sstevel@tonic-gate (pp->pv_type != PROP_VAL_SIMPLE || 28137c478bd9Sstevel@tonic-gate (prop_id = pp->pv_simple) == NULL)) { 28147c478bd9Sstevel@tonic-gate zerr(gettext("A %s value was expected here."), 28157c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_SIMPLE)); 28167c478bd9Sstevel@tonic-gate saw_error = TRUE; 28177c478bd9Sstevel@tonic-gate return; 28187c478bd9Sstevel@tonic-gate } 28197c478bd9Sstevel@tonic-gate if (prop_type == PT_UNKNOWN) { 28207c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 28217c478bd9Sstevel@tonic-gate return; 28227c478bd9Sstevel@tonic-gate } 28237c478bd9Sstevel@tonic-gate 2824087719fdSdp /* 2825087719fdSdp * Special case: the user can change the zone name prior to 'create'; 2826087719fdSdp * if the zone already exists, we fall through letting initialize() 2827087719fdSdp * and the rest of the logic run. 2828087719fdSdp */ 2829087719fdSdp if (res_type == RT_ZONENAME && got_handle == FALSE && 2830087719fdSdp !state_atleast(ZONE_STATE_CONFIGURED)) { 2831fb03efaaSdp if ((err = zonecfg_validate_zonename(prop_id)) != Z_OK) { 2832fb03efaaSdp zone_perror(prop_id, err, TRUE); 2833fb03efaaSdp usage(FALSE, HELP_SYNTAX); 2834fb03efaaSdp return; 2835fb03efaaSdp } 2836087719fdSdp (void) strlcpy(zone, prop_id, sizeof (zone)); 2837087719fdSdp return; 2838087719fdSdp } 2839087719fdSdp 28407c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 28417c478bd9Sstevel@tonic-gate return; 28427c478bd9Sstevel@tonic-gate 28437c478bd9Sstevel@tonic-gate switch (res_type) { 2844087719fdSdp case RT_ZONENAME: 2845087719fdSdp if ((err = zonecfg_set_name(handle, prop_id)) != Z_OK) { 2846087719fdSdp /* 2847087719fdSdp * Use prop_id instead of 'zone' here, since we're 2848087719fdSdp * reporting a problem about the *new* zonename. 2849087719fdSdp */ 2850087719fdSdp zone_perror(prop_id, err, TRUE); 2851fb03efaaSdp usage(FALSE, HELP_SYNTAX); 2852087719fdSdp } else { 2853087719fdSdp need_to_commit = TRUE; 2854087719fdSdp (void) strlcpy(zone, prop_id, sizeof (zone)); 2855087719fdSdp } 2856087719fdSdp return; 28577c478bd9Sstevel@tonic-gate case RT_ZONEPATH: 2858555afedfScarlsonj if (!force_set && state_atleast(ZONE_STATE_INSTALLED)) { 28597c478bd9Sstevel@tonic-gate zerr(gettext("Zone %s already installed; %s %s not " 28607c478bd9Sstevel@tonic-gate "allowed."), zone, cmd_to_str(CMD_SET), 28617c478bd9Sstevel@tonic-gate rt_to_str(RT_ZONEPATH)); 28627c478bd9Sstevel@tonic-gate return; 28637c478bd9Sstevel@tonic-gate } 28647c478bd9Sstevel@tonic-gate if (validate_zonepath_syntax(prop_id) != Z_OK) { 28657c478bd9Sstevel@tonic-gate saw_error = TRUE; 28667c478bd9Sstevel@tonic-gate return; 28677c478bd9Sstevel@tonic-gate } 28687c478bd9Sstevel@tonic-gate if ((err = zonecfg_set_zonepath(handle, prop_id)) != Z_OK) 28697c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 28707c478bd9Sstevel@tonic-gate else 28717c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 28727c478bd9Sstevel@tonic-gate return; 2873*9acbbeafSnn case RT_BRAND: 2874*9acbbeafSnn if (state_atleast(ZONE_STATE_INSTALLED)) { 2875*9acbbeafSnn zerr(gettext("Zone %s already installed; %s %s not " 2876*9acbbeafSnn "allowed."), zone, cmd_to_str(CMD_SET), 2877*9acbbeafSnn rt_to_str(RT_BRAND)); 2878*9acbbeafSnn return; 2879*9acbbeafSnn } 2880*9acbbeafSnn if ((err = zonecfg_set_brand(handle, prop_id)) != Z_OK) 2881*9acbbeafSnn zone_perror(zone, err, TRUE); 2882*9acbbeafSnn else 2883*9acbbeafSnn need_to_commit = TRUE; 2884*9acbbeafSnn return; 28857c478bd9Sstevel@tonic-gate case RT_AUTOBOOT: 28867c478bd9Sstevel@tonic-gate if (strcmp(prop_id, "true") == 0) { 28877c478bd9Sstevel@tonic-gate autoboot = B_TRUE; 28887c478bd9Sstevel@tonic-gate } else if (strcmp(prop_id, "false") == 0) { 28897c478bd9Sstevel@tonic-gate autoboot = B_FALSE; 28907c478bd9Sstevel@tonic-gate } else { 28917c478bd9Sstevel@tonic-gate zerr(gettext("%s value must be '%s' or '%s'."), 28927c478bd9Sstevel@tonic-gate pt_to_str(PT_AUTOBOOT), "true", "false"); 28937c478bd9Sstevel@tonic-gate saw_error = TRUE; 28947c478bd9Sstevel@tonic-gate return; 28957c478bd9Sstevel@tonic-gate } 28967c478bd9Sstevel@tonic-gate if ((err = zonecfg_set_autoboot(handle, autoboot)) != Z_OK) 28977c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 28987c478bd9Sstevel@tonic-gate else 28997c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 29007c478bd9Sstevel@tonic-gate return; 29017c478bd9Sstevel@tonic-gate case RT_POOL: 29027c478bd9Sstevel@tonic-gate if ((err = zonecfg_set_pool(handle, prop_id)) != Z_OK) 29037c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 29047c478bd9Sstevel@tonic-gate else 29057c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 29067c478bd9Sstevel@tonic-gate return; 2907ffbafc53Scomay case RT_LIMITPRIV: 2908ffbafc53Scomay if ((err = zonecfg_set_limitpriv(handle, prop_id)) != Z_OK) 2909ffbafc53Scomay zone_perror(zone, err, TRUE); 2910ffbafc53Scomay else 2911ffbafc53Scomay need_to_commit = TRUE; 2912ffbafc53Scomay return; 29133f2f09c1Sdp case RT_BOOTARGS: 29143f2f09c1Sdp if ((err = zonecfg_set_bootargs(handle, prop_id)) != Z_OK) 29153f2f09c1Sdp zone_perror(zone, err, TRUE); 29163f2f09c1Sdp else 29173f2f09c1Sdp need_to_commit = TRUE; 29183f2f09c1Sdp return; 29197c478bd9Sstevel@tonic-gate case RT_FS: 29207c478bd9Sstevel@tonic-gate switch (prop_type) { 29217c478bd9Sstevel@tonic-gate case PT_DIR: 29227c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_fstab.zone_fs_dir, prop_id, 29237c478bd9Sstevel@tonic-gate sizeof (in_progress_fstab.zone_fs_dir)); 29247c478bd9Sstevel@tonic-gate return; 29257c478bd9Sstevel@tonic-gate case PT_SPECIAL: 29267c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_fstab.zone_fs_special, 29277c478bd9Sstevel@tonic-gate prop_id, 29287c478bd9Sstevel@tonic-gate sizeof (in_progress_fstab.zone_fs_special)); 29297c478bd9Sstevel@tonic-gate return; 29307c478bd9Sstevel@tonic-gate case PT_RAW: 29317c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_fstab.zone_fs_raw, 29327c478bd9Sstevel@tonic-gate prop_id, sizeof (in_progress_fstab.zone_fs_raw)); 29337c478bd9Sstevel@tonic-gate return; 29347c478bd9Sstevel@tonic-gate case PT_TYPE: 29357c478bd9Sstevel@tonic-gate if (!valid_fs_type(prop_id)) { 29367c478bd9Sstevel@tonic-gate zerr(gettext("\"%s\" is not a valid %s."), 29377c478bd9Sstevel@tonic-gate prop_id, pt_to_str(PT_TYPE)); 29387c478bd9Sstevel@tonic-gate saw_error = TRUE; 29397c478bd9Sstevel@tonic-gate return; 29407c478bd9Sstevel@tonic-gate } 29417c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_fstab.zone_fs_type, prop_id, 29427c478bd9Sstevel@tonic-gate sizeof (in_progress_fstab.zone_fs_type)); 29437c478bd9Sstevel@tonic-gate return; 29447c478bd9Sstevel@tonic-gate case PT_OPTIONS: 29457c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_SIMPLE && 29467c478bd9Sstevel@tonic-gate pp->pv_type != PROP_VAL_LIST) { 29477c478bd9Sstevel@tonic-gate zerr(gettext("A %s or %s value was expected " 29487c478bd9Sstevel@tonic-gate "here."), pvt_to_str(PROP_VAL_SIMPLE), 29497c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_LIST)); 29507c478bd9Sstevel@tonic-gate saw_error = TRUE; 29517c478bd9Sstevel@tonic-gate return; 29527c478bd9Sstevel@tonic-gate } 29537c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list( 29547c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_options); 29557c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_options = NULL; 29567c478bd9Sstevel@tonic-gate if (!(pp->pv_type == PROP_VAL_LIST && 29577c478bd9Sstevel@tonic-gate pp->pv_list == NULL)) 29587c478bd9Sstevel@tonic-gate add_property(cmd); 29597c478bd9Sstevel@tonic-gate return; 29607c478bd9Sstevel@tonic-gate default: 29617c478bd9Sstevel@tonic-gate break; 29627c478bd9Sstevel@tonic-gate } 29637c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, TRUE); 29647c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 29657c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 29667c478bd9Sstevel@tonic-gate return; 29677c478bd9Sstevel@tonic-gate case RT_IPD: 29687c478bd9Sstevel@tonic-gate switch (prop_type) { 29697c478bd9Sstevel@tonic-gate case PT_DIR: 29707c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_ipdtab.zone_fs_dir, prop_id, 29717c478bd9Sstevel@tonic-gate sizeof (in_progress_ipdtab.zone_fs_dir)); 29727c478bd9Sstevel@tonic-gate return; 29737c478bd9Sstevel@tonic-gate default: 29747c478bd9Sstevel@tonic-gate break; 29757c478bd9Sstevel@tonic-gate } 29767c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, TRUE); 29777c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 29787c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 29797c478bd9Sstevel@tonic-gate return; 29807c478bd9Sstevel@tonic-gate case RT_NET: 29817c478bd9Sstevel@tonic-gate switch (prop_type) { 29827c478bd9Sstevel@tonic-gate case PT_ADDRESS: 29837c478bd9Sstevel@tonic-gate if (validate_net_address_syntax(prop_id) != Z_OK) { 29847c478bd9Sstevel@tonic-gate saw_error = TRUE; 29857c478bd9Sstevel@tonic-gate return; 29867c478bd9Sstevel@tonic-gate } 29877c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_nwiftab.zone_nwif_address, 29887c478bd9Sstevel@tonic-gate prop_id, 29897c478bd9Sstevel@tonic-gate sizeof (in_progress_nwiftab.zone_nwif_address)); 29907c478bd9Sstevel@tonic-gate break; 29917c478bd9Sstevel@tonic-gate case PT_PHYSICAL: 29927c478bd9Sstevel@tonic-gate if (validate_net_physical_syntax(prop_id) != Z_OK) { 29937c478bd9Sstevel@tonic-gate saw_error = TRUE; 29947c478bd9Sstevel@tonic-gate return; 29957c478bd9Sstevel@tonic-gate } 29967c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_nwiftab.zone_nwif_physical, 29977c478bd9Sstevel@tonic-gate prop_id, 29987c478bd9Sstevel@tonic-gate sizeof (in_progress_nwiftab.zone_nwif_physical)); 29997c478bd9Sstevel@tonic-gate break; 30007c478bd9Sstevel@tonic-gate default: 30017c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 30027c478bd9Sstevel@tonic-gate TRUE); 30037c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 30047c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 30057c478bd9Sstevel@tonic-gate return; 30067c478bd9Sstevel@tonic-gate } 30077c478bd9Sstevel@tonic-gate return; 30087c478bd9Sstevel@tonic-gate case RT_DEVICE: 30097c478bd9Sstevel@tonic-gate switch (prop_type) { 30107c478bd9Sstevel@tonic-gate case PT_MATCH: 30117c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_devtab.zone_dev_match, 30127c478bd9Sstevel@tonic-gate prop_id, 30137c478bd9Sstevel@tonic-gate sizeof (in_progress_devtab.zone_dev_match)); 30147c478bd9Sstevel@tonic-gate break; 30157c478bd9Sstevel@tonic-gate default: 30167c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 30177c478bd9Sstevel@tonic-gate TRUE); 30187c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 30197c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 30207c478bd9Sstevel@tonic-gate return; 30217c478bd9Sstevel@tonic-gate } 30227c478bd9Sstevel@tonic-gate return; 30237c478bd9Sstevel@tonic-gate case RT_RCTL: 30247c478bd9Sstevel@tonic-gate switch (prop_type) { 30257c478bd9Sstevel@tonic-gate case PT_NAME: 30267c478bd9Sstevel@tonic-gate if (!zonecfg_valid_rctlname(prop_id)) { 30277c478bd9Sstevel@tonic-gate zerr(gettext("'%s' is not a valid zone %s " 30287c478bd9Sstevel@tonic-gate "name."), prop_id, rt_to_str(RT_RCTL)); 30297c478bd9Sstevel@tonic-gate return; 30307c478bd9Sstevel@tonic-gate } 30317c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_rctltab.zone_rctl_name, 30327c478bd9Sstevel@tonic-gate prop_id, 30337c478bd9Sstevel@tonic-gate sizeof (in_progress_rctltab.zone_rctl_name)); 30347c478bd9Sstevel@tonic-gate break; 30357c478bd9Sstevel@tonic-gate case PT_VALUE: 30367c478bd9Sstevel@tonic-gate if (pp->pv_type != PROP_VAL_COMPLEX && 30377c478bd9Sstevel@tonic-gate pp->pv_type != PROP_VAL_LIST) { 30387c478bd9Sstevel@tonic-gate zerr(gettext("A %s or %s value was expected " 30397c478bd9Sstevel@tonic-gate "here."), pvt_to_str(PROP_VAL_COMPLEX), 30407c478bd9Sstevel@tonic-gate pvt_to_str(PROP_VAL_LIST)); 30417c478bd9Sstevel@tonic-gate saw_error = TRUE; 30427c478bd9Sstevel@tonic-gate return; 30437c478bd9Sstevel@tonic-gate } 30447c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list( 30457c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_valptr); 30467c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_valptr = NULL; 30477c478bd9Sstevel@tonic-gate if (!(pp->pv_type == PROP_VAL_LIST && 30487c478bd9Sstevel@tonic-gate pp->pv_list == NULL)) 30497c478bd9Sstevel@tonic-gate add_property(cmd); 30507c478bd9Sstevel@tonic-gate break; 30517c478bd9Sstevel@tonic-gate default: 30527c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 30537c478bd9Sstevel@tonic-gate TRUE); 30547c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 30557c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 30567c478bd9Sstevel@tonic-gate return; 30577c478bd9Sstevel@tonic-gate } 30587c478bd9Sstevel@tonic-gate return; 30597c478bd9Sstevel@tonic-gate case RT_ATTR: 30607c478bd9Sstevel@tonic-gate switch (prop_type) { 30617c478bd9Sstevel@tonic-gate case PT_NAME: 30627c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_attrtab.zone_attr_name, 30637c478bd9Sstevel@tonic-gate prop_id, 30647c478bd9Sstevel@tonic-gate sizeof (in_progress_attrtab.zone_attr_name)); 30657c478bd9Sstevel@tonic-gate break; 30667c478bd9Sstevel@tonic-gate case PT_TYPE: 30677c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_attrtab.zone_attr_type, 30687c478bd9Sstevel@tonic-gate prop_id, 30697c478bd9Sstevel@tonic-gate sizeof (in_progress_attrtab.zone_attr_type)); 30707c478bd9Sstevel@tonic-gate break; 30717c478bd9Sstevel@tonic-gate case PT_VALUE: 30727c478bd9Sstevel@tonic-gate (void) strlcpy(in_progress_attrtab.zone_attr_value, 30737c478bd9Sstevel@tonic-gate prop_id, 30747c478bd9Sstevel@tonic-gate sizeof (in_progress_attrtab.zone_attr_value)); 30757c478bd9Sstevel@tonic-gate break; 30767c478bd9Sstevel@tonic-gate default: 30777c478bd9Sstevel@tonic-gate zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, 30787c478bd9Sstevel@tonic-gate TRUE); 30797c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 30807c478bd9Sstevel@tonic-gate usage(FALSE, HELP_PROPS); 30817c478bd9Sstevel@tonic-gate return; 30827c478bd9Sstevel@tonic-gate } 30837c478bd9Sstevel@tonic-gate return; 3084fa9e4066Sahrens case RT_DATASET: 3085fa9e4066Sahrens switch (prop_type) { 3086fa9e4066Sahrens case PT_NAME: 3087fa9e4066Sahrens (void) strlcpy(in_progress_dstab.zone_dataset_name, 3088fa9e4066Sahrens prop_id, 3089fa9e4066Sahrens sizeof (in_progress_dstab.zone_dataset_name)); 3090fa9e4066Sahrens return; 3091fa9e4066Sahrens default: 3092fa9e4066Sahrens break; 3093fa9e4066Sahrens } 3094fa9e4066Sahrens zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, TRUE); 3095fa9e4066Sahrens long_usage(CMD_SET, TRUE); 3096fa9e4066Sahrens usage(FALSE, HELP_PROPS); 3097fa9e4066Sahrens return; 30987c478bd9Sstevel@tonic-gate default: 30997c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, TRUE); 31007c478bd9Sstevel@tonic-gate long_usage(CMD_SET, TRUE); 31017c478bd9Sstevel@tonic-gate usage(FALSE, HELP_RESOURCES); 31027c478bd9Sstevel@tonic-gate return; 31037c478bd9Sstevel@tonic-gate } 31047c478bd9Sstevel@tonic-gate } 31057c478bd9Sstevel@tonic-gate 31067c478bd9Sstevel@tonic-gate static void 31077c478bd9Sstevel@tonic-gate output_prop(FILE *fp, int pnum, char *pval, bool print_notspec) 31087c478bd9Sstevel@tonic-gate { 31097c478bd9Sstevel@tonic-gate char *qstr; 31107c478bd9Sstevel@tonic-gate 31117c478bd9Sstevel@tonic-gate if (*pval != '\0') { 31127c478bd9Sstevel@tonic-gate qstr = quoteit(pval); 31137c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s: %s\n", pt_to_str(pnum), qstr); 31147c478bd9Sstevel@tonic-gate free(qstr); 31157c478bd9Sstevel@tonic-gate } else if (print_notspec) 3116087719fdSdp (void) fprintf(fp, gettext("\t%s not specified\n"), 3117087719fdSdp pt_to_str(pnum)); 3118087719fdSdp } 3119087719fdSdp 3120087719fdSdp static void 3121087719fdSdp info_zonename(zone_dochandle_t handle, FILE *fp) 3122087719fdSdp { 3123087719fdSdp char zonename[ZONENAME_MAX]; 3124087719fdSdp 3125087719fdSdp if (zonecfg_get_name(handle, zonename, sizeof (zonename)) == Z_OK) 3126087719fdSdp (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONENAME), 3127087719fdSdp zonename); 3128087719fdSdp else 3129087719fdSdp (void) fprintf(fp, gettext("%s not specified\n"), 3130087719fdSdp pt_to_str(PT_ZONENAME)); 31317c478bd9Sstevel@tonic-gate } 31327c478bd9Sstevel@tonic-gate 31337c478bd9Sstevel@tonic-gate static void 31347c478bd9Sstevel@tonic-gate info_zonepath(zone_dochandle_t handle, FILE *fp) 31357c478bd9Sstevel@tonic-gate { 31367c478bd9Sstevel@tonic-gate char zonepath[MAXPATHLEN]; 31377c478bd9Sstevel@tonic-gate 31387c478bd9Sstevel@tonic-gate if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) == Z_OK) 31397c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_ZONEPATH), 31407c478bd9Sstevel@tonic-gate zonepath); 3141087719fdSdp else { 3142087719fdSdp (void) fprintf(fp, gettext("%s not specified\n"), 3143087719fdSdp pt_to_str(PT_ZONEPATH)); 3144087719fdSdp } 31457c478bd9Sstevel@tonic-gate } 31467c478bd9Sstevel@tonic-gate 3147*9acbbeafSnn static void 3148*9acbbeafSnn info_brand(zone_dochandle_t handle, FILE *fp) 3149*9acbbeafSnn { 3150*9acbbeafSnn char brand[MAXNAMELEN]; 3151*9acbbeafSnn 3152*9acbbeafSnn if (zonecfg_get_brand(handle, brand, sizeof (brand)) == Z_OK) 3153*9acbbeafSnn (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BRAND), 3154*9acbbeafSnn brand); 3155*9acbbeafSnn else 3156*9acbbeafSnn (void) fprintf(fp, "%s %s\n", pt_to_str(PT_BRAND), 3157*9acbbeafSnn gettext("not specified")); 3158*9acbbeafSnn } 3159*9acbbeafSnn 31607c478bd9Sstevel@tonic-gate static void 31617c478bd9Sstevel@tonic-gate info_autoboot(zone_dochandle_t handle, FILE *fp) 31627c478bd9Sstevel@tonic-gate { 31637c478bd9Sstevel@tonic-gate boolean_t autoboot; 31647c478bd9Sstevel@tonic-gate int err; 31657c478bd9Sstevel@tonic-gate 31667c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_autoboot(handle, &autoboot)) == Z_OK) 31677c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_AUTOBOOT), 31687c478bd9Sstevel@tonic-gate autoboot ? "true" : "false"); 31697c478bd9Sstevel@tonic-gate else 31707c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 31717c478bd9Sstevel@tonic-gate } 31727c478bd9Sstevel@tonic-gate 31737c478bd9Sstevel@tonic-gate static void 31747c478bd9Sstevel@tonic-gate info_pool(zone_dochandle_t handle, FILE *fp) 31757c478bd9Sstevel@tonic-gate { 31767c478bd9Sstevel@tonic-gate char pool[MAXNAMELEN]; 31777c478bd9Sstevel@tonic-gate int err; 31787c478bd9Sstevel@tonic-gate 31797c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_pool(handle, pool, sizeof (pool))) == Z_OK) 31807c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_POOL), pool); 31817c478bd9Sstevel@tonic-gate else 31827c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 31837c478bd9Sstevel@tonic-gate } 31847c478bd9Sstevel@tonic-gate 3185ffbafc53Scomay static void 3186ffbafc53Scomay info_limitpriv(zone_dochandle_t handle, FILE *fp) 3187ffbafc53Scomay { 3188ffbafc53Scomay char *limitpriv; 3189ffbafc53Scomay int err; 3190ffbafc53Scomay 3191ffbafc53Scomay if ((err = zonecfg_get_limitpriv(handle, &limitpriv)) == Z_OK) { 3192ffbafc53Scomay (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_LIMITPRIV), 3193ffbafc53Scomay limitpriv); 3194ffbafc53Scomay free(limitpriv); 3195ffbafc53Scomay } else { 3196ffbafc53Scomay zone_perror(zone, err, TRUE); 3197ffbafc53Scomay } 3198ffbafc53Scomay } 3199ffbafc53Scomay 32003f2f09c1Sdp static void 32013f2f09c1Sdp info_bootargs(zone_dochandle_t handle, FILE *fp) 32023f2f09c1Sdp { 32033f2f09c1Sdp char bootargs[BOOTARGS_MAX]; 32043f2f09c1Sdp int err; 32053f2f09c1Sdp 32063f2f09c1Sdp if ((err = zonecfg_get_bootargs(handle, bootargs, 32073f2f09c1Sdp sizeof (bootargs))) == Z_OK) { 32083f2f09c1Sdp (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_BOOTARGS), 32093f2f09c1Sdp bootargs); 32103f2f09c1Sdp } else { 32113f2f09c1Sdp zone_perror(zone, err, TRUE); 32123f2f09c1Sdp } 32133f2f09c1Sdp } 32143f2f09c1Sdp 32157c478bd9Sstevel@tonic-gate static void 32167c478bd9Sstevel@tonic-gate output_fs(FILE *fp, struct zone_fstab *fstab) 32177c478bd9Sstevel@tonic-gate { 32187c478bd9Sstevel@tonic-gate zone_fsopt_t *this; 32197c478bd9Sstevel@tonic-gate 32207c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n", rt_to_str(RT_FS)); 32217c478bd9Sstevel@tonic-gate output_prop(fp, PT_DIR, fstab->zone_fs_dir, B_TRUE); 32227c478bd9Sstevel@tonic-gate output_prop(fp, PT_SPECIAL, fstab->zone_fs_special, B_TRUE); 32237c478bd9Sstevel@tonic-gate output_prop(fp, PT_RAW, fstab->zone_fs_raw, B_TRUE); 32247c478bd9Sstevel@tonic-gate output_prop(fp, PT_TYPE, fstab->zone_fs_type, B_TRUE); 32257c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\t%s: [", pt_to_str(PT_OPTIONS)); 32267c478bd9Sstevel@tonic-gate for (this = fstab->zone_fs_options; this != NULL; 32277c478bd9Sstevel@tonic-gate this = this->zone_fsopt_next) { 32287c478bd9Sstevel@tonic-gate if (strchr(this->zone_fsopt_opt, '=')) 32297c478bd9Sstevel@tonic-gate (void) fprintf(fp, "\"%s\"", this->zone_fsopt_opt); 32307c478bd9Sstevel@tonic-gate else 32317c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s", this->zone_fsopt_opt); 32327c478bd9Sstevel@tonic-gate if (this->zone_fsopt_next != NULL) 32337c478bd9Sstevel@tonic-gate (void) fprintf(fp, ","); 32347c478bd9Sstevel@tonic-gate } 32357c478bd9Sstevel@tonic-gate (void) fprintf(fp, "]\n"); 32367c478bd9Sstevel@tonic-gate } 32377c478bd9Sstevel@tonic-gate 32387c478bd9Sstevel@tonic-gate static void 32397c478bd9Sstevel@tonic-gate output_ipd(FILE *fp, struct zone_fstab *ipdtab) 32407c478bd9Sstevel@tonic-gate { 32417c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n", rt_to_str(RT_IPD)); 32427c478bd9Sstevel@tonic-gate output_prop(fp, PT_DIR, ipdtab->zone_fs_dir, B_TRUE); 32437c478bd9Sstevel@tonic-gate } 32447c478bd9Sstevel@tonic-gate 32457c478bd9Sstevel@tonic-gate static void 32467c478bd9Sstevel@tonic-gate info_fs(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 32477c478bd9Sstevel@tonic-gate { 32487c478bd9Sstevel@tonic-gate struct zone_fstab lookup, user; 32497c478bd9Sstevel@tonic-gate bool output = FALSE; 32507c478bd9Sstevel@tonic-gate 32517c478bd9Sstevel@tonic-gate if (zonecfg_setfsent(handle) != Z_OK) 32527c478bd9Sstevel@tonic-gate return; 32537c478bd9Sstevel@tonic-gate while (zonecfg_getfsent(handle, &lookup) == Z_OK) { 32547c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 32557c478bd9Sstevel@tonic-gate output_fs(fp, &lookup); 32567c478bd9Sstevel@tonic-gate goto loopend; 32577c478bd9Sstevel@tonic-gate } 32587c478bd9Sstevel@tonic-gate if (fill_in_fstab(cmd, &user, TRUE) != Z_OK) 32597c478bd9Sstevel@tonic-gate goto loopend; 32607c478bd9Sstevel@tonic-gate if (strlen(user.zone_fs_dir) > 0 && 32617c478bd9Sstevel@tonic-gate strcmp(user.zone_fs_dir, lookup.zone_fs_dir) != 0) 32627c478bd9Sstevel@tonic-gate goto loopend; /* no match */ 32637c478bd9Sstevel@tonic-gate if (strlen(user.zone_fs_special) > 0 && 32647c478bd9Sstevel@tonic-gate strcmp(user.zone_fs_special, lookup.zone_fs_special) != 0) 32657c478bd9Sstevel@tonic-gate goto loopend; /* no match */ 32667c478bd9Sstevel@tonic-gate if (strlen(user.zone_fs_type) > 0 && 32677c478bd9Sstevel@tonic-gate strcmp(user.zone_fs_type, lookup.zone_fs_type) != 0) 32687c478bd9Sstevel@tonic-gate goto loopend; /* no match */ 32697c478bd9Sstevel@tonic-gate output_fs(fp, &lookup); 32707c478bd9Sstevel@tonic-gate output = TRUE; 32717c478bd9Sstevel@tonic-gate loopend: 32727c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(lookup.zone_fs_options); 32737c478bd9Sstevel@tonic-gate } 32747c478bd9Sstevel@tonic-gate (void) zonecfg_endfsent(handle); 32757c478bd9Sstevel@tonic-gate /* 32767c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 32777c478bd9Sstevel@tonic-gate * nothing to output. 32787c478bd9Sstevel@tonic-gate */ 32797c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 32807c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 32817c478bd9Sstevel@tonic-gate rt_to_str(RT_FS)); 32827c478bd9Sstevel@tonic-gate } 32837c478bd9Sstevel@tonic-gate 32847c478bd9Sstevel@tonic-gate static void 32857c478bd9Sstevel@tonic-gate info_ipd(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 32867c478bd9Sstevel@tonic-gate { 32877c478bd9Sstevel@tonic-gate struct zone_fstab lookup, user; 32887c478bd9Sstevel@tonic-gate bool output = FALSE; 32897c478bd9Sstevel@tonic-gate 32907c478bd9Sstevel@tonic-gate if (zonecfg_setipdent(handle) != Z_OK) 32917c478bd9Sstevel@tonic-gate return; 32927c478bd9Sstevel@tonic-gate while (zonecfg_getipdent(handle, &lookup) == Z_OK) { 32937c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 32947c478bd9Sstevel@tonic-gate output_ipd(fp, &lookup); 32957c478bd9Sstevel@tonic-gate continue; 32967c478bd9Sstevel@tonic-gate } 32977c478bd9Sstevel@tonic-gate if (fill_in_ipdtab(cmd, &user, TRUE) != Z_OK) 32987c478bd9Sstevel@tonic-gate continue; 32997c478bd9Sstevel@tonic-gate if (strlen(user.zone_fs_dir) > 0 && 33007c478bd9Sstevel@tonic-gate strcmp(user.zone_fs_dir, lookup.zone_fs_dir) != 0) 33017c478bd9Sstevel@tonic-gate continue; /* no match */ 33027c478bd9Sstevel@tonic-gate output_ipd(fp, &lookup); 33037c478bd9Sstevel@tonic-gate output = TRUE; 33047c478bd9Sstevel@tonic-gate } 33057c478bd9Sstevel@tonic-gate (void) zonecfg_endipdent(handle); 33067c478bd9Sstevel@tonic-gate /* 33077c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 33087c478bd9Sstevel@tonic-gate * nothing to output. 33097c478bd9Sstevel@tonic-gate */ 33107c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 33117c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 33127c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD)); 33137c478bd9Sstevel@tonic-gate } 33147c478bd9Sstevel@tonic-gate 33157c478bd9Sstevel@tonic-gate static void 33167c478bd9Sstevel@tonic-gate output_net(FILE *fp, struct zone_nwiftab *nwiftab) 33177c478bd9Sstevel@tonic-gate { 33187c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET)); 33197c478bd9Sstevel@tonic-gate output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE); 33207c478bd9Sstevel@tonic-gate output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE); 33217c478bd9Sstevel@tonic-gate } 33227c478bd9Sstevel@tonic-gate 33237c478bd9Sstevel@tonic-gate static void 33247c478bd9Sstevel@tonic-gate info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 33257c478bd9Sstevel@tonic-gate { 33267c478bd9Sstevel@tonic-gate struct zone_nwiftab lookup, user; 33277c478bd9Sstevel@tonic-gate bool output = FALSE; 33287c478bd9Sstevel@tonic-gate 33297c478bd9Sstevel@tonic-gate if (zonecfg_setnwifent(handle) != Z_OK) 33307c478bd9Sstevel@tonic-gate return; 33317c478bd9Sstevel@tonic-gate while (zonecfg_getnwifent(handle, &lookup) == Z_OK) { 33327c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 33337c478bd9Sstevel@tonic-gate output_net(fp, &lookup); 33347c478bd9Sstevel@tonic-gate continue; 33357c478bd9Sstevel@tonic-gate } 33367c478bd9Sstevel@tonic-gate if (fill_in_nwiftab(cmd, &user, TRUE) != Z_OK) 33377c478bd9Sstevel@tonic-gate continue; 33387c478bd9Sstevel@tonic-gate if (strlen(user.zone_nwif_physical) > 0 && 33397c478bd9Sstevel@tonic-gate strcmp(user.zone_nwif_physical, 33407c478bd9Sstevel@tonic-gate lookup.zone_nwif_physical) != 0) 33417c478bd9Sstevel@tonic-gate continue; /* no match */ 33427c478bd9Sstevel@tonic-gate if (strlen(user.zone_nwif_address) > 0 && 33437c478bd9Sstevel@tonic-gate !zonecfg_same_net_address(user.zone_nwif_address, 33447c478bd9Sstevel@tonic-gate lookup.zone_nwif_address)) 33457c478bd9Sstevel@tonic-gate continue; /* no match */ 33467c478bd9Sstevel@tonic-gate output_net(fp, &lookup); 33477c478bd9Sstevel@tonic-gate output = TRUE; 33487c478bd9Sstevel@tonic-gate } 33497c478bd9Sstevel@tonic-gate (void) zonecfg_endnwifent(handle); 33507c478bd9Sstevel@tonic-gate /* 33517c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 33527c478bd9Sstevel@tonic-gate * nothing to output. 33537c478bd9Sstevel@tonic-gate */ 33547c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 33557c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 33567c478bd9Sstevel@tonic-gate rt_to_str(RT_NET)); 33577c478bd9Sstevel@tonic-gate } 33587c478bd9Sstevel@tonic-gate 33597c478bd9Sstevel@tonic-gate static void 33607c478bd9Sstevel@tonic-gate output_dev(FILE *fp, struct zone_devtab *devtab) 33617c478bd9Sstevel@tonic-gate { 33627c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s\n", rt_to_str(RT_DEVICE)); 33637c478bd9Sstevel@tonic-gate output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE); 33647c478bd9Sstevel@tonic-gate } 33657c478bd9Sstevel@tonic-gate 33667c478bd9Sstevel@tonic-gate static void 33677c478bd9Sstevel@tonic-gate info_dev(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 33687c478bd9Sstevel@tonic-gate { 33697c478bd9Sstevel@tonic-gate struct zone_devtab lookup, user; 33707c478bd9Sstevel@tonic-gate bool output = FALSE; 33717c478bd9Sstevel@tonic-gate 33727c478bd9Sstevel@tonic-gate if (zonecfg_setdevent(handle) != Z_OK) 33737c478bd9Sstevel@tonic-gate return; 33747c478bd9Sstevel@tonic-gate while (zonecfg_getdevent(handle, &lookup) == Z_OK) { 33757c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 33767c478bd9Sstevel@tonic-gate output_dev(fp, &lookup); 33777c478bd9Sstevel@tonic-gate continue; 33787c478bd9Sstevel@tonic-gate } 33797c478bd9Sstevel@tonic-gate if (fill_in_devtab(cmd, &user, TRUE) != Z_OK) 33807c478bd9Sstevel@tonic-gate continue; 33817c478bd9Sstevel@tonic-gate if (strlen(user.zone_dev_match) > 0 && 33827c478bd9Sstevel@tonic-gate strcmp(user.zone_dev_match, lookup.zone_dev_match) != 0) 33837c478bd9Sstevel@tonic-gate continue; /* no match */ 33847c478bd9Sstevel@tonic-gate output_dev(fp, &lookup); 33857c478bd9Sstevel@tonic-gate output = TRUE; 33867c478bd9Sstevel@tonic-gate } 33877c478bd9Sstevel@tonic-gate (void) zonecfg_enddevent(handle); 33887c478bd9Sstevel@tonic-gate /* 33897c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 33907c478bd9Sstevel@tonic-gate * nothing to output. 33917c478bd9Sstevel@tonic-gate */ 33927c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 33937c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 33947c478bd9Sstevel@tonic-gate rt_to_str(RT_DEVICE)); 33957c478bd9Sstevel@tonic-gate } 33967c478bd9Sstevel@tonic-gate 33977c478bd9Sstevel@tonic-gate static void 33987c478bd9Sstevel@tonic-gate output_rctl(FILE *fp, struct zone_rctltab *rctltab) 33997c478bd9Sstevel@tonic-gate { 34007c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valptr; 34017c478bd9Sstevel@tonic-gate 34027c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n", rt_to_str(RT_RCTL)); 34037c478bd9Sstevel@tonic-gate output_prop(fp, PT_NAME, rctltab->zone_rctl_name, B_TRUE); 34047c478bd9Sstevel@tonic-gate for (valptr = rctltab->zone_rctl_valptr; valptr != NULL; 34057c478bd9Sstevel@tonic-gate valptr = valptr->zone_rctlval_next) { 34067c478bd9Sstevel@tonic-gate fprintf(fp, "\t%s: (%s=%s,%s=%s,%s=%s)\n", 34077c478bd9Sstevel@tonic-gate pt_to_str(PT_VALUE), 34087c478bd9Sstevel@tonic-gate pt_to_str(PT_PRIV), valptr->zone_rctlval_priv, 34097c478bd9Sstevel@tonic-gate pt_to_str(PT_LIMIT), valptr->zone_rctlval_limit, 34107c478bd9Sstevel@tonic-gate pt_to_str(PT_ACTION), valptr->zone_rctlval_action); 34117c478bd9Sstevel@tonic-gate } 34127c478bd9Sstevel@tonic-gate } 34137c478bd9Sstevel@tonic-gate 34147c478bd9Sstevel@tonic-gate static void 34157c478bd9Sstevel@tonic-gate info_rctl(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 34167c478bd9Sstevel@tonic-gate { 34177c478bd9Sstevel@tonic-gate struct zone_rctltab lookup, user; 34187c478bd9Sstevel@tonic-gate bool output = FALSE; 34197c478bd9Sstevel@tonic-gate 34207c478bd9Sstevel@tonic-gate if (zonecfg_setrctlent(handle) != Z_OK) 34217c478bd9Sstevel@tonic-gate return; 34227c478bd9Sstevel@tonic-gate while (zonecfg_getrctlent(handle, &lookup) == Z_OK) { 34237c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 34247c478bd9Sstevel@tonic-gate output_rctl(fp, &lookup); 34257c478bd9Sstevel@tonic-gate } else if (fill_in_rctltab(cmd, &user, TRUE) == Z_OK && 34267c478bd9Sstevel@tonic-gate (strlen(user.zone_rctl_name) == 0 || 34277c478bd9Sstevel@tonic-gate strcmp(user.zone_rctl_name, lookup.zone_rctl_name) == 0)) { 34287c478bd9Sstevel@tonic-gate output_rctl(fp, &lookup); 34297c478bd9Sstevel@tonic-gate output = TRUE; 34307c478bd9Sstevel@tonic-gate } 34317c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(lookup.zone_rctl_valptr); 34327c478bd9Sstevel@tonic-gate } 34337c478bd9Sstevel@tonic-gate (void) zonecfg_endrctlent(handle); 34347c478bd9Sstevel@tonic-gate /* 34357c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 34367c478bd9Sstevel@tonic-gate * nothing to output. 34377c478bd9Sstevel@tonic-gate */ 34387c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 34397c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 34407c478bd9Sstevel@tonic-gate rt_to_str(RT_RCTL)); 34417c478bd9Sstevel@tonic-gate } 34427c478bd9Sstevel@tonic-gate 34437c478bd9Sstevel@tonic-gate static void 34447c478bd9Sstevel@tonic-gate output_attr(FILE *fp, struct zone_attrtab *attrtab) 34457c478bd9Sstevel@tonic-gate { 34467c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:\n", rt_to_str(RT_ATTR)); 34477c478bd9Sstevel@tonic-gate output_prop(fp, PT_NAME, attrtab->zone_attr_name, B_TRUE); 34487c478bd9Sstevel@tonic-gate output_prop(fp, PT_TYPE, attrtab->zone_attr_type, B_TRUE); 34497c478bd9Sstevel@tonic-gate output_prop(fp, PT_VALUE, attrtab->zone_attr_value, B_TRUE); 34507c478bd9Sstevel@tonic-gate } 34517c478bd9Sstevel@tonic-gate 34527c478bd9Sstevel@tonic-gate static void 34537c478bd9Sstevel@tonic-gate info_attr(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 34547c478bd9Sstevel@tonic-gate { 34557c478bd9Sstevel@tonic-gate struct zone_attrtab lookup, user; 34567c478bd9Sstevel@tonic-gate bool output = FALSE; 34577c478bd9Sstevel@tonic-gate 34587c478bd9Sstevel@tonic-gate if (zonecfg_setattrent(handle) != Z_OK) 34597c478bd9Sstevel@tonic-gate return; 34607c478bd9Sstevel@tonic-gate while (zonecfg_getattrent(handle, &lookup) == Z_OK) { 34617c478bd9Sstevel@tonic-gate if (cmd->cmd_prop_nv_pairs == 0) { 34627c478bd9Sstevel@tonic-gate output_attr(fp, &lookup); 34637c478bd9Sstevel@tonic-gate continue; 34647c478bd9Sstevel@tonic-gate } 34657c478bd9Sstevel@tonic-gate if (fill_in_attrtab(cmd, &user, TRUE) != Z_OK) 34667c478bd9Sstevel@tonic-gate continue; 34677c478bd9Sstevel@tonic-gate if (strlen(user.zone_attr_name) > 0 && 34687c478bd9Sstevel@tonic-gate strcmp(user.zone_attr_name, lookup.zone_attr_name) != 0) 34697c478bd9Sstevel@tonic-gate continue; /* no match */ 34707c478bd9Sstevel@tonic-gate if (strlen(user.zone_attr_type) > 0 && 34717c478bd9Sstevel@tonic-gate strcmp(user.zone_attr_type, lookup.zone_attr_type) != 0) 34727c478bd9Sstevel@tonic-gate continue; /* no match */ 34737c478bd9Sstevel@tonic-gate if (strlen(user.zone_attr_value) > 0 && 34747c478bd9Sstevel@tonic-gate strcmp(user.zone_attr_value, lookup.zone_attr_value) != 0) 34757c478bd9Sstevel@tonic-gate continue; /* no match */ 34767c478bd9Sstevel@tonic-gate output_attr(fp, &lookup); 34777c478bd9Sstevel@tonic-gate output = TRUE; 34787c478bd9Sstevel@tonic-gate } 34797c478bd9Sstevel@tonic-gate (void) zonecfg_endattrent(handle); 34807c478bd9Sstevel@tonic-gate /* 34817c478bd9Sstevel@tonic-gate * If a property n/v pair was specified, warn the user if there was 34827c478bd9Sstevel@tonic-gate * nothing to output. 34837c478bd9Sstevel@tonic-gate */ 34847c478bd9Sstevel@tonic-gate if (!output && cmd->cmd_prop_nv_pairs > 0) 34857c478bd9Sstevel@tonic-gate (void) printf(gettext("No such %s resource.\n"), 34867c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR)); 34877c478bd9Sstevel@tonic-gate } 34887c478bd9Sstevel@tonic-gate 3489fa9e4066Sahrens static void 3490fa9e4066Sahrens output_ds(FILE *fp, struct zone_dstab *dstab) 3491fa9e4066Sahrens { 3492fa9e4066Sahrens (void) fprintf(fp, "%s:\n", rt_to_str(RT_DATASET)); 3493fa9e4066Sahrens output_prop(fp, PT_NAME, dstab->zone_dataset_name, B_TRUE); 3494fa9e4066Sahrens } 3495fa9e4066Sahrens 3496fa9e4066Sahrens static void 3497fa9e4066Sahrens info_ds(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) 3498fa9e4066Sahrens { 3499fa9e4066Sahrens struct zone_dstab lookup, user; 3500fa9e4066Sahrens bool output = FALSE; 3501fa9e4066Sahrens 3502fa9e4066Sahrens if (zonecfg_setdevent(handle) != Z_OK) 3503fa9e4066Sahrens return; 3504fa9e4066Sahrens while (zonecfg_getdsent(handle, &lookup) == Z_OK) { 3505fa9e4066Sahrens if (cmd->cmd_prop_nv_pairs == 0) { 3506fa9e4066Sahrens output_ds(fp, &lookup); 3507fa9e4066Sahrens continue; 3508fa9e4066Sahrens } 3509fa9e4066Sahrens if (fill_in_dstab(cmd, &user, TRUE) != Z_OK) 3510fa9e4066Sahrens continue; 3511fa9e4066Sahrens if (strlen(user.zone_dataset_name) > 0 && 3512fa9e4066Sahrens strcmp(user.zone_dataset_name, 3513fa9e4066Sahrens lookup.zone_dataset_name) != 0) 3514fa9e4066Sahrens continue; /* no match */ 3515fa9e4066Sahrens output_ds(fp, &lookup); 3516fa9e4066Sahrens output = TRUE; 3517fa9e4066Sahrens } 3518fa9e4066Sahrens (void) zonecfg_enddsent(handle); 3519fa9e4066Sahrens /* 3520fa9e4066Sahrens * If a property n/v pair was specified, warn the user if there was 3521fa9e4066Sahrens * nothing to output. 3522fa9e4066Sahrens */ 3523fa9e4066Sahrens if (!output && cmd->cmd_prop_nv_pairs > 0) 3524fa9e4066Sahrens (void) printf(gettext("No such %s resource.\n"), 3525fa9e4066Sahrens rt_to_str(RT_DATASET)); 3526fa9e4066Sahrens } 3527fa9e4066Sahrens 35287c478bd9Sstevel@tonic-gate void 35297c478bd9Sstevel@tonic-gate info_func(cmd_t *cmd) 35307c478bd9Sstevel@tonic-gate { 35317c478bd9Sstevel@tonic-gate FILE *fp = stdout; 35327c478bd9Sstevel@tonic-gate bool need_to_close = FALSE; 35337c478bd9Sstevel@tonic-gate char *pager; 35347c478bd9Sstevel@tonic-gate 35357c478bd9Sstevel@tonic-gate assert(cmd != NULL); 35367c478bd9Sstevel@tonic-gate 35377c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 35387c478bd9Sstevel@tonic-gate return; 35397c478bd9Sstevel@tonic-gate 35407c478bd9Sstevel@tonic-gate /* don't page error output */ 35417c478bd9Sstevel@tonic-gate if (interactive_mode) { 35427c478bd9Sstevel@tonic-gate if ((pager = getenv("PAGER")) == NULL) 35437c478bd9Sstevel@tonic-gate pager = PAGER; 35447c478bd9Sstevel@tonic-gate if ((fp = popen(pager, "w")) != NULL) 35457c478bd9Sstevel@tonic-gate need_to_close = TRUE; 35467c478bd9Sstevel@tonic-gate setbuf(fp, NULL); 35477c478bd9Sstevel@tonic-gate } 35487c478bd9Sstevel@tonic-gate 35497c478bd9Sstevel@tonic-gate if (!global_scope) { 35507c478bd9Sstevel@tonic-gate switch (resource_scope) { 35517c478bd9Sstevel@tonic-gate case RT_FS: 35527c478bd9Sstevel@tonic-gate output_fs(fp, &in_progress_fstab); 35537c478bd9Sstevel@tonic-gate break; 35547c478bd9Sstevel@tonic-gate case RT_IPD: 35557c478bd9Sstevel@tonic-gate output_ipd(fp, &in_progress_ipdtab); 35567c478bd9Sstevel@tonic-gate break; 35577c478bd9Sstevel@tonic-gate case RT_NET: 35587c478bd9Sstevel@tonic-gate output_net(fp, &in_progress_nwiftab); 35597c478bd9Sstevel@tonic-gate break; 35607c478bd9Sstevel@tonic-gate case RT_DEVICE: 35617c478bd9Sstevel@tonic-gate output_dev(fp, &in_progress_devtab); 35627c478bd9Sstevel@tonic-gate break; 35637c478bd9Sstevel@tonic-gate case RT_RCTL: 35647c478bd9Sstevel@tonic-gate output_rctl(fp, &in_progress_rctltab); 35657c478bd9Sstevel@tonic-gate break; 35667c478bd9Sstevel@tonic-gate case RT_ATTR: 35677c478bd9Sstevel@tonic-gate output_attr(fp, &in_progress_attrtab); 35687c478bd9Sstevel@tonic-gate break; 3569fa9e4066Sahrens case RT_DATASET: 3570fa9e4066Sahrens output_ds(fp, &in_progress_dstab); 3571fa9e4066Sahrens break; 35727c478bd9Sstevel@tonic-gate } 35737c478bd9Sstevel@tonic-gate goto cleanup; 35747c478bd9Sstevel@tonic-gate } 35757c478bd9Sstevel@tonic-gate 35767c478bd9Sstevel@tonic-gate switch (cmd->cmd_res_type) { 35777c478bd9Sstevel@tonic-gate case RT_UNKNOWN: 3578087719fdSdp info_zonename(handle, fp); 35797c478bd9Sstevel@tonic-gate info_zonepath(handle, fp); 3580*9acbbeafSnn info_brand(handle, fp); 35817c478bd9Sstevel@tonic-gate info_autoboot(handle, fp); 35823f2f09c1Sdp info_bootargs(handle, fp); 35837c478bd9Sstevel@tonic-gate info_pool(handle, fp); 3584ffbafc53Scomay info_limitpriv(handle, fp); 35857c478bd9Sstevel@tonic-gate info_ipd(handle, fp, cmd); 35867c478bd9Sstevel@tonic-gate info_fs(handle, fp, cmd); 35877c478bd9Sstevel@tonic-gate info_net(handle, fp, cmd); 35887c478bd9Sstevel@tonic-gate info_dev(handle, fp, cmd); 35897c478bd9Sstevel@tonic-gate info_rctl(handle, fp, cmd); 35907c478bd9Sstevel@tonic-gate info_attr(handle, fp, cmd); 3591fa9e4066Sahrens info_ds(handle, fp, cmd); 35927c478bd9Sstevel@tonic-gate break; 3593087719fdSdp case RT_ZONENAME: 3594087719fdSdp info_zonename(handle, fp); 3595087719fdSdp break; 35967c478bd9Sstevel@tonic-gate case RT_ZONEPATH: 35977c478bd9Sstevel@tonic-gate info_zonepath(handle, fp); 35987c478bd9Sstevel@tonic-gate break; 3599*9acbbeafSnn case RT_BRAND: 3600*9acbbeafSnn info_brand(handle, fp); 3601*9acbbeafSnn break; 36027c478bd9Sstevel@tonic-gate case RT_AUTOBOOT: 36037c478bd9Sstevel@tonic-gate info_autoboot(handle, fp); 36047c478bd9Sstevel@tonic-gate break; 36057c478bd9Sstevel@tonic-gate case RT_POOL: 36067c478bd9Sstevel@tonic-gate info_pool(handle, fp); 36077c478bd9Sstevel@tonic-gate break; 3608ffbafc53Scomay case RT_LIMITPRIV: 3609ffbafc53Scomay info_limitpriv(handle, fp); 3610ffbafc53Scomay break; 36113f2f09c1Sdp case RT_BOOTARGS: 36123f2f09c1Sdp info_bootargs(handle, fp); 36133f2f09c1Sdp break; 36147c478bd9Sstevel@tonic-gate case RT_FS: 36157c478bd9Sstevel@tonic-gate info_fs(handle, fp, cmd); 36167c478bd9Sstevel@tonic-gate break; 36177c478bd9Sstevel@tonic-gate case RT_IPD: 36187c478bd9Sstevel@tonic-gate info_ipd(handle, fp, cmd); 36197c478bd9Sstevel@tonic-gate break; 36207c478bd9Sstevel@tonic-gate case RT_NET: 36217c478bd9Sstevel@tonic-gate info_net(handle, fp, cmd); 36227c478bd9Sstevel@tonic-gate break; 36237c478bd9Sstevel@tonic-gate case RT_DEVICE: 36247c478bd9Sstevel@tonic-gate info_dev(handle, fp, cmd); 36257c478bd9Sstevel@tonic-gate break; 36267c478bd9Sstevel@tonic-gate case RT_RCTL: 36277c478bd9Sstevel@tonic-gate info_rctl(handle, fp, cmd); 36287c478bd9Sstevel@tonic-gate break; 36297c478bd9Sstevel@tonic-gate case RT_ATTR: 36307c478bd9Sstevel@tonic-gate info_attr(handle, fp, cmd); 36317c478bd9Sstevel@tonic-gate break; 3632fa9e4066Sahrens case RT_DATASET: 3633fa9e4066Sahrens info_ds(handle, fp, cmd); 3634fa9e4066Sahrens break; 36357c478bd9Sstevel@tonic-gate default: 36367c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE, 36377c478bd9Sstevel@tonic-gate TRUE); 36387c478bd9Sstevel@tonic-gate } 36397c478bd9Sstevel@tonic-gate 36407c478bd9Sstevel@tonic-gate cleanup: 36417c478bd9Sstevel@tonic-gate if (need_to_close) 36427c478bd9Sstevel@tonic-gate (void) pclose(fp); 36437c478bd9Sstevel@tonic-gate } 36447c478bd9Sstevel@tonic-gate 3645087719fdSdp /* 3646087719fdSdp * Helper function for verify-- checks that a required string property 3647087719fdSdp * exists. 3648087719fdSdp */ 3649087719fdSdp static void 3650087719fdSdp check_reqd_prop(char *attr, int rt, int pt, int *ret_val) 36517c478bd9Sstevel@tonic-gate { 3652087719fdSdp if (strlen(attr) == 0) { 3653087719fdSdp zerr(gettext("%s: %s not specified"), rt_to_str(rt), 3654087719fdSdp pt_to_str(pt)); 3655087719fdSdp saw_error = TRUE; 3656087719fdSdp if (*ret_val == Z_OK) 3657087719fdSdp *ret_val = Z_REQD_PROPERTY_MISSING; 36587c478bd9Sstevel@tonic-gate } 36597c478bd9Sstevel@tonic-gate } 36607c478bd9Sstevel@tonic-gate 3661*9acbbeafSnn static int 3662*9acbbeafSnn do_subproc(char *cmdbuf) 3663*9acbbeafSnn { 3664*9acbbeafSnn char inbuf[MAX_CMD_LEN]; 3665*9acbbeafSnn FILE *file; 3666*9acbbeafSnn int status; 3667*9acbbeafSnn 3668*9acbbeafSnn file = popen(cmdbuf, "r"); 3669*9acbbeafSnn if (file == NULL) { 3670*9acbbeafSnn zerr(gettext("Could not launch: %s"), cmdbuf); 3671*9acbbeafSnn return (-1); 3672*9acbbeafSnn } 3673*9acbbeafSnn 3674*9acbbeafSnn while (fgets(inbuf, sizeof (inbuf), file) != NULL) 3675*9acbbeafSnn fprintf(stderr, "%s", inbuf); 3676*9acbbeafSnn status = pclose(file); 3677*9acbbeafSnn 3678*9acbbeafSnn if (WIFSIGNALED(status)) { 3679*9acbbeafSnn zerr(gettext("%s unexpectedly terminated due to signal %d"), 3680*9acbbeafSnn cmdbuf, WTERMSIG(status)); 3681*9acbbeafSnn return (-1); 3682*9acbbeafSnn } 3683*9acbbeafSnn assert(WIFEXITED(status)); 3684*9acbbeafSnn return (WEXITSTATUS(status)); 3685*9acbbeafSnn } 3686*9acbbeafSnn 3687*9acbbeafSnn static int 3688*9acbbeafSnn brand_verify(zone_dochandle_t handle) 3689*9acbbeafSnn { 3690*9acbbeafSnn char *xml_file = "/tmp/zonecfg_verify.XXXXXX"; 3691*9acbbeafSnn char cmdbuf[MAX_CMD_LEN]; 3692*9acbbeafSnn brand_handle_t *bhp; 3693*9acbbeafSnn char brand[MAXNAMELEN]; 3694*9acbbeafSnn int err; 3695*9acbbeafSnn 3696*9acbbeafSnn if (zonecfg_get_brand(handle, brand, sizeof (brand)) != Z_OK) { 3697*9acbbeafSnn zerr("%s: %s\n", zone, gettext("could not get zone brand")); 3698*9acbbeafSnn return (Z_INVALID_DOCUMENT); 3699*9acbbeafSnn } 3700*9acbbeafSnn if ((bhp = brand_open(brand)) == NULL) { 3701*9acbbeafSnn zerr("%s: %s\n", zone, gettext("unknown brand.")); 3702*9acbbeafSnn return (Z_INVALID_DOCUMENT); 3703*9acbbeafSnn } 3704*9acbbeafSnn 3705*9acbbeafSnn /* 3706*9acbbeafSnn * Fetch the verify command, if any, from the brand configuration 3707*9acbbeafSnn * and build the command line to execute it. 3708*9acbbeafSnn */ 3709*9acbbeafSnn strcpy(cmdbuf, EXEC_PREFIX); 3710*9acbbeafSnn err = brand_get_verify_cfg(bhp, cmdbuf + EXEC_LEN, 3711*9acbbeafSnn sizeof (cmdbuf) - (EXEC_LEN + (strlen(xml_file) + 1))); 3712*9acbbeafSnn brand_close(bhp); 3713*9acbbeafSnn if (err != Z_OK) { 3714*9acbbeafSnn zerr("%s: %s\n", zone, 3715*9acbbeafSnn gettext("could not get brand verification command")); 3716*9acbbeafSnn return (Z_INVALID_DOCUMENT); 3717*9acbbeafSnn } 3718*9acbbeafSnn 3719*9acbbeafSnn /* 3720*9acbbeafSnn * If the brand doesn't provide a verification routine, we just 3721*9acbbeafSnn * return success. 3722*9acbbeafSnn */ 3723*9acbbeafSnn if (strlen(cmdbuf) == EXEC_LEN) 3724*9acbbeafSnn return (Z_OK); 3725*9acbbeafSnn 3726*9acbbeafSnn /* 3727*9acbbeafSnn * Dump the current config information for this zone to a file. 3728*9acbbeafSnn */ 3729*9acbbeafSnn if (mkstemp(xml_file) == NULL) 3730*9acbbeafSnn return (Z_TEMP_FILE); 3731*9acbbeafSnn if ((err = zonecfg_verify_save(handle, xml_file)) != Z_OK) { 3732*9acbbeafSnn (void) unlink(xml_file); 3733*9acbbeafSnn return (err); 3734*9acbbeafSnn } 3735*9acbbeafSnn 3736*9acbbeafSnn /* 3737*9acbbeafSnn * Execute the verification command. 3738*9acbbeafSnn */ 3739*9acbbeafSnn if ((strlcat(cmdbuf, " ", MAX_CMD_LEN) >= MAX_CMD_LEN) || 3740*9acbbeafSnn (strlcat(cmdbuf, xml_file, MAX_CMD_LEN) >= MAX_CMD_LEN)) { 3741*9acbbeafSnn err = Z_BRAND_ERROR; 3742*9acbbeafSnn } else { 3743*9acbbeafSnn err = do_subproc(cmdbuf); 3744*9acbbeafSnn } 3745*9acbbeafSnn 3746*9acbbeafSnn (void) unlink(xml_file); 3747*9acbbeafSnn return ((err == Z_OK) ? Z_OK : Z_BRAND_ERROR); 3748*9acbbeafSnn } 3749*9acbbeafSnn 37507c478bd9Sstevel@tonic-gate /* 37517c478bd9Sstevel@tonic-gate * See the DTD for which attributes are required for which resources. 37527c478bd9Sstevel@tonic-gate * 37537c478bd9Sstevel@tonic-gate * This function can be called by commit_func(), which needs to save things, 37547c478bd9Sstevel@tonic-gate * in addition to the general call from parse_and_run(), which doesn't need 37557c478bd9Sstevel@tonic-gate * things saved. Since the parameters are standardized, we distinguish by 37567c478bd9Sstevel@tonic-gate * having commit_func() call here with cmd->cmd_arg set to "save" to indicate 37577c478bd9Sstevel@tonic-gate * that a save is needed. 37587c478bd9Sstevel@tonic-gate */ 37597c478bd9Sstevel@tonic-gate void 37607c478bd9Sstevel@tonic-gate verify_func(cmd_t *cmd) 37617c478bd9Sstevel@tonic-gate { 37627c478bd9Sstevel@tonic-gate struct zone_nwiftab nwiftab; 37637c478bd9Sstevel@tonic-gate struct zone_fstab fstab; 37647c478bd9Sstevel@tonic-gate struct zone_attrtab attrtab; 37657c478bd9Sstevel@tonic-gate struct zone_rctltab rctltab; 3766fa9e4066Sahrens struct zone_dstab dstab; 37677c478bd9Sstevel@tonic-gate char zonepath[MAXPATHLEN]; 3768*9acbbeafSnn char brand[MAXNAMELEN]; 37697c478bd9Sstevel@tonic-gate int err, ret_val = Z_OK, arg; 37707c478bd9Sstevel@tonic-gate bool save = FALSE; 37717c478bd9Sstevel@tonic-gate 37727c478bd9Sstevel@tonic-gate optind = 0; 37737c478bd9Sstevel@tonic-gate if ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) { 37747c478bd9Sstevel@tonic-gate switch (arg) { 37757c478bd9Sstevel@tonic-gate case '?': 37767c478bd9Sstevel@tonic-gate longer_usage(CMD_VERIFY); 37777c478bd9Sstevel@tonic-gate return; 37787c478bd9Sstevel@tonic-gate default: 37797c478bd9Sstevel@tonic-gate short_usage(CMD_VERIFY); 37807c478bd9Sstevel@tonic-gate return; 37817c478bd9Sstevel@tonic-gate } 37827c478bd9Sstevel@tonic-gate } 37837c478bd9Sstevel@tonic-gate if (optind > cmd->cmd_argc) { 37847c478bd9Sstevel@tonic-gate short_usage(CMD_VERIFY); 37857c478bd9Sstevel@tonic-gate return; 37867c478bd9Sstevel@tonic-gate } 37877c478bd9Sstevel@tonic-gate 37887c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_VERIFY)) 37897c478bd9Sstevel@tonic-gate return; 37907c478bd9Sstevel@tonic-gate 37917c478bd9Sstevel@tonic-gate assert(cmd != NULL); 37927c478bd9Sstevel@tonic-gate 37937c478bd9Sstevel@tonic-gate if (cmd->cmd_argc > 0 && (strcmp(cmd->cmd_argv[0], "save") == 0)) 37947c478bd9Sstevel@tonic-gate save = TRUE; 37957c478bd9Sstevel@tonic-gate if (initialize(TRUE) != Z_OK) 37967c478bd9Sstevel@tonic-gate return; 37977c478bd9Sstevel@tonic-gate 37987c478bd9Sstevel@tonic-gate if (zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)) != Z_OK) { 3799087719fdSdp zerr(gettext("%s not specified"), pt_to_str(PT_ZONEPATH)); 38007c478bd9Sstevel@tonic-gate ret_val = Z_REQD_RESOURCE_MISSING; 38017c478bd9Sstevel@tonic-gate saw_error = TRUE; 38027c478bd9Sstevel@tonic-gate } 38037c478bd9Sstevel@tonic-gate if (strlen(zonepath) == 0) { 3804087719fdSdp zerr(gettext("%s cannot be empty."), pt_to_str(PT_ZONEPATH)); 38057c478bd9Sstevel@tonic-gate ret_val = Z_REQD_RESOURCE_MISSING; 38067c478bd9Sstevel@tonic-gate saw_error = TRUE; 38077c478bd9Sstevel@tonic-gate } 38087c478bd9Sstevel@tonic-gate 3809*9acbbeafSnn if ((err = zonecfg_get_brand(handle, brand, sizeof (brand))) != Z_OK) { 3810*9acbbeafSnn zone_perror(zone, err, TRUE); 3811*9acbbeafSnn return; 3812*9acbbeafSnn } 3813*9acbbeafSnn if (strcmp(brand, NATIVE_BRAND_NAME) != 0) { 3814*9acbbeafSnn if ((err = brand_verify(handle)) != Z_OK) { 3815*9acbbeafSnn zone_perror(zone, err, TRUE); 3816*9acbbeafSnn return; 3817*9acbbeafSnn } 3818*9acbbeafSnn } 3819*9acbbeafSnn 38207c478bd9Sstevel@tonic-gate if ((err = zonecfg_setipdent(handle)) != Z_OK) { 38217c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 38227c478bd9Sstevel@tonic-gate return; 38237c478bd9Sstevel@tonic-gate } 38247c478bd9Sstevel@tonic-gate while (zonecfg_getipdent(handle, &fstab) == Z_OK) { 3825087719fdSdp check_reqd_prop(fstab.zone_fs_dir, RT_IPD, PT_DIR, &ret_val); 38267c478bd9Sstevel@tonic-gate } 38277c478bd9Sstevel@tonic-gate (void) zonecfg_endipdent(handle); 38287c478bd9Sstevel@tonic-gate 38297c478bd9Sstevel@tonic-gate if ((err = zonecfg_setfsent(handle)) != Z_OK) { 38307c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 38317c478bd9Sstevel@tonic-gate return; 38327c478bd9Sstevel@tonic-gate } 38337c478bd9Sstevel@tonic-gate while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 3834087719fdSdp check_reqd_prop(fstab.zone_fs_dir, RT_FS, PT_DIR, &ret_val); 3835087719fdSdp check_reqd_prop(fstab.zone_fs_special, RT_FS, PT_SPECIAL, 3836087719fdSdp &ret_val); 3837087719fdSdp check_reqd_prop(fstab.zone_fs_type, RT_FS, PT_TYPE, &ret_val); 3838087719fdSdp 38397c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(fstab.zone_fs_options); 38407c478bd9Sstevel@tonic-gate } 38417c478bd9Sstevel@tonic-gate (void) zonecfg_endfsent(handle); 38427c478bd9Sstevel@tonic-gate 38437c478bd9Sstevel@tonic-gate if ((err = zonecfg_setnwifent(handle)) != Z_OK) { 38447c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 38457c478bd9Sstevel@tonic-gate return; 38467c478bd9Sstevel@tonic-gate } 38477c478bd9Sstevel@tonic-gate while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) { 3848087719fdSdp check_reqd_prop(nwiftab.zone_nwif_address, RT_NET, 3849087719fdSdp PT_ADDRESS, &ret_val); 3850087719fdSdp check_reqd_prop(nwiftab.zone_nwif_physical, RT_NET, 3851087719fdSdp PT_PHYSICAL, &ret_val); 38527c478bd9Sstevel@tonic-gate } 38537c478bd9Sstevel@tonic-gate (void) zonecfg_endnwifent(handle); 38547c478bd9Sstevel@tonic-gate 38557c478bd9Sstevel@tonic-gate if ((err = zonecfg_setrctlent(handle)) != Z_OK) { 38567c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 38577c478bd9Sstevel@tonic-gate return; 38587c478bd9Sstevel@tonic-gate } 38597c478bd9Sstevel@tonic-gate while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { 3860087719fdSdp check_reqd_prop(rctltab.zone_rctl_name, RT_RCTL, PT_NAME, 3861087719fdSdp &ret_val); 3862087719fdSdp 38637c478bd9Sstevel@tonic-gate if (rctltab.zone_rctl_valptr == NULL) { 38647c478bd9Sstevel@tonic-gate zerr(gettext("%s: no %s specified"), 38657c478bd9Sstevel@tonic-gate rt_to_str(RT_RCTL), pt_to_str(PT_VALUE)); 38667c478bd9Sstevel@tonic-gate saw_error = TRUE; 38677c478bd9Sstevel@tonic-gate if (ret_val == Z_OK) 38687c478bd9Sstevel@tonic-gate ret_val = Z_REQD_PROPERTY_MISSING; 38697c478bd9Sstevel@tonic-gate } else { 38707c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 38717c478bd9Sstevel@tonic-gate } 38727c478bd9Sstevel@tonic-gate } 38737c478bd9Sstevel@tonic-gate (void) zonecfg_endrctlent(handle); 38747c478bd9Sstevel@tonic-gate 38757c478bd9Sstevel@tonic-gate if ((err = zonecfg_setattrent(handle)) != Z_OK) { 38767c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 38777c478bd9Sstevel@tonic-gate return; 38787c478bd9Sstevel@tonic-gate } 38797c478bd9Sstevel@tonic-gate while (zonecfg_getattrent(handle, &attrtab) == Z_OK) { 3880087719fdSdp check_reqd_prop(attrtab.zone_attr_name, RT_ATTR, PT_NAME, 3881087719fdSdp &ret_val); 3882087719fdSdp check_reqd_prop(attrtab.zone_attr_type, RT_ATTR, PT_TYPE, 3883087719fdSdp &ret_val); 3884087719fdSdp check_reqd_prop(attrtab.zone_attr_value, RT_ATTR, PT_VALUE, 3885087719fdSdp &ret_val); 38867c478bd9Sstevel@tonic-gate } 38877c478bd9Sstevel@tonic-gate (void) zonecfg_endattrent(handle); 38887c478bd9Sstevel@tonic-gate 3889fa9e4066Sahrens if ((err = zonecfg_setdsent(handle)) != Z_OK) { 3890fa9e4066Sahrens zone_perror(zone, err, TRUE); 3891fa9e4066Sahrens return; 3892fa9e4066Sahrens } 3893fa9e4066Sahrens while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 3894fa9e4066Sahrens if (strlen(dstab.zone_dataset_name) == 0) { 3895fa9e4066Sahrens zerr("%s: %s %s", rt_to_str(RT_DATASET), 3896fa9e4066Sahrens pt_to_str(PT_NAME), gettext("not specified")); 3897fa9e4066Sahrens saw_error = TRUE; 3898fa9e4066Sahrens if (ret_val == Z_OK) 3899fa9e4066Sahrens ret_val = Z_REQD_PROPERTY_MISSING; 3900fa9e4066Sahrens } else if (!zfs_name_valid(dstab.zone_dataset_name, 3901fa9e4066Sahrens ZFS_TYPE_FILESYSTEM)) { 3902fa9e4066Sahrens zerr("%s: %s %s", rt_to_str(RT_DATASET), 3903fa9e4066Sahrens pt_to_str(PT_NAME), gettext("invalid")); 3904fa9e4066Sahrens saw_error = TRUE; 3905fa9e4066Sahrens if (ret_val == Z_OK) 3906fa9e4066Sahrens ret_val = Z_BAD_PROPERTY; 3907fa9e4066Sahrens } 3908fa9e4066Sahrens 3909fa9e4066Sahrens } 3910fa9e4066Sahrens (void) zonecfg_enddsent(handle); 3911fa9e4066Sahrens 39127c478bd9Sstevel@tonic-gate if (!global_scope) { 39137c478bd9Sstevel@tonic-gate zerr(gettext("resource specification incomplete")); 39147c478bd9Sstevel@tonic-gate saw_error = TRUE; 39157c478bd9Sstevel@tonic-gate if (ret_val == Z_OK) 39167c478bd9Sstevel@tonic-gate ret_val = Z_INSUFFICIENT_SPEC; 39177c478bd9Sstevel@tonic-gate } 39187c478bd9Sstevel@tonic-gate 39197c478bd9Sstevel@tonic-gate if (save) { 3920087719fdSdp if (ret_val == Z_OK) { 3921087719fdSdp if ((ret_val = zonecfg_save(handle)) == Z_OK) { 3922087719fdSdp need_to_commit = FALSE; 3923087719fdSdp (void) strlcpy(revert_zone, zone, 3924087719fdSdp sizeof (revert_zone)); 3925087719fdSdp } 3926087719fdSdp } else { 3927087719fdSdp zerr(gettext("Zone %s failed to verify"), zone); 3928087719fdSdp } 39297c478bd9Sstevel@tonic-gate } 39307c478bd9Sstevel@tonic-gate if (ret_val != Z_OK) 39317c478bd9Sstevel@tonic-gate zone_perror(zone, ret_val, TRUE); 39327c478bd9Sstevel@tonic-gate } 39337c478bd9Sstevel@tonic-gate 39347c478bd9Sstevel@tonic-gate void 39357c478bd9Sstevel@tonic-gate cancel_func(cmd_t *cmd) 39367c478bd9Sstevel@tonic-gate { 39377c478bd9Sstevel@tonic-gate int arg; 39387c478bd9Sstevel@tonic-gate 39397c478bd9Sstevel@tonic-gate assert(cmd != NULL); 39407c478bd9Sstevel@tonic-gate 39417c478bd9Sstevel@tonic-gate optind = 0; 39427c478bd9Sstevel@tonic-gate if ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) { 39437c478bd9Sstevel@tonic-gate switch (arg) { 39447c478bd9Sstevel@tonic-gate case '?': 39457c478bd9Sstevel@tonic-gate longer_usage(CMD_CANCEL); 39467c478bd9Sstevel@tonic-gate return; 39477c478bd9Sstevel@tonic-gate default: 39487c478bd9Sstevel@tonic-gate short_usage(CMD_CANCEL); 39497c478bd9Sstevel@tonic-gate return; 39507c478bd9Sstevel@tonic-gate } 39517c478bd9Sstevel@tonic-gate } 39527c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 39537c478bd9Sstevel@tonic-gate short_usage(CMD_CANCEL); 39547c478bd9Sstevel@tonic-gate return; 39557c478bd9Sstevel@tonic-gate } 39567c478bd9Sstevel@tonic-gate 39577c478bd9Sstevel@tonic-gate if (global_scope) 39587c478bd9Sstevel@tonic-gate scope_usage(CMD_CANCEL); 39597c478bd9Sstevel@tonic-gate global_scope = TRUE; 39607c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options); 39617c478bd9Sstevel@tonic-gate bzero(&in_progress_fstab, sizeof (in_progress_fstab)); 39627c478bd9Sstevel@tonic-gate bzero(&in_progress_nwiftab, sizeof (in_progress_nwiftab)); 3963fa9e4066Sahrens bzero(&in_progress_ipdtab, sizeof (in_progress_ipdtab)); 39647c478bd9Sstevel@tonic-gate bzero(&in_progress_devtab, sizeof (in_progress_devtab)); 39657c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(in_progress_rctltab.zone_rctl_valptr); 39667c478bd9Sstevel@tonic-gate bzero(&in_progress_rctltab, sizeof (in_progress_rctltab)); 39677c478bd9Sstevel@tonic-gate bzero(&in_progress_attrtab, sizeof (in_progress_attrtab)); 3968fa9e4066Sahrens bzero(&in_progress_dstab, sizeof (in_progress_dstab)); 39697c478bd9Sstevel@tonic-gate } 39707c478bd9Sstevel@tonic-gate 39717c478bd9Sstevel@tonic-gate static int 39727c478bd9Sstevel@tonic-gate validate_attr_name(char *name) 39737c478bd9Sstevel@tonic-gate { 39747c478bd9Sstevel@tonic-gate int i; 39757c478bd9Sstevel@tonic-gate 39767c478bd9Sstevel@tonic-gate if (!isalnum(name[0])) { 39777c478bd9Sstevel@tonic-gate zerr(gettext("Invalid %s %s %s: must start with an alpha-" 39787c478bd9Sstevel@tonic-gate "numeric character."), rt_to_str(RT_ATTR), 39797c478bd9Sstevel@tonic-gate pt_to_str(PT_NAME), name); 39807c478bd9Sstevel@tonic-gate return (Z_INVAL); 39817c478bd9Sstevel@tonic-gate } 39827c478bd9Sstevel@tonic-gate for (i = 1; name[i]; i++) 39837c478bd9Sstevel@tonic-gate if (!isalnum(name[i]) && name[i] != '-' && name[i] != '.') { 39847c478bd9Sstevel@tonic-gate zerr(gettext("Invalid %s %s %s: can only contain " 39857c478bd9Sstevel@tonic-gate "alpha-numeric characters, plus '-' and '.'."), 39867c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_NAME), name); 39877c478bd9Sstevel@tonic-gate return (Z_INVAL); 39887c478bd9Sstevel@tonic-gate } 39897c478bd9Sstevel@tonic-gate return (Z_OK); 39907c478bd9Sstevel@tonic-gate } 39917c478bd9Sstevel@tonic-gate 39927c478bd9Sstevel@tonic-gate static int 39937c478bd9Sstevel@tonic-gate validate_attr_type_val(struct zone_attrtab *attrtab) 39947c478bd9Sstevel@tonic-gate { 39957c478bd9Sstevel@tonic-gate boolean_t boolval; 39967c478bd9Sstevel@tonic-gate int64_t intval; 39977c478bd9Sstevel@tonic-gate char strval[MAXNAMELEN]; 39987c478bd9Sstevel@tonic-gate uint64_t uintval; 39997c478bd9Sstevel@tonic-gate 40007c478bd9Sstevel@tonic-gate if (strcmp(attrtab->zone_attr_type, "boolean") == 0) { 40017c478bd9Sstevel@tonic-gate if (zonecfg_get_attr_boolean(attrtab, &boolval) == Z_OK) 40027c478bd9Sstevel@tonic-gate return (Z_OK); 40037c478bd9Sstevel@tonic-gate zerr(gettext("invalid %s value for %s=%s"), 40047c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "boolean"); 40057c478bd9Sstevel@tonic-gate return (Z_ERR); 40067c478bd9Sstevel@tonic-gate } 40077c478bd9Sstevel@tonic-gate 40087c478bd9Sstevel@tonic-gate if (strcmp(attrtab->zone_attr_type, "int") == 0) { 40097c478bd9Sstevel@tonic-gate if (zonecfg_get_attr_int(attrtab, &intval) == Z_OK) 40107c478bd9Sstevel@tonic-gate return (Z_OK); 40117c478bd9Sstevel@tonic-gate zerr(gettext("invalid %s value for %s=%s"), 40127c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "int"); 40137c478bd9Sstevel@tonic-gate return (Z_ERR); 40147c478bd9Sstevel@tonic-gate } 40157c478bd9Sstevel@tonic-gate 40167c478bd9Sstevel@tonic-gate if (strcmp(attrtab->zone_attr_type, "string") == 0) { 40177c478bd9Sstevel@tonic-gate if (zonecfg_get_attr_string(attrtab, strval, 40187c478bd9Sstevel@tonic-gate sizeof (strval)) == Z_OK) 40197c478bd9Sstevel@tonic-gate return (Z_OK); 40207c478bd9Sstevel@tonic-gate zerr(gettext("invalid %s value for %s=%s"), 40217c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "string"); 40227c478bd9Sstevel@tonic-gate return (Z_ERR); 40237c478bd9Sstevel@tonic-gate } 40247c478bd9Sstevel@tonic-gate 40257c478bd9Sstevel@tonic-gate if (strcmp(attrtab->zone_attr_type, "uint") == 0) { 40267c478bd9Sstevel@tonic-gate if (zonecfg_get_attr_uint(attrtab, &uintval) == Z_OK) 40277c478bd9Sstevel@tonic-gate return (Z_OK); 40287c478bd9Sstevel@tonic-gate zerr(gettext("invalid %s value for %s=%s"), 40297c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_TYPE), "uint"); 40307c478bd9Sstevel@tonic-gate return (Z_ERR); 40317c478bd9Sstevel@tonic-gate } 40327c478bd9Sstevel@tonic-gate 40337c478bd9Sstevel@tonic-gate zerr(gettext("invalid %s %s '%s'"), rt_to_str(RT_ATTR), 40347c478bd9Sstevel@tonic-gate pt_to_str(PT_TYPE), attrtab->zone_attr_type); 40357c478bd9Sstevel@tonic-gate return (Z_ERR); 40367c478bd9Sstevel@tonic-gate } 40377c478bd9Sstevel@tonic-gate 4038087719fdSdp /* 4039087719fdSdp * Helper function for end_func-- checks the existence of a given property 4040087719fdSdp * and emits a message if not specified. 4041087719fdSdp */ 4042087719fdSdp static int 4043087719fdSdp end_check_reqd(char *attr, int pt, bool *validation_failed) 4044087719fdSdp { 4045087719fdSdp if (strlen(attr) == 0) { 4046087719fdSdp *validation_failed = TRUE; 4047087719fdSdp zerr(gettext("%s not specified"), pt_to_str(pt)); 4048087719fdSdp return (Z_ERR); 4049087719fdSdp } 4050087719fdSdp return (Z_OK); 4051087719fdSdp } 4052087719fdSdp 40537c478bd9Sstevel@tonic-gate void 40547c478bd9Sstevel@tonic-gate end_func(cmd_t *cmd) 40557c478bd9Sstevel@tonic-gate { 40567c478bd9Sstevel@tonic-gate bool validation_failed = FALSE; 40577c478bd9Sstevel@tonic-gate struct zone_fstab tmp_fstab; 40587c478bd9Sstevel@tonic-gate struct zone_nwiftab tmp_nwiftab; 40597c478bd9Sstevel@tonic-gate struct zone_devtab tmp_devtab; 40607c478bd9Sstevel@tonic-gate struct zone_rctltab tmp_rctltab; 40617c478bd9Sstevel@tonic-gate struct zone_attrtab tmp_attrtab; 4062fa9e4066Sahrens struct zone_dstab tmp_dstab; 40637c478bd9Sstevel@tonic-gate int err, arg; 40647c478bd9Sstevel@tonic-gate 40657c478bd9Sstevel@tonic-gate assert(cmd != NULL); 40667c478bd9Sstevel@tonic-gate 40677c478bd9Sstevel@tonic-gate optind = 0; 40687c478bd9Sstevel@tonic-gate if ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) { 40697c478bd9Sstevel@tonic-gate switch (arg) { 40707c478bd9Sstevel@tonic-gate case '?': 40717c478bd9Sstevel@tonic-gate longer_usage(CMD_END); 40727c478bd9Sstevel@tonic-gate return; 40737c478bd9Sstevel@tonic-gate default: 40747c478bd9Sstevel@tonic-gate short_usage(CMD_END); 40757c478bd9Sstevel@tonic-gate return; 40767c478bd9Sstevel@tonic-gate } 40777c478bd9Sstevel@tonic-gate } 40787c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 40797c478bd9Sstevel@tonic-gate short_usage(CMD_END); 40807c478bd9Sstevel@tonic-gate return; 40817c478bd9Sstevel@tonic-gate } 40827c478bd9Sstevel@tonic-gate 40837c478bd9Sstevel@tonic-gate if (global_scope) { 40847c478bd9Sstevel@tonic-gate scope_usage(CMD_END); 40857c478bd9Sstevel@tonic-gate return; 40867c478bd9Sstevel@tonic-gate } 40877c478bd9Sstevel@tonic-gate 40887c478bd9Sstevel@tonic-gate assert(end_op == CMD_ADD || end_op == CMD_SELECT); 40897c478bd9Sstevel@tonic-gate 40907c478bd9Sstevel@tonic-gate switch (resource_scope) { 40917c478bd9Sstevel@tonic-gate case RT_FS: 40927c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4093087719fdSdp if (end_check_reqd(in_progress_fstab.zone_fs_dir, 4094087719fdSdp PT_DIR, &validation_failed) == Z_OK) { 4095087719fdSdp if (in_progress_fstab.zone_fs_dir[0] != '/') { 4096087719fdSdp zerr(gettext("%s %s is not an absolute path."), 4097087719fdSdp pt_to_str(PT_DIR), 4098087719fdSdp in_progress_fstab.zone_fs_dir); 4099087719fdSdp validation_failed = TRUE; 4100087719fdSdp } 41017c478bd9Sstevel@tonic-gate } 4102087719fdSdp 4103087719fdSdp (void) end_check_reqd(in_progress_fstab.zone_fs_special, 4104087719fdSdp PT_SPECIAL, &validation_failed); 4105087719fdSdp 41067c478bd9Sstevel@tonic-gate if (in_progress_fstab.zone_fs_raw[0] != '\0' && 41077c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_raw[0] != '/') { 4108087719fdSdp zerr(gettext("%s %s is not an absolute path."), 4109087719fdSdp pt_to_str(PT_RAW), 4110087719fdSdp in_progress_fstab.zone_fs_raw); 41117c478bd9Sstevel@tonic-gate validation_failed = TRUE; 41127c478bd9Sstevel@tonic-gate } 4113087719fdSdp 4114087719fdSdp (void) end_check_reqd(in_progress_fstab.zone_fs_type, PT_TYPE, 4115087719fdSdp &validation_failed); 4116087719fdSdp 4117087719fdSdp if (validation_failed) { 41187c478bd9Sstevel@tonic-gate saw_error = TRUE; 41197c478bd9Sstevel@tonic-gate return; 4120087719fdSdp } 4121087719fdSdp 41227c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 41237c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 41247c478bd9Sstevel@tonic-gate bzero(&tmp_fstab, sizeof (tmp_fstab)); 41257c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_fstab.zone_fs_dir, 41267c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_dir, 41277c478bd9Sstevel@tonic-gate sizeof (tmp_fstab.zone_fs_dir)); 41287c478bd9Sstevel@tonic-gate err = zonecfg_lookup_filesystem(handle, &tmp_fstab); 41297c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(tmp_fstab.zone_fs_options); 41307c478bd9Sstevel@tonic-gate if (err == Z_OK) { 41317c478bd9Sstevel@tonic-gate zerr(gettext("A %s resource " 41327c478bd9Sstevel@tonic-gate "with the %s '%s' already exists."), 41337c478bd9Sstevel@tonic-gate rt_to_str(RT_FS), pt_to_str(PT_DIR), 41347c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_dir); 41357c478bd9Sstevel@tonic-gate saw_error = TRUE; 41367c478bd9Sstevel@tonic-gate return; 41377c478bd9Sstevel@tonic-gate } 41387c478bd9Sstevel@tonic-gate err = zonecfg_add_filesystem(handle, 41397c478bd9Sstevel@tonic-gate &in_progress_fstab); 41407c478bd9Sstevel@tonic-gate } else { 41417c478bd9Sstevel@tonic-gate err = zonecfg_modify_filesystem(handle, &old_fstab, 41427c478bd9Sstevel@tonic-gate &in_progress_fstab); 41437c478bd9Sstevel@tonic-gate } 41447c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(in_progress_fstab.zone_fs_options); 41457c478bd9Sstevel@tonic-gate in_progress_fstab.zone_fs_options = NULL; 41467c478bd9Sstevel@tonic-gate break; 4147087719fdSdp 41487c478bd9Sstevel@tonic-gate case RT_IPD: 41497c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4150087719fdSdp if (end_check_reqd(in_progress_ipdtab.zone_fs_dir, PT_DIR, 4151087719fdSdp &validation_failed) == Z_OK) { 4152087719fdSdp if (in_progress_ipdtab.zone_fs_dir[0] != '/') { 4153087719fdSdp zerr(gettext("%s %s is not an absolute path."), 4154087719fdSdp pt_to_str(PT_DIR), 4155087719fdSdp in_progress_ipdtab.zone_fs_dir); 4156087719fdSdp validation_failed = TRUE; 4157087719fdSdp } 41587c478bd9Sstevel@tonic-gate } 4159087719fdSdp if (validation_failed) { 4160087719fdSdp saw_error = TRUE; 41617c478bd9Sstevel@tonic-gate return; 4162087719fdSdp } 4163087719fdSdp 41647c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 41657c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 41667c478bd9Sstevel@tonic-gate bzero(&tmp_fstab, sizeof (tmp_fstab)); 41677c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_fstab.zone_fs_dir, 41687c478bd9Sstevel@tonic-gate in_progress_ipdtab.zone_fs_dir, 41697c478bd9Sstevel@tonic-gate sizeof (tmp_fstab.zone_fs_dir)); 41707c478bd9Sstevel@tonic-gate err = zonecfg_lookup_ipd(handle, &tmp_fstab); 41717c478bd9Sstevel@tonic-gate if (err == Z_OK) { 41727c478bd9Sstevel@tonic-gate zerr(gettext("An %s resource " 41737c478bd9Sstevel@tonic-gate "with the %s '%s' already exists."), 41747c478bd9Sstevel@tonic-gate rt_to_str(RT_IPD), pt_to_str(PT_DIR), 41757c478bd9Sstevel@tonic-gate in_progress_ipdtab.zone_fs_dir); 41767c478bd9Sstevel@tonic-gate saw_error = TRUE; 41777c478bd9Sstevel@tonic-gate return; 41787c478bd9Sstevel@tonic-gate } 41797c478bd9Sstevel@tonic-gate err = zonecfg_add_ipd(handle, &in_progress_ipdtab); 41807c478bd9Sstevel@tonic-gate } else { 41817c478bd9Sstevel@tonic-gate err = zonecfg_modify_ipd(handle, &old_ipdtab, 41827c478bd9Sstevel@tonic-gate &in_progress_ipdtab); 41837c478bd9Sstevel@tonic-gate } 41847c478bd9Sstevel@tonic-gate break; 41857c478bd9Sstevel@tonic-gate case RT_NET: 41867c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4187087719fdSdp (void) end_check_reqd(in_progress_nwiftab.zone_nwif_physical, 4188087719fdSdp PT_PHYSICAL, &validation_failed); 4189087719fdSdp (void) end_check_reqd(in_progress_nwiftab.zone_nwif_address, 4190087719fdSdp PT_ADDRESS, &validation_failed); 4191087719fdSdp 4192087719fdSdp if (validation_failed) { 41937c478bd9Sstevel@tonic-gate saw_error = TRUE; 41947c478bd9Sstevel@tonic-gate return; 4195087719fdSdp } 4196087719fdSdp 41977c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 41987c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 41997c478bd9Sstevel@tonic-gate bzero(&tmp_nwiftab, sizeof (tmp_nwiftab)); 42007c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_nwiftab.zone_nwif_address, 42017c478bd9Sstevel@tonic-gate in_progress_nwiftab.zone_nwif_address, 42027c478bd9Sstevel@tonic-gate sizeof (tmp_nwiftab.zone_nwif_address)); 42037c478bd9Sstevel@tonic-gate if (zonecfg_lookup_nwif(handle, &tmp_nwiftab) == Z_OK) { 42047c478bd9Sstevel@tonic-gate zerr(gettext("A %s resource " 42057c478bd9Sstevel@tonic-gate "with the %s '%s' already exists."), 42067c478bd9Sstevel@tonic-gate rt_to_str(RT_NET), pt_to_str(PT_ADDRESS), 42077c478bd9Sstevel@tonic-gate in_progress_nwiftab.zone_nwif_address); 42087c478bd9Sstevel@tonic-gate saw_error = TRUE; 42097c478bd9Sstevel@tonic-gate return; 42107c478bd9Sstevel@tonic-gate } 42117c478bd9Sstevel@tonic-gate err = zonecfg_add_nwif(handle, &in_progress_nwiftab); 42127c478bd9Sstevel@tonic-gate } else { 42137c478bd9Sstevel@tonic-gate err = zonecfg_modify_nwif(handle, &old_nwiftab, 42147c478bd9Sstevel@tonic-gate &in_progress_nwiftab); 42157c478bd9Sstevel@tonic-gate } 42167c478bd9Sstevel@tonic-gate break; 4217087719fdSdp 42187c478bd9Sstevel@tonic-gate case RT_DEVICE: 42197c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4220087719fdSdp (void) end_check_reqd(in_progress_devtab.zone_dev_match, 4221087719fdSdp PT_MATCH, &validation_failed); 4222087719fdSdp 4223087719fdSdp if (validation_failed) { 42247c478bd9Sstevel@tonic-gate saw_error = TRUE; 42257c478bd9Sstevel@tonic-gate return; 4226087719fdSdp } 4227087719fdSdp 42287c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 42297c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 42307c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_devtab.zone_dev_match, 42317c478bd9Sstevel@tonic-gate in_progress_devtab.zone_dev_match, 42327c478bd9Sstevel@tonic-gate sizeof (tmp_devtab.zone_dev_match)); 42337c478bd9Sstevel@tonic-gate if (zonecfg_lookup_dev(handle, &tmp_devtab) == Z_OK) { 42347c478bd9Sstevel@tonic-gate zerr(gettext("A %s resource with the %s '%s' " 42357c478bd9Sstevel@tonic-gate "already exists."), rt_to_str(RT_DEVICE), 42367c478bd9Sstevel@tonic-gate pt_to_str(PT_MATCH), 42377c478bd9Sstevel@tonic-gate in_progress_devtab.zone_dev_match); 42387c478bd9Sstevel@tonic-gate saw_error = TRUE; 42397c478bd9Sstevel@tonic-gate return; 42407c478bd9Sstevel@tonic-gate } 42417c478bd9Sstevel@tonic-gate err = zonecfg_add_dev(handle, &in_progress_devtab); 42427c478bd9Sstevel@tonic-gate } else { 42437c478bd9Sstevel@tonic-gate err = zonecfg_modify_dev(handle, &old_devtab, 42447c478bd9Sstevel@tonic-gate &in_progress_devtab); 42457c478bd9Sstevel@tonic-gate } 42467c478bd9Sstevel@tonic-gate break; 4247087719fdSdp 42487c478bd9Sstevel@tonic-gate case RT_RCTL: 42497c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4250087719fdSdp (void) end_check_reqd(in_progress_rctltab.zone_rctl_name, 4251087719fdSdp PT_NAME, &validation_failed); 4252087719fdSdp 42537c478bd9Sstevel@tonic-gate if (in_progress_rctltab.zone_rctl_valptr == NULL) { 42547c478bd9Sstevel@tonic-gate zerr(gettext("no %s specified"), pt_to_str(PT_VALUE)); 42557c478bd9Sstevel@tonic-gate validation_failed = TRUE; 42567c478bd9Sstevel@tonic-gate } 4257087719fdSdp 4258087719fdSdp if (validation_failed) { 4259087719fdSdp saw_error = TRUE; 42607c478bd9Sstevel@tonic-gate return; 4261087719fdSdp } 4262087719fdSdp 42637c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 42647c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 42657c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_rctltab.zone_rctl_name, 42667c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_name, 42677c478bd9Sstevel@tonic-gate sizeof (tmp_rctltab.zone_rctl_name)); 42687c478bd9Sstevel@tonic-gate tmp_rctltab.zone_rctl_valptr = NULL; 42697c478bd9Sstevel@tonic-gate err = zonecfg_lookup_rctl(handle, &tmp_rctltab); 42707c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list( 42717c478bd9Sstevel@tonic-gate tmp_rctltab.zone_rctl_valptr); 42727c478bd9Sstevel@tonic-gate if (err == Z_OK) { 42737c478bd9Sstevel@tonic-gate zerr(gettext("A %s resource " 42747c478bd9Sstevel@tonic-gate "with the %s '%s' already exists."), 42757c478bd9Sstevel@tonic-gate rt_to_str(RT_RCTL), pt_to_str(PT_NAME), 42767c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_name); 42777c478bd9Sstevel@tonic-gate saw_error = TRUE; 42787c478bd9Sstevel@tonic-gate return; 42797c478bd9Sstevel@tonic-gate } 42807c478bd9Sstevel@tonic-gate err = zonecfg_add_rctl(handle, &in_progress_rctltab); 42817c478bd9Sstevel@tonic-gate } else { 42827c478bd9Sstevel@tonic-gate err = zonecfg_modify_rctl(handle, &old_rctltab, 42837c478bd9Sstevel@tonic-gate &in_progress_rctltab); 42847c478bd9Sstevel@tonic-gate } 42857c478bd9Sstevel@tonic-gate if (err == Z_OK) { 42867c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list( 42877c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_valptr); 42887c478bd9Sstevel@tonic-gate in_progress_rctltab.zone_rctl_valptr = NULL; 42897c478bd9Sstevel@tonic-gate } 42907c478bd9Sstevel@tonic-gate break; 4291087719fdSdp 42927c478bd9Sstevel@tonic-gate case RT_ATTR: 42937c478bd9Sstevel@tonic-gate /* First make sure everything was filled in. */ 4294087719fdSdp (void) end_check_reqd(in_progress_attrtab.zone_attr_name, 4295087719fdSdp PT_NAME, &validation_failed); 4296087719fdSdp (void) end_check_reqd(in_progress_attrtab.zone_attr_type, 4297087719fdSdp PT_TYPE, &validation_failed); 4298087719fdSdp (void) end_check_reqd(in_progress_attrtab.zone_attr_value, 4299087719fdSdp PT_VALUE, &validation_failed); 4300087719fdSdp 43017c478bd9Sstevel@tonic-gate if (validate_attr_name(in_progress_attrtab.zone_attr_name) != 4302087719fdSdp Z_OK) 43037c478bd9Sstevel@tonic-gate validation_failed = TRUE; 4304087719fdSdp 4305087719fdSdp if (validate_attr_type_val(&in_progress_attrtab) != Z_OK) 43067c478bd9Sstevel@tonic-gate validation_failed = TRUE; 4307087719fdSdp 4308087719fdSdp if (validation_failed) { 4309087719fdSdp saw_error = TRUE; 43107c478bd9Sstevel@tonic-gate return; 4311087719fdSdp } 43127c478bd9Sstevel@tonic-gate if (end_op == CMD_ADD) { 43137c478bd9Sstevel@tonic-gate /* Make sure there isn't already one like this. */ 43147c478bd9Sstevel@tonic-gate bzero(&tmp_attrtab, sizeof (tmp_attrtab)); 43157c478bd9Sstevel@tonic-gate (void) strlcpy(tmp_attrtab.zone_attr_name, 43167c478bd9Sstevel@tonic-gate in_progress_attrtab.zone_attr_name, 43177c478bd9Sstevel@tonic-gate sizeof (tmp_attrtab.zone_attr_name)); 43187c478bd9Sstevel@tonic-gate if (zonecfg_lookup_attr(handle, &tmp_attrtab) == Z_OK) { 43197c478bd9Sstevel@tonic-gate zerr(gettext("An %s resource " 43207c478bd9Sstevel@tonic-gate "with the %s '%s' already exists."), 43217c478bd9Sstevel@tonic-gate rt_to_str(RT_ATTR), pt_to_str(PT_NAME), 43227c478bd9Sstevel@tonic-gate in_progress_attrtab.zone_attr_name); 43237c478bd9Sstevel@tonic-gate saw_error = TRUE; 43247c478bd9Sstevel@tonic-gate return; 43257c478bd9Sstevel@tonic-gate } 43267c478bd9Sstevel@tonic-gate err = zonecfg_add_attr(handle, &in_progress_attrtab); 43277c478bd9Sstevel@tonic-gate } else { 43287c478bd9Sstevel@tonic-gate err = zonecfg_modify_attr(handle, &old_attrtab, 43297c478bd9Sstevel@tonic-gate &in_progress_attrtab); 43307c478bd9Sstevel@tonic-gate } 43317c478bd9Sstevel@tonic-gate break; 4332fa9e4066Sahrens case RT_DATASET: 4333fa9e4066Sahrens /* First make sure everything was filled in. */ 4334fa9e4066Sahrens if (strlen(in_progress_dstab.zone_dataset_name) == 0) { 4335fa9e4066Sahrens zerr("%s %s", pt_to_str(PT_NAME), 4336fa9e4066Sahrens gettext("not specified")); 4337fa9e4066Sahrens saw_error = TRUE; 4338fa9e4066Sahrens validation_failed = TRUE; 4339fa9e4066Sahrens } 4340fa9e4066Sahrens if (validation_failed) 4341fa9e4066Sahrens return; 4342fa9e4066Sahrens if (end_op == CMD_ADD) { 4343fa9e4066Sahrens /* Make sure there isn't already one like this. */ 4344fa9e4066Sahrens bzero(&tmp_dstab, sizeof (tmp_dstab)); 4345fa9e4066Sahrens (void) strlcpy(tmp_dstab.zone_dataset_name, 4346fa9e4066Sahrens in_progress_dstab.zone_dataset_name, 4347fa9e4066Sahrens sizeof (tmp_dstab.zone_dataset_name)); 4348fa9e4066Sahrens err = zonecfg_lookup_ds(handle, &tmp_dstab); 4349fa9e4066Sahrens if (err == Z_OK) { 4350fa9e4066Sahrens zerr(gettext("A %s resource " 4351fa9e4066Sahrens "with the %s '%s' already exists."), 4352fa9e4066Sahrens rt_to_str(RT_DATASET), pt_to_str(PT_NAME), 4353fa9e4066Sahrens in_progress_dstab.zone_dataset_name); 4354fa9e4066Sahrens saw_error = TRUE; 4355fa9e4066Sahrens return; 4356fa9e4066Sahrens } 4357fa9e4066Sahrens err = zonecfg_add_ds(handle, &in_progress_dstab); 4358fa9e4066Sahrens } else { 4359fa9e4066Sahrens err = zonecfg_modify_ds(handle, &old_dstab, 4360fa9e4066Sahrens &in_progress_dstab); 4361fa9e4066Sahrens } 4362fa9e4066Sahrens break; 43637c478bd9Sstevel@tonic-gate default: 43647c478bd9Sstevel@tonic-gate zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE, 43657c478bd9Sstevel@tonic-gate TRUE); 43667c478bd9Sstevel@tonic-gate saw_error = TRUE; 43677c478bd9Sstevel@tonic-gate return; 43687c478bd9Sstevel@tonic-gate } 43697c478bd9Sstevel@tonic-gate 43707c478bd9Sstevel@tonic-gate if (err != Z_OK) { 43717c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 43727c478bd9Sstevel@tonic-gate } else { 43737c478bd9Sstevel@tonic-gate need_to_commit = TRUE; 43747c478bd9Sstevel@tonic-gate global_scope = TRUE; 43757c478bd9Sstevel@tonic-gate end_op = -1; 43767c478bd9Sstevel@tonic-gate } 43777c478bd9Sstevel@tonic-gate } 43787c478bd9Sstevel@tonic-gate 43797c478bd9Sstevel@tonic-gate void 43807c478bd9Sstevel@tonic-gate commit_func(cmd_t *cmd) 43817c478bd9Sstevel@tonic-gate { 43827c478bd9Sstevel@tonic-gate int arg; 43837c478bd9Sstevel@tonic-gate 43847c478bd9Sstevel@tonic-gate optind = 0; 43857c478bd9Sstevel@tonic-gate if ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?")) != EOF) { 43867c478bd9Sstevel@tonic-gate switch (arg) { 43877c478bd9Sstevel@tonic-gate case '?': 43887c478bd9Sstevel@tonic-gate longer_usage(CMD_COMMIT); 43897c478bd9Sstevel@tonic-gate return; 43907c478bd9Sstevel@tonic-gate default: 43917c478bd9Sstevel@tonic-gate short_usage(CMD_COMMIT); 43927c478bd9Sstevel@tonic-gate return; 43937c478bd9Sstevel@tonic-gate } 43947c478bd9Sstevel@tonic-gate } 43957c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 43967c478bd9Sstevel@tonic-gate short_usage(CMD_COMMIT); 43977c478bd9Sstevel@tonic-gate return; 43987c478bd9Sstevel@tonic-gate } 43997c478bd9Sstevel@tonic-gate 44007c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_COMMIT)) 44017c478bd9Sstevel@tonic-gate return; 44027c478bd9Sstevel@tonic-gate 44037c478bd9Sstevel@tonic-gate assert(cmd != NULL); 44047c478bd9Sstevel@tonic-gate 44057c478bd9Sstevel@tonic-gate cmd->cmd_argc = 1; 44067c478bd9Sstevel@tonic-gate /* 44077c478bd9Sstevel@tonic-gate * cmd_arg normally comes from a strdup() in the lexer, and the 44087c478bd9Sstevel@tonic-gate * whole cmd structure and its (char *) attributes are freed at 44097c478bd9Sstevel@tonic-gate * the completion of each command, so the strdup() below is needed 44107c478bd9Sstevel@tonic-gate * to match this and prevent a core dump from trying to free() 44117c478bd9Sstevel@tonic-gate * something that can't be. 44127c478bd9Sstevel@tonic-gate */ 44137c478bd9Sstevel@tonic-gate if ((cmd->cmd_argv[0] = strdup("save")) == NULL) { 44147c478bd9Sstevel@tonic-gate zone_perror(zone, Z_NOMEM, TRUE); 44157c478bd9Sstevel@tonic-gate exit(Z_ERR); 44167c478bd9Sstevel@tonic-gate } 44177c478bd9Sstevel@tonic-gate cmd->cmd_argv[1] = NULL; 44187c478bd9Sstevel@tonic-gate verify_func(cmd); 44197c478bd9Sstevel@tonic-gate } 44207c478bd9Sstevel@tonic-gate 44217c478bd9Sstevel@tonic-gate void 44227c478bd9Sstevel@tonic-gate revert_func(cmd_t *cmd) 44237c478bd9Sstevel@tonic-gate { 44247c478bd9Sstevel@tonic-gate char line[128]; /* enough to ask a question */ 44257c478bd9Sstevel@tonic-gate bool force = FALSE; 44267c478bd9Sstevel@tonic-gate int err, arg, answer; 44277c478bd9Sstevel@tonic-gate 44287c478bd9Sstevel@tonic-gate optind = 0; 44297c478bd9Sstevel@tonic-gate while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?F")) != EOF) { 44307c478bd9Sstevel@tonic-gate switch (arg) { 44317c478bd9Sstevel@tonic-gate case '?': 44327c478bd9Sstevel@tonic-gate longer_usage(CMD_REVERT); 44337c478bd9Sstevel@tonic-gate return; 44347c478bd9Sstevel@tonic-gate case 'F': 44357c478bd9Sstevel@tonic-gate force = TRUE; 44367c478bd9Sstevel@tonic-gate break; 44377c478bd9Sstevel@tonic-gate default: 44387c478bd9Sstevel@tonic-gate short_usage(CMD_REVERT); 44397c478bd9Sstevel@tonic-gate return; 44407c478bd9Sstevel@tonic-gate } 44417c478bd9Sstevel@tonic-gate } 44427c478bd9Sstevel@tonic-gate if (optind != cmd->cmd_argc) { 44437c478bd9Sstevel@tonic-gate short_usage(CMD_REVERT); 44447c478bd9Sstevel@tonic-gate return; 44457c478bd9Sstevel@tonic-gate } 44467c478bd9Sstevel@tonic-gate 44477c478bd9Sstevel@tonic-gate if (zone_is_read_only(CMD_REVERT)) 44487c478bd9Sstevel@tonic-gate return; 44497c478bd9Sstevel@tonic-gate 44507c478bd9Sstevel@tonic-gate if (zonecfg_check_handle(handle) != Z_OK) { 44517c478bd9Sstevel@tonic-gate zerr(gettext("No changes to revert.")); 44527c478bd9Sstevel@tonic-gate saw_error = TRUE; 44537c478bd9Sstevel@tonic-gate return; 44547c478bd9Sstevel@tonic-gate } 44557c478bd9Sstevel@tonic-gate 44567c478bd9Sstevel@tonic-gate if (!force) { 44577c478bd9Sstevel@tonic-gate (void) snprintf(line, sizeof (line), 44587c478bd9Sstevel@tonic-gate gettext("Are you sure you want to revert")); 44597c478bd9Sstevel@tonic-gate if ((answer = ask_yesno(FALSE, line)) == -1) { 44607c478bd9Sstevel@tonic-gate zerr(gettext("Input not from terminal and -F not " 44617c478bd9Sstevel@tonic-gate "specified:\n%s command ignored, exiting."), 44627c478bd9Sstevel@tonic-gate cmd_to_str(CMD_REVERT)); 44637c478bd9Sstevel@tonic-gate exit(Z_ERR); 44647c478bd9Sstevel@tonic-gate } 44657c478bd9Sstevel@tonic-gate if (answer != 1) 44667c478bd9Sstevel@tonic-gate return; 44677c478bd9Sstevel@tonic-gate } 44687c478bd9Sstevel@tonic-gate 44697c478bd9Sstevel@tonic-gate /* 44707c478bd9Sstevel@tonic-gate * Time for a new handle: finish the old one off first 44717c478bd9Sstevel@tonic-gate * then get a new one properly to avoid leaks. 44727c478bd9Sstevel@tonic-gate */ 44737c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 44747c478bd9Sstevel@tonic-gate if ((handle = zonecfg_init_handle()) == NULL) { 44757c478bd9Sstevel@tonic-gate zone_perror(execname, Z_NOMEM, TRUE); 44767c478bd9Sstevel@tonic-gate exit(Z_ERR); 44777c478bd9Sstevel@tonic-gate } 4478087719fdSdp if ((err = zonecfg_get_handle(revert_zone, handle)) != Z_OK) { 44797c478bd9Sstevel@tonic-gate saw_error = TRUE; 44807c478bd9Sstevel@tonic-gate got_handle = FALSE; 44817c478bd9Sstevel@tonic-gate if (err == Z_NO_ZONE) 44827c478bd9Sstevel@tonic-gate zerr(gettext("%s: no such saved zone to revert to."), 4483087719fdSdp revert_zone); 44847c478bd9Sstevel@tonic-gate else 44857c478bd9Sstevel@tonic-gate zone_perror(zone, err, TRUE); 44867c478bd9Sstevel@tonic-gate } 4487087719fdSdp (void) strlcpy(zone, revert_zone, sizeof (zone)); 44887c478bd9Sstevel@tonic-gate } 44897c478bd9Sstevel@tonic-gate 44907c478bd9Sstevel@tonic-gate void 44917c478bd9Sstevel@tonic-gate help_func(cmd_t *cmd) 44927c478bd9Sstevel@tonic-gate { 44937c478bd9Sstevel@tonic-gate int i; 44947c478bd9Sstevel@tonic-gate 44957c478bd9Sstevel@tonic-gate assert(cmd != NULL); 44967c478bd9Sstevel@tonic-gate 44977c478bd9Sstevel@tonic-gate if (cmd->cmd_argc == 0) { 44987c478bd9Sstevel@tonic-gate usage(TRUE, global_scope ? HELP_SUBCMDS : HELP_RES_SCOPE); 44997c478bd9Sstevel@tonic-gate return; 45007c478bd9Sstevel@tonic-gate } 45017c478bd9Sstevel@tonic-gate if (strcmp(cmd->cmd_argv[0], "usage") == 0) { 45027c478bd9Sstevel@tonic-gate usage(TRUE, HELP_USAGE); 45037c478bd9Sstevel@tonic-gate return; 45047c478bd9Sstevel@tonic-gate } 45057c478bd9Sstevel@tonic-gate if (strcmp(cmd->cmd_argv[0], "commands") == 0) { 45067c478bd9Sstevel@tonic-gate usage(TRUE, HELP_SUBCMDS); 45077c478bd9Sstevel@tonic-gate return; 45087c478bd9Sstevel@tonic-gate } 45097c478bd9Sstevel@tonic-gate if (strcmp(cmd->cmd_argv[0], "syntax") == 0) { 45107c478bd9Sstevel@tonic-gate usage(TRUE, HELP_SYNTAX | HELP_RES_PROPS); 45117c478bd9Sstevel@tonic-gate return; 45127c478bd9Sstevel@tonic-gate } 45137c478bd9Sstevel@tonic-gate if (strcmp(cmd->cmd_argv[0], "-?") == 0) { 45147c478bd9Sstevel@tonic-gate longer_usage(CMD_HELP); 45157c478bd9Sstevel@tonic-gate return; 45167c478bd9Sstevel@tonic-gate } 45177c478bd9Sstevel@tonic-gate 45187c478bd9Sstevel@tonic-gate for (i = 0; i <= CMD_MAX; i++) { 45197c478bd9Sstevel@tonic-gate if (strcmp(cmd->cmd_argv[0], cmd_to_str(i)) == 0) { 45207c478bd9Sstevel@tonic-gate longer_usage(i); 45217c478bd9Sstevel@tonic-gate return; 45227c478bd9Sstevel@tonic-gate } 45237c478bd9Sstevel@tonic-gate } 45247c478bd9Sstevel@tonic-gate /* We do not use zerr() here because we do not want its extra \n. */ 45257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Unknown help subject %s. "), 45267c478bd9Sstevel@tonic-gate cmd->cmd_argv[0]); 45277c478bd9Sstevel@tonic-gate usage(FALSE, HELP_META); 45287c478bd9Sstevel@tonic-gate } 45297c478bd9Sstevel@tonic-gate 45307c478bd9Sstevel@tonic-gate static int 45317c478bd9Sstevel@tonic-gate string_to_yyin(char *string) 45327c478bd9Sstevel@tonic-gate { 45337c478bd9Sstevel@tonic-gate if ((yyin = tmpfile()) == NULL) { 45347c478bd9Sstevel@tonic-gate zone_perror(execname, Z_TEMP_FILE, TRUE); 45357c478bd9Sstevel@tonic-gate return (Z_ERR); 45367c478bd9Sstevel@tonic-gate } 45377c478bd9Sstevel@tonic-gate if (fwrite(string, strlen(string), 1, yyin) != 1) { 45387c478bd9Sstevel@tonic-gate zone_perror(execname, Z_TEMP_FILE, TRUE); 45397c478bd9Sstevel@tonic-gate return (Z_ERR); 45407c478bd9Sstevel@tonic-gate } 45417c478bd9Sstevel@tonic-gate if (fseek(yyin, 0, SEEK_SET) != 0) { 45427c478bd9Sstevel@tonic-gate zone_perror(execname, Z_TEMP_FILE, TRUE); 45437c478bd9Sstevel@tonic-gate return (Z_ERR); 45447c478bd9Sstevel@tonic-gate } 45457c478bd9Sstevel@tonic-gate return (Z_OK); 45467c478bd9Sstevel@tonic-gate } 45477c478bd9Sstevel@tonic-gate 45487c478bd9Sstevel@tonic-gate /* This is the back-end helper function for read_input() below. */ 45497c478bd9Sstevel@tonic-gate 45507c478bd9Sstevel@tonic-gate static int 45517c478bd9Sstevel@tonic-gate cleanup() 45527c478bd9Sstevel@tonic-gate { 45537c478bd9Sstevel@tonic-gate int answer; 45547c478bd9Sstevel@tonic-gate cmd_t *cmd; 45557c478bd9Sstevel@tonic-gate 45567c478bd9Sstevel@tonic-gate if (!interactive_mode && !cmd_file_mode) { 45577c478bd9Sstevel@tonic-gate /* 45587c478bd9Sstevel@tonic-gate * If we're not in interactive mode, and we're not in command 45597c478bd9Sstevel@tonic-gate * file mode, then we must be in commands-from-the-command-line 45607c478bd9Sstevel@tonic-gate * mode. As such, we can't loop back and ask for more input. 45617c478bd9Sstevel@tonic-gate * It was OK to prompt for such things as whether or not to 45627c478bd9Sstevel@tonic-gate * really delete a zone in the command handler called from 45637c478bd9Sstevel@tonic-gate * yyparse() above, but "really quit?" makes no sense in this 45647c478bd9Sstevel@tonic-gate * context. So disable prompting. 45657c478bd9Sstevel@tonic-gate */ 45667c478bd9Sstevel@tonic-gate ok_to_prompt = FALSE; 45677c478bd9Sstevel@tonic-gate } 45687c478bd9Sstevel@tonic-gate if (!global_scope) { 45697c478bd9Sstevel@tonic-gate if (!time_to_exit) { 45707c478bd9Sstevel@tonic-gate /* 45717c478bd9Sstevel@tonic-gate * Just print a simple error message in the -1 case, 45727c478bd9Sstevel@tonic-gate * since exit_func() already handles that case, and 45737c478bd9Sstevel@tonic-gate * EOF means we are finished anyway. 45747c478bd9Sstevel@tonic-gate */ 45757c478bd9Sstevel@tonic-gate answer = ask_yesno(FALSE, 45767c478bd9Sstevel@tonic-gate gettext("Resource incomplete; really quit")); 45777c478bd9Sstevel@tonic-gate if (answer == -1) { 45787c478bd9Sstevel@tonic-gate zerr(gettext("Resource incomplete.")); 45797c478bd9Sstevel@tonic-gate return (Z_ERR); 45807c478bd9Sstevel@tonic-gate } 45817c478bd9Sstevel@tonic-gate if (answer != 1) { 45827c478bd9Sstevel@tonic-gate yyin = stdin; 45837c478bd9Sstevel@tonic-gate return (Z_REPEAT); 45847c478bd9Sstevel@tonic-gate } 45857c478bd9Sstevel@tonic-gate } else { 45867c478bd9Sstevel@tonic-gate saw_error = TRUE; 45877c478bd9Sstevel@tonic-gate } 45887c478bd9Sstevel@tonic-gate } 45897c478bd9Sstevel@tonic-gate /* 45907c478bd9Sstevel@tonic-gate * Make sure we tried something and that the handle checks 45917c478bd9Sstevel@tonic-gate * out, or we would get a false error trying to commit. 45927c478bd9Sstevel@tonic-gate */ 45937c478bd9Sstevel@tonic-gate if (need_to_commit && zonecfg_check_handle(handle) == Z_OK) { 45947c478bd9Sstevel@tonic-gate if ((cmd = alloc_cmd()) == NULL) { 45957c478bd9Sstevel@tonic-gate zone_perror(zone, Z_NOMEM, TRUE); 45967c478bd9Sstevel@tonic-gate return (Z_ERR); 45977c478bd9Sstevel@tonic-gate } 45987c478bd9Sstevel@tonic-gate cmd->cmd_argc = 0; 45997c478bd9Sstevel@tonic-gate cmd->cmd_argv[0] = NULL; 46007c478bd9Sstevel@tonic-gate commit_func(cmd); 46017c478bd9Sstevel@tonic-gate free_cmd(cmd); 46027c478bd9Sstevel@tonic-gate /* 46037c478bd9Sstevel@tonic-gate * need_to_commit will get set back to FALSE if the 46047c478bd9Sstevel@tonic-gate * configuration is saved successfully. 46057c478bd9Sstevel@tonic-gate */ 46067c478bd9Sstevel@tonic-gate if (need_to_commit) { 46077c478bd9Sstevel@tonic-gate if (force_exit) { 46087c478bd9Sstevel@tonic-gate zerr(gettext("Configuration not saved.")); 46097c478bd9Sstevel@tonic-gate return (Z_ERR); 46107c478bd9Sstevel@tonic-gate } 46117c478bd9Sstevel@tonic-gate answer = ask_yesno(FALSE, 46127c478bd9Sstevel@tonic-gate gettext("Configuration not saved; really quit")); 46137c478bd9Sstevel@tonic-gate if (answer == -1) { 46147c478bd9Sstevel@tonic-gate zerr(gettext("Configuration not saved.")); 46157c478bd9Sstevel@tonic-gate return (Z_ERR); 46167c478bd9Sstevel@tonic-gate } 46177c478bd9Sstevel@tonic-gate if (answer != 1) { 46187c478bd9Sstevel@tonic-gate time_to_exit = FALSE; 46197c478bd9Sstevel@tonic-gate yyin = stdin; 46207c478bd9Sstevel@tonic-gate return (Z_REPEAT); 46217c478bd9Sstevel@tonic-gate } 46227c478bd9Sstevel@tonic-gate } 46237c478bd9Sstevel@tonic-gate } 46247c478bd9Sstevel@tonic-gate return ((need_to_commit || saw_error) ? Z_ERR : Z_OK); 46257c478bd9Sstevel@tonic-gate } 46267c478bd9Sstevel@tonic-gate 46277c478bd9Sstevel@tonic-gate /* 46287c478bd9Sstevel@tonic-gate * read_input() is the driver of this program. It is a wrapper around 46297c478bd9Sstevel@tonic-gate * yyparse(), printing appropriate prompts when needed, checking for 46307c478bd9Sstevel@tonic-gate * exit conditions and reacting appropriately [the latter in its cleanup() 46317c478bd9Sstevel@tonic-gate * helper function]. 46327c478bd9Sstevel@tonic-gate * 46337c478bd9Sstevel@tonic-gate * Like most zonecfg functions, it returns Z_OK or Z_ERR, *or* Z_REPEAT 46347c478bd9Sstevel@tonic-gate * so do_interactive() knows that we are not really done (i.e, we asked 46357c478bd9Sstevel@tonic-gate * the user if we should really quit and the user said no). 46367c478bd9Sstevel@tonic-gate */ 46377c478bd9Sstevel@tonic-gate static int 46387c478bd9Sstevel@tonic-gate read_input() 46397c478bd9Sstevel@tonic-gate { 46407c478bd9Sstevel@tonic-gate bool yyin_is_a_tty = isatty(fileno(yyin)); 46417c478bd9Sstevel@tonic-gate /* 46427c478bd9Sstevel@tonic-gate * The prompt is "e:z> " or "e:z:r> " where e is execname, z is zone 46437c478bd9Sstevel@tonic-gate * and r is resource_scope: 5 is for the two ":"s + "> " + terminator. 46447c478bd9Sstevel@tonic-gate */ 46457c478bd9Sstevel@tonic-gate char prompt[MAXPATHLEN + ZONENAME_MAX + MAX_RT_STRLEN + 5], *line; 46467c478bd9Sstevel@tonic-gate 46477c478bd9Sstevel@tonic-gate /* yyin should have been set to the appropriate (FILE *) if not stdin */ 46487c478bd9Sstevel@tonic-gate newline_terminated = TRUE; 46497c478bd9Sstevel@tonic-gate for (;;) { 46507c478bd9Sstevel@tonic-gate if (yyin_is_a_tty) { 46517c478bd9Sstevel@tonic-gate if (newline_terminated) { 46527c478bd9Sstevel@tonic-gate if (global_scope) 46537c478bd9Sstevel@tonic-gate (void) snprintf(prompt, sizeof (prompt), 46547c478bd9Sstevel@tonic-gate "%s:%s> ", execname, zone); 46557c478bd9Sstevel@tonic-gate else 46567c478bd9Sstevel@tonic-gate (void) snprintf(prompt, sizeof (prompt), 46577c478bd9Sstevel@tonic-gate "%s:%s:%s> ", execname, zone, 46587c478bd9Sstevel@tonic-gate rt_to_str(resource_scope)); 46597c478bd9Sstevel@tonic-gate } 46607c478bd9Sstevel@tonic-gate /* 46617c478bd9Sstevel@tonic-gate * If the user hits ^C then we want to catch it and 46627c478bd9Sstevel@tonic-gate * start over. If the user hits EOF then we want to 46637c478bd9Sstevel@tonic-gate * bail out. 46647c478bd9Sstevel@tonic-gate */ 46657c478bd9Sstevel@tonic-gate line = gl_get_line(gl, prompt, NULL, -1); 46667c478bd9Sstevel@tonic-gate if (gl_return_status(gl) == GLR_SIGNAL) { 46677c478bd9Sstevel@tonic-gate gl_abandon_line(gl); 46687c478bd9Sstevel@tonic-gate continue; 46697c478bd9Sstevel@tonic-gate } 46707c478bd9Sstevel@tonic-gate if (line == NULL) 46717c478bd9Sstevel@tonic-gate break; 46727c478bd9Sstevel@tonic-gate (void) string_to_yyin(line); 46737c478bd9Sstevel@tonic-gate while (!feof(yyin)) 46747c478bd9Sstevel@tonic-gate yyparse(); 46757c478bd9Sstevel@tonic-gate } else { 46767c478bd9Sstevel@tonic-gate yyparse(); 46777c478bd9Sstevel@tonic-gate } 46787c478bd9Sstevel@tonic-gate /* Bail out on an error in command file mode. */ 46797c478bd9Sstevel@tonic-gate if (saw_error && cmd_file_mode && !interactive_mode) 46807c478bd9Sstevel@tonic-gate time_to_exit = TRUE; 46817c478bd9Sstevel@tonic-gate if (time_to_exit || (!yyin_is_a_tty && feof(yyin))) 46827c478bd9Sstevel@tonic-gate break; 46837c478bd9Sstevel@tonic-gate } 46847c478bd9Sstevel@tonic-gate return (cleanup()); 46857c478bd9Sstevel@tonic-gate } 46867c478bd9Sstevel@tonic-gate 46877c478bd9Sstevel@tonic-gate /* 46887c478bd9Sstevel@tonic-gate * This function is used in the zonecfg-interactive-mode scenario: it just 46897c478bd9Sstevel@tonic-gate * calls read_input() until we are done. 46907c478bd9Sstevel@tonic-gate */ 46917c478bd9Sstevel@tonic-gate 46927c478bd9Sstevel@tonic-gate static int 46937c478bd9Sstevel@tonic-gate do_interactive(void) 46947c478bd9Sstevel@tonic-gate { 46957c478bd9Sstevel@tonic-gate int err; 46967c478bd9Sstevel@tonic-gate 46977c478bd9Sstevel@tonic-gate interactive_mode = TRUE; 46987c478bd9Sstevel@tonic-gate if (!read_only_mode) { 46997c478bd9Sstevel@tonic-gate /* 47007c478bd9Sstevel@tonic-gate * Try to set things up proactively in interactive mode, so 47017c478bd9Sstevel@tonic-gate * that if the zone in question does not exist yet, we can 47027c478bd9Sstevel@tonic-gate * provide the user with a clue. 47037c478bd9Sstevel@tonic-gate */ 47047c478bd9Sstevel@tonic-gate (void) initialize(FALSE); 47057c478bd9Sstevel@tonic-gate } 4706087719fdSdp do { 47077c478bd9Sstevel@tonic-gate err = read_input(); 4708087719fdSdp } while (err == Z_REPEAT); 47097c478bd9Sstevel@tonic-gate return (err); 47107c478bd9Sstevel@tonic-gate } 47117c478bd9Sstevel@tonic-gate 47127c478bd9Sstevel@tonic-gate /* 47137c478bd9Sstevel@tonic-gate * cmd_file is slightly more complicated, as it has to open the command file 47147c478bd9Sstevel@tonic-gate * and set yyin appropriately. Once that is done, though, it just calls 47157c478bd9Sstevel@tonic-gate * read_input(), and only once, since prompting is not possible. 47167c478bd9Sstevel@tonic-gate */ 47177c478bd9Sstevel@tonic-gate 47187c478bd9Sstevel@tonic-gate static int 47197c478bd9Sstevel@tonic-gate cmd_file(char *file) 47207c478bd9Sstevel@tonic-gate { 47217c478bd9Sstevel@tonic-gate FILE *infile; 47227c478bd9Sstevel@tonic-gate int err; 47237c478bd9Sstevel@tonic-gate struct stat statbuf; 47247c478bd9Sstevel@tonic-gate bool using_real_file = (strcmp(file, "-") != 0); 47257c478bd9Sstevel@tonic-gate 47267c478bd9Sstevel@tonic-gate if (using_real_file) { 47277c478bd9Sstevel@tonic-gate /* 47287c478bd9Sstevel@tonic-gate * zerr() prints a line number in cmd_file_mode, which we do 47297c478bd9Sstevel@tonic-gate * not want here, so temporarily unset it. 47307c478bd9Sstevel@tonic-gate */ 47317c478bd9Sstevel@tonic-gate cmd_file_mode = FALSE; 47327c478bd9Sstevel@tonic-gate if ((infile = fopen(file, "r")) == NULL) { 47337c478bd9Sstevel@tonic-gate zerr(gettext("could not open file %s: %s"), 47347c478bd9Sstevel@tonic-gate file, strerror(errno)); 47357c478bd9Sstevel@tonic-gate return (Z_ERR); 47367c478bd9Sstevel@tonic-gate } 47377c478bd9Sstevel@tonic-gate if ((err = fstat(fileno(infile), &statbuf)) != 0) { 47387c478bd9Sstevel@tonic-gate zerr(gettext("could not stat file %s: %s"), 47397c478bd9Sstevel@tonic-gate file, strerror(errno)); 47407c478bd9Sstevel@tonic-gate err = Z_ERR; 47417c478bd9Sstevel@tonic-gate goto done; 47427c478bd9Sstevel@tonic-gate } 47437c478bd9Sstevel@tonic-gate if (!S_ISREG(statbuf.st_mode)) { 47447c478bd9Sstevel@tonic-gate zerr(gettext("%s is not a regular file."), file); 47457c478bd9Sstevel@tonic-gate err = Z_ERR; 47467c478bd9Sstevel@tonic-gate goto done; 47477c478bd9Sstevel@tonic-gate } 47487c478bd9Sstevel@tonic-gate yyin = infile; 47497c478bd9Sstevel@tonic-gate cmd_file_mode = TRUE; 47507c478bd9Sstevel@tonic-gate ok_to_prompt = FALSE; 47517c478bd9Sstevel@tonic-gate } else { 47527c478bd9Sstevel@tonic-gate /* 47537c478bd9Sstevel@tonic-gate * "-f -" is essentially the same as interactive mode, 47547c478bd9Sstevel@tonic-gate * so treat it that way. 47557c478bd9Sstevel@tonic-gate */ 47567c478bd9Sstevel@tonic-gate interactive_mode = TRUE; 47577c478bd9Sstevel@tonic-gate } 47587c478bd9Sstevel@tonic-gate /* Z_REPEAT is for interactive mode; treat it like Z_ERR here. */ 47597c478bd9Sstevel@tonic-gate if ((err = read_input()) == Z_REPEAT) 47607c478bd9Sstevel@tonic-gate err = Z_ERR; 47617c478bd9Sstevel@tonic-gate done: 47627c478bd9Sstevel@tonic-gate if (using_real_file) 47637c478bd9Sstevel@tonic-gate (void) fclose(infile); 47647c478bd9Sstevel@tonic-gate return (err); 47657c478bd9Sstevel@tonic-gate } 47667c478bd9Sstevel@tonic-gate 47677c478bd9Sstevel@tonic-gate /* 47687c478bd9Sstevel@tonic-gate * Since yacc is based on reading from a (FILE *) whereas what we get from 47697c478bd9Sstevel@tonic-gate * the command line is in argv format, we need to convert when the user 47707c478bd9Sstevel@tonic-gate * gives us commands directly from the command line. That is done here by 47717c478bd9Sstevel@tonic-gate * concatenating the argv list into a space-separated string, writing it 47727c478bd9Sstevel@tonic-gate * to a temp file, and rewinding the file so yyin can be set to it. Then 47737c478bd9Sstevel@tonic-gate * we call read_input(), and only once, since prompting about whether to 47747c478bd9Sstevel@tonic-gate * continue or quit would make no sense in this context. 47757c478bd9Sstevel@tonic-gate */ 47767c478bd9Sstevel@tonic-gate 47777c478bd9Sstevel@tonic-gate static int 47787c478bd9Sstevel@tonic-gate one_command_at_a_time(int argc, char *argv[]) 47797c478bd9Sstevel@tonic-gate { 47807c478bd9Sstevel@tonic-gate char *command; 47817c478bd9Sstevel@tonic-gate size_t len = 2; /* terminal \n\0 */ 47827c478bd9Sstevel@tonic-gate int i, err; 47837c478bd9Sstevel@tonic-gate 47847c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i++) 47857c478bd9Sstevel@tonic-gate len += strlen(argv[i]) + 1; 47867c478bd9Sstevel@tonic-gate if ((command = malloc(len)) == NULL) { 47877c478bd9Sstevel@tonic-gate zone_perror(execname, Z_NOMEM, TRUE); 47887c478bd9Sstevel@tonic-gate return (Z_ERR); 47897c478bd9Sstevel@tonic-gate } 47907c478bd9Sstevel@tonic-gate (void) strlcpy(command, argv[0], len); 47917c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i++) { 47927c478bd9Sstevel@tonic-gate (void) strlcat(command, " ", len); 47937c478bd9Sstevel@tonic-gate (void) strlcat(command, argv[i], len); 47947c478bd9Sstevel@tonic-gate } 47957c478bd9Sstevel@tonic-gate (void) strlcat(command, "\n", len); 47967c478bd9Sstevel@tonic-gate err = string_to_yyin(command); 47977c478bd9Sstevel@tonic-gate free(command); 47987c478bd9Sstevel@tonic-gate if (err != Z_OK) 47997c478bd9Sstevel@tonic-gate return (err); 48007c478bd9Sstevel@tonic-gate while (!feof(yyin)) 48017c478bd9Sstevel@tonic-gate yyparse(); 48027c478bd9Sstevel@tonic-gate return (cleanup()); 48037c478bd9Sstevel@tonic-gate } 48047c478bd9Sstevel@tonic-gate 48057c478bd9Sstevel@tonic-gate static char * 48067c478bd9Sstevel@tonic-gate get_execbasename(char *execfullname) 48077c478bd9Sstevel@tonic-gate { 48087c478bd9Sstevel@tonic-gate char *last_slash, *execbasename; 48097c478bd9Sstevel@tonic-gate 48107c478bd9Sstevel@tonic-gate /* guard against '/' at end of command invocation */ 48117c478bd9Sstevel@tonic-gate for (;;) { 48127c478bd9Sstevel@tonic-gate last_slash = strrchr(execfullname, '/'); 48137c478bd9Sstevel@tonic-gate if (last_slash == NULL) { 48147c478bd9Sstevel@tonic-gate execbasename = execfullname; 48157c478bd9Sstevel@tonic-gate break; 48167c478bd9Sstevel@tonic-gate } else { 48177c478bd9Sstevel@tonic-gate execbasename = last_slash + 1; 48187c478bd9Sstevel@tonic-gate if (*execbasename == '\0') { 48197c478bd9Sstevel@tonic-gate *last_slash = '\0'; 48207c478bd9Sstevel@tonic-gate continue; 48217c478bd9Sstevel@tonic-gate } 48227c478bd9Sstevel@tonic-gate break; 48237c478bd9Sstevel@tonic-gate } 48247c478bd9Sstevel@tonic-gate } 48257c478bd9Sstevel@tonic-gate return (execbasename); 48267c478bd9Sstevel@tonic-gate } 48277c478bd9Sstevel@tonic-gate 48287c478bd9Sstevel@tonic-gate int 48297c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 48307c478bd9Sstevel@tonic-gate { 48317c478bd9Sstevel@tonic-gate int err, arg; 4832555afedfScarlsonj struct stat st; 48337c478bd9Sstevel@tonic-gate 48347c478bd9Sstevel@tonic-gate /* This must be before anything goes to stdout. */ 48357c478bd9Sstevel@tonic-gate setbuf(stdout, NULL); 48367c478bd9Sstevel@tonic-gate 48377c478bd9Sstevel@tonic-gate saw_error = FALSE; 48387c478bd9Sstevel@tonic-gate cmd_file_mode = FALSE; 48397c478bd9Sstevel@tonic-gate execname = get_execbasename(argv[0]); 48407c478bd9Sstevel@tonic-gate 48417c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 48427c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 48437c478bd9Sstevel@tonic-gate 48447c478bd9Sstevel@tonic-gate if (getzoneid() != GLOBAL_ZONEID) { 48457c478bd9Sstevel@tonic-gate zerr(gettext("%s can only be run from the global zone."), 48467c478bd9Sstevel@tonic-gate execname); 48477c478bd9Sstevel@tonic-gate exit(Z_ERR); 48487c478bd9Sstevel@tonic-gate } 48497c478bd9Sstevel@tonic-gate 48507c478bd9Sstevel@tonic-gate if (argc < 2) { 48517c478bd9Sstevel@tonic-gate usage(FALSE, HELP_USAGE | HELP_SUBCMDS); 48527c478bd9Sstevel@tonic-gate exit(Z_USAGE); 48537c478bd9Sstevel@tonic-gate } 48547c478bd9Sstevel@tonic-gate if (strcmp(argv[1], cmd_to_str(CMD_HELP)) == 0) { 48557c478bd9Sstevel@tonic-gate (void) one_command_at_a_time(argc - 1, &(argv[1])); 48567c478bd9Sstevel@tonic-gate exit(Z_OK); 48577c478bd9Sstevel@tonic-gate } 48587c478bd9Sstevel@tonic-gate 4859555afedfScarlsonj while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) { 48607c478bd9Sstevel@tonic-gate switch (arg) { 48617c478bd9Sstevel@tonic-gate case '?': 48627c478bd9Sstevel@tonic-gate if (optopt == '?') 48637c478bd9Sstevel@tonic-gate usage(TRUE, HELP_USAGE | HELP_SUBCMDS); 48647c478bd9Sstevel@tonic-gate else 48657c478bd9Sstevel@tonic-gate usage(FALSE, HELP_USAGE); 48667c478bd9Sstevel@tonic-gate exit(Z_USAGE); 48677c478bd9Sstevel@tonic-gate /* NOTREACHED */ 48687c478bd9Sstevel@tonic-gate case 'f': 48697c478bd9Sstevel@tonic-gate cmd_file_name = optarg; 48707c478bd9Sstevel@tonic-gate cmd_file_mode = TRUE; 48717c478bd9Sstevel@tonic-gate break; 4872555afedfScarlsonj case 'R': 4873555afedfScarlsonj if (*optarg != '/') { 4874555afedfScarlsonj zerr(gettext("root path must be absolute: %s"), 4875555afedfScarlsonj optarg); 4876555afedfScarlsonj exit(Z_USAGE); 4877555afedfScarlsonj } 4878555afedfScarlsonj if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { 4879555afedfScarlsonj zerr(gettext( 4880555afedfScarlsonj "root path must be a directory: %s"), 4881555afedfScarlsonj optarg); 4882555afedfScarlsonj exit(Z_USAGE); 4883555afedfScarlsonj } 4884555afedfScarlsonj zonecfg_set_root(optarg); 4885555afedfScarlsonj break; 48867c478bd9Sstevel@tonic-gate case 'z': 4887087719fdSdp if (zonecfg_validate_zonename(optarg) != Z_OK) { 4888087719fdSdp zone_perror(optarg, Z_BOGUS_ZONE_NAME, TRUE); 4889087719fdSdp usage(FALSE, HELP_SYNTAX); 4890087719fdSdp exit(Z_USAGE); 4891087719fdSdp } 4892087719fdSdp (void) strlcpy(zone, optarg, sizeof (zone)); 4893087719fdSdp (void) strlcpy(revert_zone, optarg, sizeof (zone)); 48947c478bd9Sstevel@tonic-gate break; 48957c478bd9Sstevel@tonic-gate default: 48967c478bd9Sstevel@tonic-gate usage(FALSE, HELP_USAGE); 48977c478bd9Sstevel@tonic-gate exit(Z_USAGE); 48987c478bd9Sstevel@tonic-gate } 48997c478bd9Sstevel@tonic-gate } 49007c478bd9Sstevel@tonic-gate 4901087719fdSdp if (optind > argc || strcmp(zone, "") == 0) { 49027c478bd9Sstevel@tonic-gate usage(FALSE, HELP_USAGE); 49037c478bd9Sstevel@tonic-gate exit(Z_USAGE); 49047c478bd9Sstevel@tonic-gate } 49057c478bd9Sstevel@tonic-gate 4906087719fdSdp if ((err = zonecfg_access(zone, W_OK)) == Z_OK) { 49077c478bd9Sstevel@tonic-gate read_only_mode = FALSE; 4908087719fdSdp } else if (err == Z_ACCES) { 49097c478bd9Sstevel@tonic-gate read_only_mode = TRUE; 49107c478bd9Sstevel@tonic-gate /* skip this message in one-off from command line mode */ 49117c478bd9Sstevel@tonic-gate if (optind == argc) 49127c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("WARNING: you do not " 49137c478bd9Sstevel@tonic-gate "have write access to this zone's configuration " 49147c478bd9Sstevel@tonic-gate "file;\ngoing into read-only mode.\n")); 4915087719fdSdp } else { 4916087719fdSdp fprintf(stderr, "%s: Could not access zone configuration " 4917087719fdSdp "store: %s\n", execname, zonecfg_strerror(err)); 4918087719fdSdp exit(Z_ERR); 49197c478bd9Sstevel@tonic-gate } 49207c478bd9Sstevel@tonic-gate 49217c478bd9Sstevel@tonic-gate if ((handle = zonecfg_init_handle()) == NULL) { 49227c478bd9Sstevel@tonic-gate zone_perror(execname, Z_NOMEM, TRUE); 49237c478bd9Sstevel@tonic-gate exit(Z_ERR); 49247c478bd9Sstevel@tonic-gate } 49257c478bd9Sstevel@tonic-gate 49267c478bd9Sstevel@tonic-gate /* 49277c478bd9Sstevel@tonic-gate * This may get set back to FALSE again in cmd_file() if cmd_file_name 49287c478bd9Sstevel@tonic-gate * is a "real" file as opposed to "-" (i.e. meaning use stdin). 49297c478bd9Sstevel@tonic-gate */ 49307c478bd9Sstevel@tonic-gate if (isatty(STDIN_FILENO)) 49317c478bd9Sstevel@tonic-gate ok_to_prompt = TRUE; 49327c478bd9Sstevel@tonic-gate if ((gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL) 49337c478bd9Sstevel@tonic-gate exit(Z_ERR); 49347c478bd9Sstevel@tonic-gate if (gl_customize_completion(gl, NULL, cmd_cpl_fn) != 0) 49357c478bd9Sstevel@tonic-gate exit(Z_ERR); 49367c478bd9Sstevel@tonic-gate (void) sigset(SIGINT, SIG_IGN); 49377c478bd9Sstevel@tonic-gate if (optind == argc) { 49387c478bd9Sstevel@tonic-gate if (!cmd_file_mode) 49397c478bd9Sstevel@tonic-gate err = do_interactive(); 49407c478bd9Sstevel@tonic-gate else 49417c478bd9Sstevel@tonic-gate err = cmd_file(cmd_file_name); 49427c478bd9Sstevel@tonic-gate } else { 49437c478bd9Sstevel@tonic-gate err = one_command_at_a_time(argc - optind, &(argv[optind])); 49447c478bd9Sstevel@tonic-gate } 49457c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 4946*9acbbeafSnn if (brand != NULL) 4947*9acbbeafSnn brand_close(brand); 49487c478bd9Sstevel@tonic-gate (void) del_GetLine(gl); 49497c478bd9Sstevel@tonic-gate return (err); 49507c478bd9Sstevel@tonic-gate } 4951