xref: /titanic_41/usr/src/cmd/lvm/util/metaonline.c (revision 989f28072d20c73ae0955d6a1e3e2fc74831cb39)
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 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * online sub-mirrors
30  */
31 
32 #include <meta.h>
33 #include <sdssc.h>
34 
35 /*
36  * print usage message
37  */
38 static void
39 usage(
40 	mdsetname_t	*sp,
41 	int		eval
42 )
43 {
44 	(void) fprintf(stderr, gettext("\
45 usage:	%s [-s setname] mirror submirror\n"),
46 	    myname);
47 	md_exit(sp, eval);
48 }
49 
50 /*
51  * Metaonline: to online a metadevice
52  */
53 int
54 main(
55 	int		argc,
56 	char		*argv[]
57 )
58 {
59 	char		*sname = NULL;
60 	mdsetname_t	*sp = NULL;
61 	mdcmdopts_t	options = (MDCMD_PRINT);
62 	mdname_t	*mirnp;
63 	mdname_t	*submirnp;
64 	int		c;
65 	md_error_t	status = mdnullerror;
66 	md_error_t	*ep = &status;
67 	int		error;
68 	bool_t		called_thru_rpc = FALSE;
69 	char		*cp;
70 	int		origargc = argc;
71 	char		**origargv = argv;
72 
73 	/*
74 	 * Get the locale set up before calling any other routines
75 	 * with messages to ouput.  Just in case we're not in a build
76 	 * environment, make sure that TEXT_DOMAIN gets set to
77 	 * something.
78 	 */
79 #if !defined(TEXT_DOMAIN)
80 #define	TEXT_DOMAIN "SYS_TEST"
81 #endif
82 	(void) setlocale(LC_ALL, "");
83 	(void) textdomain(TEXT_DOMAIN);
84 
85 	if ((cp = strstr(argv[0], ".rpc_call")) == NULL) {
86 		if (sdssc_bind_library() == SDSSC_OKAY)
87 			if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY,
88 						&error) == SDSSC_PROXY_DONE)
89 				exit(error);
90 	} else {
91 		*cp = '\0'; /* cut off ".rpc_call" */
92 		called_thru_rpc = TRUE;
93 	}
94 
95 	/* initialize */
96 	if (md_init(argc, argv, 0, 1, ep) != 0 ||
97 			meta_check_root(ep) != 0) {
98 		mde_perror(ep, "");
99 		md_exit(sp, 1);
100 	}
101 
102 	/* parse args */
103 	optind = 1;
104 	opterr = 1;
105 	while ((c = getopt(argc, argv, "hs:?")) != -1) {
106 		switch (c) {
107 		case 'h':
108 			usage(sp, 0);
109 			break;
110 
111 		case 's':
112 			sname = optarg;
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 	if (argc != 2)
127 		usage(sp, 1);
128 
129 	if (sname != NULL) {
130 		if ((sp = metasetname(sname, ep)) == NULL) {
131 			mde_perror(ep, "");
132 			md_exit(sp, 1);
133 		}
134 	}
135 
136 	/* get names */
137 	if (((mirnp = metaname(&sp, argv[0], META_DEVICE, ep)) == NULL) ||
138 	    ((submirnp = metaname(&sp, argv[1], META_DEVICE, ep)) == NULL)) {
139 		mde_perror(ep, "");
140 		md_exit(sp, 1);
141 	}
142 
143 	assert(sp != NULL);
144 
145 	if ((called_thru_rpc == FALSE) &&
146 	    meta_is_mn_name(&sp, argv[0], ep)) {
147 		/*
148 		 * If we are dealing with a MN set and we were not
149 		 * called thru an rpc call, we are just to send this
150 		 * command string to the master of the set and let it
151 		 * deal with it.
152 		 * Note that if sp is NULL, meta_is_mn_name() derives sp
153 		 * from argv[0] which is the metadevice arg
154 		 * If this fails, the master must panic as the mddb may be
155 		 * inconsistent.
156 		 */
157 		int  result;
158 		result = meta_mn_send_command(sp, origargc, origargv,
159 		    MD_DISP_STDERR | MD_PANIC_WHEN_INCONSISTENT,
160 		    NO_CONTEXT_STRING, ep);
161 		/*
162 		 * Unlike non-MN sets, the metaonline command does not actually
163 		 * start a resync, it simply updates the state on all of the
164 		 * nodes. Therefore, to start a resync we send a resync starting
165 		 * message for the metadevice
166 		 */
167 		if (result == 0) {
168 			if ((result = meta_mn_send_resync_starting(mirnp, ep))
169 			    != 0)
170 				mde_perror(ep, "Unable to start resync");
171 		}
172 		md_exit(sp, result);
173 	}
174 
175 	/* grab set lock */
176 	if (meta_lock(sp, TRUE, ep)) {
177 		mde_perror(ep, "");
178 		md_exit(sp, 1);
179 	}
180 
181 	/* check for ownership */
182 	if (meta_check_ownership(sp, ep) != 0) {
183 		mde_perror(ep, "");
184 		md_exit(sp, 1);
185 	}
186 
187 	/* online submirror */
188 	if (meta_mirror_online(sp, mirnp, submirnp, options, ep) != 0) {
189 		mde_perror(ep, "");
190 		md_exit(sp, 1);
191 	}
192 
193 	/* return success */
194 	md_exit(sp, 0);
195 	/*NOTREACHED*/
196 	return (0);
197 }
198