xref: /illumos-gate/usr/src/cmd/pools/pooladm/pooladm.c (revision 4eaa471005973e11a6110b69fe990530b3b95a38)
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