metarecover.c revision 11053:f33a1c7f3155
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*
27 * Recover metadevice configurations that have been lost by scanning
28 * media, intelligent guessing, or other means.
29 */
30
31#include <meta.h>
32#include <sdssc.h>
33
34/*
35 * print usage message
36 */
37static void
38usage(
39	mdsetname_t	*sp,
40	int		eval
41)
42{
43	(void) fprintf(stderr, gettext(
44	    "usage: %s [-s setname] [-v] raw-device -p\n"), myname);
45	(void) fprintf(stderr, gettext(
46	    "       %s [-s setname] [-v] [-n] raw-device -p -d\n"), myname);
47	(void) fprintf(stderr, gettext(
48	    "       %s [-s setname] [-v] [-n] raw-device -p -m\n"), myname);
49
50	md_exit(sp, eval);
51}
52
53int
54main(
55	int	argc,
56	char	*argv[]
57)
58{
59	char		*sname = MD_LOCAL_NAME;
60	mdcmdopts_t	options = (MDCMD_DOIT | MDCMD_PRINT);
61
62	mdsetname_t	*sp = NULL;
63	md_error_t	status = mdnullerror;
64	md_error_t	*ep = &status;
65	mdname_t	*namep;
66	char		*devname;
67	int		error;
68	int		c;
69
70	/*
71	 * Get the locale set up before calling any other routines
72	 * with messages to ouput.  Just in case we're not in a build
73	 * environment, make sure that TEXT_DOMAIN gets set to
74	 * something.
75	 */
76#if !defined(TEXT_DOMAIN)
77#define	TEXT_DOMAIN "SYS_TEST"
78#endif
79	(void) setlocale(LC_ALL, "");
80	(void) textdomain(TEXT_DOMAIN);
81
82	if (sdssc_bind_library() == SDSSC_ERROR) {
83		(void) printf(gettext(
84		    "%s: Interface error with libsds_sc.so\n"), argv[0]);
85		exit(1);
86	}
87
88	if (md_init(argc, argv, 0, 1, ep) != 0 ||
89	    meta_check_root(ep) != 0) {
90		mde_perror(ep, "");
91		md_exit((mdsetname_t *)NULL, 1);
92	}
93
94	/* parse arguments */
95	optind = 1;
96	opterr = 1;
97	while ((c = getopt(argc, argv, "s:hnv?")) != -1) {
98		switch (c) {
99		case 's':
100			sname = optarg;
101			break;
102
103		case 'h':
104			usage(sp, 0);
105			break;
106
107		case 'v':
108			options |= MDCMD_VERBOSE;
109			break;
110
111		case 'n':
112			options &= ~MDCMD_DOIT;
113			break;
114
115		case '?':
116			if (optopt == '?')
117				usage(sp, 0);
118			/*FALLTHROUGH*/
119		default:
120			usage(sp, 1);
121			break;
122		}
123	}
124	argc -= optind;
125	argv += optind;
126
127	/* sname is MD_LOCAL_NAME if not specified on the command line */
128	if ((sp = metasetname(sname, ep)) == NULL) {
129		mde_perror(ep, "");
130		md_exit(sp, 1);
131	}
132
133	if ((argc == 0) || (argv[0] == NULL)) {
134		usage(sp, 1);
135	}
136
137	/* get raw device name */
138	devname = Strdup(argv[0]);
139	argv++;
140	argc--;
141
142	if ((namep = metaname(&sp, devname, UNKNOWN, ep)) == NULL) {
143		mde_perror(ep, "");
144		md_exit(sp, 1);
145	}
146
147	/* check for a valid component */
148	if ((metagetsize(namep, ep) == MD_DISKADDR_ERROR)) {
149		mde_perror(ep, "");
150		md_exit(sp, 1);
151	}
152
153	/* check for ownership */
154	assert(sp != NULL);
155	if (meta_check_ownership(sp, ep) != 0) {
156		mde_perror(ep, "");
157		md_exit(sp, 1);
158	}
159
160	/*
161	 * If the component is not a metadevice and we have a named set
162	 * make sure that the component is part of the named set.
163	 */
164	if (strcmp(sp->setname, MD_LOCAL_NAME) != 0) {
165		if (!metaismeta(namep)) {
166			if (! meta_is_drive_in_thisset(sp, namep->drivenamep,
167			    FALSE, ep)) {
168				(void) mddeverror(ep, MDE_NOT_IN_SET,
169				    namep->dev, namep->cname);
170				mde_perror(ep, "");
171				md_exit(sp, 1);
172			}
173		}
174	}
175
176	/* parse command line -- currently only soft partitions are supported */
177	if ((argc > 0) && (*argv != NULL) && strncmp(*argv, "-p", 2) == 0) {
178		error = meta_recover_sp(sp, namep, --argc, ++argv, options, ep);
179	} else {
180		usage(sp, 1);
181	}
182
183	if (error < 0) {
184		mde_perror(ep, "");
185		md_exit(sp, 1);
186	} else {
187		if (meta_update_md_cf(sp, ep) != 0) {
188			mde_perror(ep, "");
189			md_exit(sp, 1);
190		}
191	}
192
193	md_exit(sp, 0);
194	/*NOTREACHED*/
195	return (0);
196}
197