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