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 */
37 static void
usage(mdsetname_t * sp,int eval)38 usage(
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
53 int
main(int argc,char * argv[])54 main(
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