xref: /titanic_41/usr/src/cmd/lvm/util/metaoffline.c (revision e0724c534a46ca4754330bc022bf1e2a68f5bb93)
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  * offline sub-mirror
30  */
31 
32 #include <meta.h>
33 
34 #include <sdssc.h>
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] [-f] mirror submirror\n"),
46 	    myname);
47 	md_exit(sp, eval);
48 }
49 
50 /*
51  * Metaoffline: to offline 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:f?")) != -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 'f':
116 			options |= MDCMD_FORCE;
117 			break;
118 
119 		case '?':
120 			if (optopt == '?')
121 				usage(sp, 0);
122 			/*FALLTHROUGH*/
123 		default:
124 			usage(sp, 1);
125 			break;
126 		}
127 	}
128 	argc -= optind;
129 	argv += optind;
130 	if (argc != 2)
131 		usage(sp, 1);
132 
133 	if (sname != NULL) {
134 		if ((sp = metasetname(sname, ep)) == NULL) {
135 			mde_perror(ep, "");
136 			md_exit(sp, 1);
137 		}
138 	}
139 
140 	/* get names */
141 	if (((mirnp = metaname(&sp, argv[0], META_DEVICE, ep)) == NULL) ||
142 	    ((submirnp = metaname(&sp, argv[1], META_DEVICE, ep)) == NULL)) {
143 		mde_perror(ep, "");
144 		md_exit(sp, 1);
145 	}
146 
147 	assert(sp != NULL);
148 
149 	if ((called_thru_rpc == FALSE) &&
150 	    meta_is_mn_name(&sp, argv[0], ep)) {
151 		/*
152 		 * If we are dealing with a MN set and we were not
153 		 * called thru an rpc call, we are just to send this
154 		 * command string to the master of the set and let it
155 		 * deal with it.
156 		 * Note that if sp is NULL, meta_is_mn_name() derives sp
157 		 * from argv[0] which is the metadevice arg
158 		 * If this fails, the master must panic as the mddb may be
159 		 * inconsistent.
160 		 */
161 		int  result;
162 		result = meta_mn_send_command(sp, origargc, origargv,
163 		    MD_DISP_STDERR | MD_PANIC_WHEN_INCONSISTENT,
164 		    NO_CONTEXT_STRING, ep);
165 		md_exit(sp, result);
166 	}
167 
168 	/* grab set lock */
169 	if (meta_lock(sp, TRUE, ep)) {
170 		mde_perror(ep, "");
171 		md_exit(sp, 1);
172 	}
173 
174 	/* check for ownership */
175 	if (meta_check_ownership(sp, ep) != 0) {
176 		mde_perror(ep, "");
177 		md_exit(sp, 1);
178 	}
179 
180 	/* offline submirror */
181 	if (meta_mirror_offline(sp, mirnp, submirnp, options, ep) != 0) {
182 		mde_perror(ep, "");
183 		md_exit(sp, 1);
184 	}
185 
186 	/* return success */
187 	md_exit(sp, 0);
188 	/*NOTREACHED*/
189 	return (0);
190 }
191