xref: /illumos-gate/usr/src/cmd/pools/pooladm/pooladm.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
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 /*
28  * pooladm - set, remove, or display active pool configurations.
29  */
30 
31 #include <sys/zone.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <libintl.h>
37 #include <locale.h>
38 #include <string.h>
39 #include <priv.h>
40 #include <errno.h>
41 #include <zone.h>
42 #include <pool.h>
43 #include <unistd.h>
44 #include "utils.h"
45 
46 #ifndef	TEXT_DOMAIN
47 #define	TEXT_DOMAIN	"SYS_TEST"
48 #endif
49 
50 static int Cflag;
51 static int Sflag;
52 static int Dflag;
53 static int Eflag;
54 static int Nflag;
55 static int Xflag;
56 
57 static void
58 usage(void)
59 {
60 	(void) fprintf(stderr,
61 	    gettext("Usage:\tpooladm [-n] [-s] [-c] [filename]\n"));
62 	(void) fprintf(stderr,
63 	    gettext("Usage:\tpooladm [-n] -x\n"));
64 	(void) fprintf(stderr,
65 	    gettext("Usage:\tpooladm -d | -e\n"));
66 	exit(E_USAGE);
67 }
68 
69 static void
70 config_print(pool_conf_t *conf)
71 {
72 	char *buf;
73 	pool_value_t *pv;
74 	const char *tgt;
75 
76 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
77 	    != PO_SUCCESS)
78 		die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
79 
80 	if ((pv = pool_value_alloc()) == NULL ||
81 	    pool_get_property(conf, pool_conf_to_elem(conf), "system.name",
82 	    pv) == POC_INVAL ||
83 	    pool_value_get_string(pv, &tgt) != PO_SUCCESS)
84 		die(gettext(ERR_GET_ELEMENT_DETAILS),
85 		    gettext(CONFIGURATION), "unknown", get_errstr());
86 
87 	if ((buf = pool_conf_info(conf, PO_TRUE)) == NULL)
88 		die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION),
89 		    tgt, get_errstr());
90 	pool_value_free(pv);
91 	(void) printf("%s", buf);
92 	free(buf);
93 	(void) pool_conf_close(conf);
94 }
95 
96 static void
97 config_destroy(pool_conf_t *conf)
98 {
99 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR)
100 	    != PO_SUCCESS)
101 		die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
102 	if (pool_conf_remove(conf) != PO_SUCCESS)
103 		die(gettext(ERR_REMOVE_DYNAMIC), get_errstr());
104 }
105 
106 static void
107 config_commit(pool_conf_t *conf, const char *static_conf_name)
108 {
109 	if (pool_conf_open(conf, static_conf_name, Nflag || !Sflag ?
110 	    PO_RDONLY : PO_RDWR) != PO_SUCCESS)
111 		die(gettext(ERR_OPEN_STATIC), static_conf_name, get_errstr());
112 
113 	if (pool_conf_validate(conf, POV_RUNTIME) != PO_SUCCESS)
114 		die(gettext(ERR_VALIDATE_RUNTIME), static_conf_name);
115 	if (!Nflag) {
116 		if (pool_conf_commit(conf, PO_TRUE) != PO_SUCCESS)
117 			die(gettext(ERR_COMMIT_DYNAMIC), static_conf_name,
118 			    get_errstr());
119 		/*
120 		 * Dump the updated state to the specified location
121 		 */
122 		if (Sflag) {
123 			if (pool_conf_commit(conf, PO_FALSE) != PO_SUCCESS)
124 				die(gettext(ERR_COMMIT_STATIC),
125 				    static_conf_name, get_errstr());
126 		}
127 	}
128 	(void) pool_conf_close(conf);
129 }
130 
131 int
132 main(int argc, char *argv[])
133 {
134 	char c;
135 	pool_conf_t *conf = NULL;
136 	const char *static_conf_loc;
137 
138 	(void) getpname(argv[0]);
139 	(void) setlocale(LC_ALL, "");
140 	(void) textdomain(TEXT_DOMAIN);
141 
142 
143 	while ((c = getopt(argc, argv, "cdensx")) != EOF) {
144 		switch (c) {
145 		case 'c':	/* Create (or modify) system configuration */
146 			Cflag++;
147 			break;
148 		case 'd':	/* Disable the pools facility */
149 			Dflag++;
150 			break;
151 		case 'e':	/* Enable the pools facility */
152 			Eflag++;
153 			break;
154 		case 'n':	/* Don't actually do anything */
155 			Nflag++;
156 			break;
157 		case 's':	/* Update the submitted configuration */
158 			Sflag++;
159 			break;
160 		case 'x':	/* Delete current system configuration */
161 			Xflag++;
162 			break;
163 		case '?':
164 		default:
165 			usage();
166 			/*NOTREACHED*/
167 		}
168 	}
169 
170 	/*
171 	 * Not all flags can be used at the same time.
172 	 */
173 	if ((Cflag || Sflag || Dflag || Eflag) && Xflag)
174 		usage();
175 
176 	if ((Dflag || Eflag) && (Cflag || Sflag || Xflag))
177 		usage();
178 
179 	if (Dflag && Eflag)
180 		usage();
181 
182 	argc -= optind;
183 	argv += optind;
184 
185 	if (! (Cflag || Sflag)) {
186 		if (argc != 0)
187 			usage();
188 	} else {
189 		if (argc == 0)
190 			static_conf_loc = pool_static_location();
191 		else if (argc == 1)
192 			static_conf_loc = argv[0];
193 		else
194 			usage();
195 	}
196 
197 	if (!Nflag && (Cflag + Dflag + Eflag + Xflag != 0) &&
198 	    !priv_ineffect(PRIV_SYS_RES_CONFIG))
199 		die(gettext(ERR_PERMISSIONS));
200 
201 	if (Dflag) {
202 		if (pool_set_status(POOL_DISABLED) != PO_SUCCESS)
203 			die(gettext(ERR_DISABLE));
204 	} else if (Eflag) {
205 		if (pool_set_status(POOL_ENABLED) != PO_SUCCESS) {
206 			if (errno == EEXIST)
207 				die(gettext(ERR_ENABLE
208 				    ": System has active processor sets\n"));
209 			else
210 				die(gettext(ERR_ENABLE));
211 		}
212 	} else {
213 		if ((conf = pool_conf_alloc()) == NULL)
214 			die(gettext(ERR_NOMEM));
215 
216 		if (Cflag + Sflag + Xflag == 0) {
217 			/*
218 			 * No flags means print current system configuration
219 			 */
220 			config_print(conf);
221 		} else if (!Nflag && Xflag) {
222 			/*
223 			 * Destroy active pools configuration and
224 			 * remove the state file.
225 			 */
226 			config_destroy(conf);
227 		} else {
228 			/*
229 			 * Commit a new configuration.
230 			 */
231 			if (Cflag)
232 				config_commit(conf, static_conf_loc);
233 			else {
234 				/*
235 				 * Dump the dynamic state to the
236 				 * specified location
237 				 */
238 				if (!Nflag && Sflag) {
239 					if (pool_conf_open(conf,
240 					    pool_dynamic_location(), PO_RDONLY)
241 					!= PO_SUCCESS)
242 						die(gettext(ERR_OPEN_DYNAMIC),
243 						get_errstr());
244 					if (pool_conf_export(conf,
245 					    static_conf_loc, POX_NATIVE) !=
246 					    PO_SUCCESS)
247 						die(gettext(ERR_EXPORT_DYNAMIC),
248 						static_conf_loc, get_errstr());
249 					(void) pool_conf_close(conf);
250 				}
251 			}
252 		}
253 		pool_conf_free(conf);
254 	}
255 	return (E_PO_SUCCESS);
256 }
257