1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * pooladm - set, remove, or display active pool configurations. 31 */ 32 33 #include <sys/zone.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <libintl.h> 39 #include <locale.h> 40 #include <string.h> 41 #include <priv.h> 42 #include <errno.h> 43 #include <zone.h> 44 #include <pool.h> 45 #include <unistd.h> 46 #include "utils.h" 47 48 #ifndef TEXT_DOMAIN 49 #define TEXT_DOMAIN "SYS_TEST" 50 #endif 51 52 static int Cflag; 53 static int Sflag; 54 static int Dflag; 55 static int Eflag; 56 static int Nflag; 57 static int Xflag; 58 59 static void 60 usage(void) 61 { 62 (void) fprintf(stderr, 63 gettext("Usage:\tpooladm [-n] [-s] [-c] [filename]\n")); 64 (void) fprintf(stderr, 65 gettext("Usage:\tpooladm [-n] -x\n")); 66 (void) fprintf(stderr, 67 gettext("Usage:\tpooladm -d | -e\n")); 68 exit(E_USAGE); 69 } 70 71 static void 72 config_print(pool_conf_t *conf) 73 { 74 char *buf; 75 pool_value_t *pv; 76 const char *tgt; 77 78 if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) 79 != PO_SUCCESS) 80 die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); 81 82 if ((pv = pool_value_alloc()) == NULL || 83 pool_get_property(conf, pool_conf_to_elem(conf), "system.name", 84 pv) == POC_INVAL || 85 pool_value_get_string(pv, &tgt) != PO_SUCCESS) 86 die(gettext(ERR_GET_ELEMENT_DETAILS), 87 gettext(CONFIGURATION), "unknown", get_errstr()); 88 89 if ((buf = pool_conf_info(conf, PO_TRUE)) == NULL) 90 die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION), 91 tgt, get_errstr()); 92 pool_value_free(pv); 93 (void) printf("%s", buf); 94 free(buf); 95 (void) pool_conf_close(conf); 96 } 97 98 static void 99 config_destroy(pool_conf_t *conf) 100 { 101 if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR) 102 != PO_SUCCESS) 103 die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); 104 if (pool_conf_remove(conf) != PO_SUCCESS) 105 die(gettext(ERR_REMOVE_DYNAMIC), get_errstr()); 106 } 107 108 static void 109 config_commit(pool_conf_t *conf, const char *static_conf_name) 110 { 111 if (pool_conf_open(conf, static_conf_name, Nflag || !Sflag ? 112 PO_RDONLY : PO_RDWR) != PO_SUCCESS) 113 die(gettext(ERR_OPEN_STATIC), static_conf_name, get_errstr()); 114 115 if (pool_conf_validate(conf, POV_RUNTIME) != PO_SUCCESS) 116 die(gettext(ERR_VALIDATE_RUNTIME), static_conf_name); 117 if (!Nflag) { 118 if (pool_conf_commit(conf, PO_TRUE) != PO_SUCCESS) 119 die(gettext(ERR_COMMIT_DYNAMIC), static_conf_name, 120 get_errstr()); 121 /* 122 * Dump the updated state to the specified location 123 */ 124 if (Sflag) { 125 if (pool_conf_commit(conf, PO_FALSE) != PO_SUCCESS) 126 die(gettext(ERR_COMMIT_STATIC), 127 static_conf_name, get_errstr()); 128 } 129 } 130 (void) pool_conf_close(conf); 131 } 132 133 int 134 main(int argc, char *argv[]) 135 { 136 char c; 137 pool_conf_t *conf = NULL; 138 const char *static_conf_loc; 139 140 (void) getpname(argv[0]); 141 (void) setlocale(LC_ALL, ""); 142 (void) textdomain(TEXT_DOMAIN); 143 144 145 while ((c = getopt(argc, argv, "cdensx")) != EOF) { 146 switch (c) { 147 case 'c': /* Create (or modify) system configuration */ 148 Cflag++; 149 break; 150 case 'd': /* Disable the pools facility */ 151 Dflag++; 152 break; 153 case 'e': /* Enable the pools facility */ 154 Eflag++; 155 break; 156 case 'n': /* Don't actually do anything */ 157 Nflag++; 158 break; 159 case 's': /* Update the submitted configuration */ 160 Sflag++; 161 break; 162 case 'x': /* Delete current system configuration */ 163 Xflag++; 164 break; 165 case '?': 166 default: 167 usage(); 168 /*NOTREACHED*/ 169 } 170 } 171 172 /* 173 * Not all flags can be used at the same time. 174 */ 175 if ((Cflag || Sflag || Dflag || Eflag) && Xflag) 176 usage(); 177 178 if ((Dflag || Eflag) && (Cflag || Sflag || Xflag)) 179 usage(); 180 181 if (Dflag && Eflag) 182 usage(); 183 184 argc -= optind; 185 argv += optind; 186 187 if (! (Cflag || Sflag)) { 188 if (argc != 0) 189 usage(); 190 } else { 191 if (argc == 0) 192 static_conf_loc = pool_static_location(); 193 else if (argc == 1) 194 static_conf_loc = argv[0]; 195 else 196 usage(); 197 } 198 199 if (!Nflag && (Cflag + Dflag + Eflag + Xflag != 0) && 200 !priv_ineffect(PRIV_SYS_RES_CONFIG)) 201 die(gettext(ERR_PERMISSIONS)); 202 203 if (Dflag) { 204 if (pool_set_status(POOL_DISABLED) != PO_SUCCESS) 205 die(gettext(ERR_DISABLE)); 206 } else if (Eflag) { 207 if (pool_set_status(POOL_ENABLED) != PO_SUCCESS) { 208 if (errno == EEXIST) 209 die(gettext(ERR_ENABLE 210 ": System has active processor sets\n")); 211 else 212 die(gettext(ERR_ENABLE)); 213 } 214 } else { 215 if ((conf = pool_conf_alloc()) == NULL) 216 die(gettext(ERR_NOMEM)); 217 218 if (Cflag + Sflag + Xflag == 0) { 219 /* 220 * No flags means print current system configuration 221 */ 222 config_print(conf); 223 } else if (!Nflag && Xflag) { 224 /* 225 * Destroy active pools configuration and 226 * remove the state file. 227 */ 228 config_destroy(conf); 229 } else { 230 /* 231 * Commit a new configuration. 232 */ 233 if (Cflag) 234 config_commit(conf, static_conf_loc); 235 else { 236 /* 237 * Dump the dynamic state to the 238 * specified location 239 */ 240 if (!Nflag && Sflag) { 241 if (pool_conf_open(conf, 242 pool_dynamic_location(), PO_RDONLY) 243 != PO_SUCCESS) 244 die(gettext(ERR_OPEN_DYNAMIC), 245 get_errstr()); 246 if (pool_conf_export(conf, 247 static_conf_loc, POX_NATIVE) != 248 PO_SUCCESS) 249 die(gettext(ERR_EXPORT_DYNAMIC), 250 static_conf_loc, get_errstr()); 251 (void) pool_conf_close(conf); 252 } 253 } 254 } 255 pool_conf_free(conf); 256 } 257 return (E_PO_SUCCESS); 258 } 259