7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / util / metasync.c
blob4d36d35cf604f657bef701510602cc36aec80d7c
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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * sync metadevices
32 #include <meta.h>
34 #include <sys/lvm/md_mirror.h>
36 #include <ctype.h>
38 #include <sdssc.h>
41 * print usage message
43 static void
44 usage(
45 mdsetname_t *sp,
46 int eval
49 (void) fprintf(stderr, gettext("\
50 usage: %s [-s setname] -r [buffer_size]\n\
51 %s [-s setname] [buffer_size] metadevices...\n\
52 %s [-s setname] -c metadevices...\n"),
53 myname, myname, myname);
54 md_exit(sp, eval);
58 * crack command line arguments.
60 int
61 main(
62 int argc,
63 char *argv[]
66 char *sname = NULL;
67 mdsetname_t *sp = NULL;
68 int rflag = 0;
69 int pflag = 0;
70 daddr_t size = 0;
71 int c;
72 md_error_t status = mdnullerror;
73 md_error_t *ep = &status;
74 int rval = 0;
75 int error;
76 md_resync_cmd_t resync_cmd = MD_RESYNC_START;
77 bool_t called_thru_rpc = FALSE;
78 char *cp;
79 int mn_set = FALSE;
80 int cflag = 0;
83 * Get the locale set up before calling any other routines
84 * with messages to ouput. Just in case we're not in a build
85 * environment, make sure that TEXT_DOMAIN gets set to
86 * something.
88 #if !defined(TEXT_DOMAIN)
89 #define TEXT_DOMAIN "SYS_TEST"
90 #endif
91 (void) setlocale(LC_ALL, "");
92 (void) textdomain(TEXT_DOMAIN);
94 if ((cp = strstr(argv[0], ".rpc_call")) == NULL) {
95 if (sdssc_bind_library() == SDSSC_OKAY)
96 if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY,
97 &error) == SDSSC_PROXY_DONE)
98 exit(error);
99 } else {
100 *cp = '\0'; /* cut off ".rpc_call" */
101 called_thru_rpc = TRUE;
105 /* initialize */
106 if (md_init(argc, argv, 0, 1, ep) != 0 ||
107 meta_check_root(ep) != 0) {
108 mde_perror(ep, "");
109 md_exit(sp, 1);
112 /* parse args */
113 optind = 1;
114 opterr = 1;
115 while ((c = getopt(argc, argv, "phs:rc?")) != -1) {
116 switch (c) {
117 case 'h':
118 usage(sp, 0);
119 break;
121 case 's':
122 sname = optarg;
123 break;
125 case 'r':
126 ++rflag;
127 break;
129 case 'p':
130 ++pflag;
131 break;
133 case 'c':
134 ++cflag;
135 resync_cmd = MD_RESYNC_KILL;
136 break;
138 case '?':
139 if (optopt == '?')
140 usage(sp, 0);
141 /*FALLTHROUGH*/
142 default:
143 usage(sp, 1);
144 break;
147 if ((pflag + rflag) > 1) {
148 usage(sp, 1);
149 mde_perror(ep, "");
150 md_exit(sp, 1);
152 argc -= optind;
153 argv += optind;
155 if (sname != NULL) {
156 if ((sp = metasetname(sname, ep)) == NULL) {
157 mde_perror(ep, "");
158 md_exit(sp, 1);
163 * look for buffer size. If one is not specified we pass '0' to
164 * the meta_resync_all() call. This uses whatever size has been
165 * configured via md_mirror:md_resync_bufsz
166 * The default value (if not overridden in /etc/system) is
167 * MD_DEF_RESYNC_BUF_SIZE
169 if ((argc > 0) && (isdigit(argv[0][0]))) {
170 if ((size = atoi(argv[0])) < 0) {
171 md_eprintf(gettext(
172 "illegal buffer size %s\n"),
173 argv[0]);
174 md_exit(sp, 1);
176 --argc;
177 ++argv;
180 /* sync all devices in set */
181 if (rflag) {
182 /* get set */
183 if (argc != 0)
184 usage(sp, 1);
185 if ((sp == NULL) &&
186 ((sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) &&
187 (metaget_setdesc(sp, ep) == NULL)) {
188 mde_perror(ep, "");
189 md_exit(sp, 1);
192 assert(sp != NULL);
194 * For a MN set "metasync -r" can only be called by the
195 * initiator. We must not take the set lock for a MN set as
196 * it will only generate individual metasync commands which
197 * will individually take the lock when executing the
198 * individual metasync commands.
199 * Therefore only take the set lock for non MN sets.
201 if (meta_is_mn_set(sp, ep) == 0) {
202 /* grab set lock */
203 if (meta_lock(sp, TRUE, ep)) {
204 mde_perror(ep, "");
205 md_exit(sp, 1);
208 /* check for ownership */
209 if (meta_check_ownership(sp, ep) != 0) {
210 mde_perror(ep, "");
211 md_exit(sp, 1);
214 /* resync all metadevices in set */
215 if (meta_resync_all(sp, size, ep) != 0) {
216 mde_perror(ep, "");
217 md_exit(sp, 1);
219 md_exit(sp, 0);
222 /* sync specified metadevices */
223 if (argc <= 0)
224 usage(sp, 1);
227 * Note that if sp is NULL, meta_is_mn_name() derives sp
228 * from argv[0] which is the metadevice arg
230 if (meta_is_mn_name(&sp, argv[0], ep))
231 mn_set = TRUE;
233 for (; (argc > 0); --argc, ++argv) {
234 mdname_t *np;
235 int result;
237 /* get device */
238 if ((np = metaname(&sp, argv[0], META_DEVICE, ep)) == NULL) {
239 mde_perror(ep, "");
240 rval = -1;
241 continue;
243 assert(sp != NULL);
246 * If we are not called through an rpc call and the
247 * set associated with the command is an MN set, send
248 * a setsync message to the master of the set and let it
249 * deal with it.
251 if (!called_thru_rpc && mn_set) {
252 if ((result = meta_mn_send_setsync(sp, np, size,
253 ep)) != 0) {
254 mde_perror(ep, "Unable to start resync");
255 md_exit(sp, result);
257 continue;
260 /* grab set lock */
261 if (meta_lock(sp, TRUE, ep)) {
262 mde_perror(ep, "");
263 md_exit(sp, 1);
266 /* check for ownership */
267 if (meta_check_ownership(sp, ep) != 0) {
268 mde_perror(ep, "");
269 md_exit(sp, 1); /* no point in continuing */
272 /* resync or regen (raid only) metadevice */
273 if (pflag) {
274 /* regen */
275 if (meta_raid_regen_byname(sp, np, size, ep) != 0) {
276 mde_perror(ep, "");
277 rval = -1;
278 continue;
280 } else {
281 if (meta_resync_byname(sp, np, size, ep, resync_cmd)
282 != 0) {
283 mde_perror(ep, "");
284 rval = -1;
285 continue;
290 /* return success */
291 md_exit(sp, rval);
292 /*NOTREACHED*/
293 return (rval);