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
usage(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
config_print(pool_conf_t * conf)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
config_destroy(pool_conf_t * conf)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
config_commit(pool_conf_t * conf,const char * static_conf_name)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
main(int argc,char * argv[])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