7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / util / metaparam.c
blob26754a049f8bf810104db3e19759e34d38fb229e
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * change metadevice parameters
32 #include <meta.h>
34 #include <sdssc.h>
37 * print usage message
39 static void
40 usage(
41 mdsetname_t *sp,
42 int eval
45 (void) fprintf(stderr, gettext("\
46 usage: %s [-s setname] [options] concat/stripe | RAID\n\
47 %s [-s setname] [options] mirror\n\
48 \n\
49 Concat/Stripe or RAID options:\n\
50 -h hotspare_pool | \"none\"\n\
51 \n\
52 Mirror options:\n\
53 -r roundrobin | geometric | first\n\
54 -w parallel | serial\n\
55 -p 0-%d\n"), myname, myname, MD_PASS_MAX);
57 md_exit(sp, eval);
61 * do mirror parameters
63 static int
64 mirror_params(
65 mdsetname_t *sp,
66 mdname_t *mirnp,
67 int argc,
68 char *argv[],
69 md_error_t *ep
72 mm_params_t mmp;
73 int modified = 0;
74 int c;
76 /* we must have a set */
77 assert(sp != NULL);
78 assert(sp->setno == MD_MIN2SET(meta_getminor(mirnp->dev)));
80 /* initialize */
81 (void) memset(&mmp, '\0', sizeof (mmp));
83 /* reset and parse args */
84 optind = 1;
85 opterr = 1;
86 while ((c = getopt(argc, argv, "s:r:w:p:")) != -1) {
87 switch (c) {
88 case 's':
89 break;
91 case 'r':
92 if (name_to_rd_opt(mirnp->cname, optarg,
93 &mmp.read_option, ep) != 0) {
94 return (-1);
96 mmp.change_read_option = 1;
97 modified = 1;
98 break;
100 case 'w':
101 if (name_to_wr_opt(mirnp->cname, optarg,
102 &mmp.write_option, ep) != 0) {
103 return (-1);
105 mmp.change_write_option = 1;
106 modified = 1;
107 break;
109 case 'p':
110 if (name_to_pass_num(mirnp->cname, optarg,
111 &mmp.pass_num, ep) != 0) {
112 return (-1);
114 mmp.change_pass_num = 1;
115 modified = 1;
116 break;
118 default:
119 usage(sp, 1);
120 /*NOTREACHED*/
121 break;
125 argc -= optind;
126 argv += optind;
127 if (argc != 1)
128 usage(sp, 1);
130 /* if just printing */
131 if (! modified) {
132 if (meta_mirror_get_params(sp, mirnp, &mmp, ep) != 0)
133 return (-1);
134 (void) printf(
135 gettext(
136 "%s: Mirror current parameters are:\n"),
137 mirnp->cname);
138 if (meta_print_mirror_options(mmp.read_option,
139 mmp.write_option, mmp.pass_num, 0, NULL,
140 sp, stdout, ep) != 0) {
141 return (-1);
145 /* otherwise, change parameters */
146 else {
147 if (meta_mirror_set_params(sp, mirnp, &mmp, ep) != 0)
148 return (-1);
150 /* update md.cf */
151 if (meta_update_md_cf(sp, ep) != 0)
152 return (-1);
155 /* return success */
156 return (0);
160 * do stripe parameters
162 static int
163 stripe_params(
164 mdsetname_t *sp,
165 mdname_t *stripenp,
166 int argc,
167 char *argv[],
168 md_error_t *ep
171 ms_params_t msp;
172 int modified = 0;
173 mdhspname_t *hspnp;
174 int c;
176 /* we must have a set */
177 assert(sp != NULL);
178 assert(sp->setno == MD_MIN2SET(meta_getminor(stripenp->dev)));
180 /* initialize */
181 (void) memset(&msp, '\0', sizeof (msp));
183 /* reset and parse args */
184 optind = 1;
185 opterr = 1;
186 while ((c = getopt(argc, argv, "s:h:")) != -1) {
187 switch (c) {
188 case 's':
189 break;
191 case 'h':
192 if (meta_is_none(optarg)) {
193 msp.hsp_id = MD_HSP_NONE;
194 } else if ((hspnp = metahspname(&sp, optarg,
195 ep)) == NULL) {
196 return (-1);
197 } else if (metachkhsp(sp, hspnp, ep) != 0) {
198 return (-1);
199 } else {
200 msp.hsp_id = hspnp->hsp;
202 msp.change_hsp_id = 1;
203 modified = 1;
204 break;
206 default:
207 usage(sp, 1);
208 /*NOTREACHED*/
209 break;
212 argc -= optind;
213 argv += optind;
214 if (argc != 1)
215 usage(sp, 1);
217 /* if just printing */
218 if (! modified) {
219 if (meta_stripe_get_params(sp, stripenp, &msp, ep) != 0)
220 return (-1);
221 if (msp.hsp_id == MD_HSP_NONE)
222 hspnp = NULL;
223 else if ((hspnp = metahsphspname(&sp, msp.hsp_id, ep)) == NULL)
224 return (-1);
225 (void) printf(gettext(
226 "%s: Concat/Stripe current parameters are:\n"),
227 stripenp->cname);
228 if (meta_print_stripe_options(hspnp, NULL, stdout, ep) != 0)
229 return (-1);
232 /* otherwise, change parameters */
233 else {
234 if (meta_stripe_set_params(sp, stripenp, &msp, ep) != 0)
235 return (-1);
237 /* update md.cf */
238 if (meta_update_md_cf(sp, ep) != 0)
239 return (-1);
242 /* return success */
243 return (0);
247 * do raid parameters
249 static int
250 raid_params(
251 mdsetname_t *sp,
252 mdname_t *raidnp,
253 int argc,
254 char *argv[],
255 md_error_t *ep
258 mr_params_t msp;
259 int modified = 0;
260 mdhspname_t *hspnp;
261 int c;
263 /* we must have a set */
264 assert(sp != NULL);
265 assert(sp->setno == MD_MIN2SET(meta_getminor(raidnp->dev)));
267 /* initialize */
268 (void) memset(&msp, '\0', sizeof (msp));
270 /* reset and parse args */
271 optind = 1;
272 opterr = 1;
273 while ((c = getopt(argc, argv, "s:h:")) != -1) {
274 switch (c) {
275 case 's':
276 break;
278 case 'h':
279 if (meta_is_none(optarg)) {
280 msp.hsp_id = MD_HSP_NONE;
281 } else if ((hspnp = metahspname(&sp, optarg,
282 ep)) == NULL) {
283 return (-1);
284 } else if (metachkhsp(sp, hspnp, ep) != 0) {
285 return (-1);
286 } else {
287 msp.hsp_id = hspnp->hsp;
289 msp.change_hsp_id = 1;
290 modified = 1;
291 break;
293 default:
294 usage(sp, 1);
295 /*NOTREACHED*/
296 break;
299 argc -= optind;
300 argv += optind;
301 if (argc != 1)
302 usage(sp, 1);
304 /* if just printing */
305 if (! modified) {
306 if (meta_raid_get_params(sp, raidnp, &msp, ep) != 0)
307 return (-1);
308 if (msp.hsp_id == MD_HSP_NONE)
309 hspnp = NULL;
310 else if ((hspnp = metahsphspname(&sp, msp.hsp_id, ep)) == NULL)
311 return (-1);
312 (void) printf(gettext(
313 "%s: RAID current parameters are:\n"),
314 raidnp->cname);
315 if (meta_print_raid_options(hspnp, NULL, stdout, ep) != 0)
316 return (-1);
319 /* otherwise, change parameters */
320 else {
321 if (meta_raid_set_params(sp, raidnp, &msp, ep) != 0)
322 return (-1);
324 /* update md.cf */
325 if (meta_update_md_cf(sp, ep) != 0)
326 return (-1);
329 /* return success */
330 return (0);
334 * parse args and doit
337 main(
338 int argc,
339 char **argv
342 char *sname = NULL;
343 mdsetname_t *sp = NULL;
344 mdname_t *np;
345 char *miscname;
346 int c;
347 md_error_t status = mdnullerror;
348 md_error_t *ep = &status;
349 int error;
350 bool_t called_thru_rpc = FALSE;
351 char *cp;
352 char *firstarg = NULL;
356 * Get the locale set up before calling any other routines
357 * with messages to ouput. Just in case we're not in a build
358 * environment, make sure that TEXT_DOMAIN gets set to
359 * something.
361 #if !defined(TEXT_DOMAIN)
362 #define TEXT_DOMAIN "SYS_TEST"
363 #endif
364 (void) setlocale(LC_ALL, "");
365 (void) textdomain(TEXT_DOMAIN);
367 if ((cp = strstr(argv[0], ".rpc_call")) == NULL) {
368 if (sdssc_bind_library() == SDSSC_OKAY)
369 if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY,
370 &error) == SDSSC_PROXY_DONE)
371 exit(error);
372 } else {
373 *cp = '\0'; /* cut off ".rpc_call" */
374 called_thru_rpc = TRUE;
378 /* initialize */
379 if (md_init(argc, argv, 0, 1, ep) != 0 ||
380 meta_check_root(ep) != 0) {
381 mde_perror(ep, "");
382 md_exit(sp, 1);
385 /* find set and metadevice first */
386 optind = 1;
387 opterr = 1;
388 while ((c = getopt(argc, argv, "s:h:p:r:w:o:?")) != -1) {
389 switch (c) {
390 case 's':
391 sname = optarg;
392 break;
393 case 'h':
394 firstarg = optarg;
395 break;
396 case '?':
397 if (optopt == '?')
398 usage(sp, 0);
399 break;
402 if ((argc - optind) <= 0)
403 usage(sp, 1);
405 if (sname != NULL) {
406 if ((sp = metasetname(sname, ep)) == NULL) {
407 mde_perror(ep, "");
408 md_exit(sp, 1);
411 if (firstarg == NULL)
412 firstarg = argv[optind];
413 if ((called_thru_rpc == FALSE) &&
414 meta_is_mn_name(&sp, firstarg, ep)) {
416 * If we are dealing with a MN set and we were not
417 * called thru an rpc call, we are just to send this
418 * command string to the master of the set and let it
419 * deal with it.
420 * Note that if sp is NULL, meta_is_mn_name() derives sp
421 * from firstarg which is the metadevice arg
422 * If this fails, the master must panic as the mddb may be
423 * inconsistent
425 int result;
426 result = meta_mn_send_command(sp, argc, argv, MD_DISP_STDERR |
427 MD_PANIC_WHEN_INCONSISTENT, NO_CONTEXT_STRING, ep);
428 /* No further action required */
429 md_exit(sp, result);
432 if ((np = metaname(&sp, argv[optind], META_DEVICE, ep)) == NULL) {
433 mde_perror(ep, "");
434 md_exit(sp, 1);
436 assert(sp != NULL);
437 /* grab set lock */
438 if (meta_lock(sp, TRUE, ep)) {
439 mde_perror(ep, "");
440 md_exit(sp, 1);
443 if (meta_check_ownership(sp, ep) != 0) {
444 mde_perror(ep, "");
445 md_exit(sp, 1);
447 if ((miscname = metagetmiscname(np, ep)) == NULL) {
448 mde_perror(ep, "");
449 md_exit(sp, 1);
452 /* dispatch based on device type */
453 if (strcmp(miscname, MD_STRIPE) == 0) {
454 if (stripe_params(sp, np, argc, argv, ep) != 0) {
455 mde_perror(ep, "");
456 md_exit(sp, 1);
458 } else if (strcmp(miscname, MD_MIRROR) == 0) {
459 if (mirror_params(sp, np, argc, argv, ep) != 0) {
460 mde_perror(ep, "");
461 md_exit(sp, 1);
463 } else if (strcmp(miscname, MD_RAID) == 0) {
464 if (raid_params(sp, np, argc, argv, ep) != 0) {
465 mde_perror(ep, "");
466 md_exit(sp, 1);
468 } else {
469 md_eprintf(gettext(
470 "%s: invalid metadevice type %s\n"),
471 np->cname, miscname);
472 md_exit(sp, 1);
475 /* return success */
476 md_exit(sp, 0);
477 /*NOTREACHED*/
478 return (0);