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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * offline sub-mirror 31 */ 32 33 #include <meta.h> 34 35 #include <sdssc.h> 36 /* 37 * print usage message 38 */ 39 static void 40 usage( 41 mdsetname_t *sp, 42 int eval 43 ) 44 { 45 (void) fprintf(stderr, gettext("\ 46 usage: %s [-s setname] [-f] mirror submirror\n"), 47 myname); 48 md_exit(sp, eval); 49 } 50 51 /* 52 * Metaoffline: to offline a metadevice 53 */ 54 int 55 main( 56 int argc, 57 char *argv[] 58 ) 59 { 60 char *sname = NULL; 61 mdsetname_t *sp = NULL; 62 mdcmdopts_t options = (MDCMD_PRINT); 63 mdname_t *mirnp; 64 mdname_t *submirnp; 65 int c; 66 md_error_t status = mdnullerror; 67 md_error_t *ep = &status; 68 int error; 69 bool_t called_thru_rpc = FALSE; 70 char *cp; 71 int origargc = argc; 72 char **origargv = argv; 73 74 /* 75 * Get the locale set up before calling any other routines 76 * with messages to ouput. Just in case we're not in a build 77 * environment, make sure that TEXT_DOMAIN gets set to 78 * something. 79 */ 80 #if !defined(TEXT_DOMAIN) 81 #define TEXT_DOMAIN "SYS_TEST" 82 #endif 83 (void) setlocale(LC_ALL, ""); 84 (void) textdomain(TEXT_DOMAIN); 85 86 if ((cp = strstr(argv[0], ".rpc_call")) == NULL) { 87 if (sdssc_bind_library() == SDSSC_OKAY) 88 if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY, 89 &error) == SDSSC_PROXY_DONE) 90 exit(error); 91 } else { 92 *cp = '\0'; /* cut off ".rpc_call" */ 93 called_thru_rpc = TRUE; 94 } 95 96 /* initialize */ 97 if (md_init(argc, argv, 0, 1, ep) != 0 || 98 meta_check_root(ep) != 0) { 99 mde_perror(ep, ""); 100 md_exit(sp, 1); 101 } 102 103 /* parse args */ 104 optind = 1; 105 opterr = 1; 106 while ((c = getopt(argc, argv, "hs:f?")) != -1) { 107 switch (c) { 108 case 'h': 109 usage(sp, 0); 110 break; 111 112 case 's': 113 sname = optarg; 114 break; 115 116 case 'f': 117 options |= MDCMD_FORCE; 118 break; 119 120 case '?': 121 if (optopt == '?') 122 usage(sp, 0); 123 /*FALLTHROUGH*/ 124 default: 125 usage(sp, 1); 126 break; 127 } 128 } 129 argc -= optind; 130 argv += optind; 131 if (argc != 2) 132 usage(sp, 1); 133 134 if (sname != NULL) { 135 if ((sp = metasetname(sname, ep)) == NULL) { 136 mde_perror(ep, ""); 137 md_exit(sp, 1); 138 } 139 } 140 141 /* get names */ 142 if (((mirnp = metaname(&sp, argv[0], ep)) == NULL) || 143 ((submirnp = metaname(&sp, argv[1], ep)) == NULL)) { 144 mde_perror(ep, ""); 145 md_exit(sp, 1); 146 } 147 148 assert(sp != NULL); 149 150 if ((called_thru_rpc == FALSE) && 151 meta_is_mn_name(&sp, argv[0], ep)) { 152 /* 153 * If we are dealing with a MN set and we were not 154 * called thru an rpc call, we are just to send this 155 * command string to the master of the set and let it 156 * deal with it. 157 * Note that if sp is NULL, meta_is_mn_name() derives sp 158 * from argv[0] which is the metadevice arg 159 * If this fails, the master must panic as the mddb may be 160 * inconsistent. 161 */ 162 int result; 163 result = meta_mn_send_command(sp, origargc, origargv, 164 MD_DISP_STDERR | MD_PANIC_WHEN_INCONSISTENT, 165 NO_CONTEXT_STRING, ep); 166 md_exit(sp, result); 167 } 168 169 /* grab set lock */ 170 if (meta_lock(sp, TRUE, ep)) { 171 mde_perror(ep, ""); 172 md_exit(sp, 1); 173 } 174 175 /* check for ownership */ 176 if (meta_check_ownership(sp, ep) != 0) { 177 mde_perror(ep, ""); 178 md_exit(sp, 1); 179 } 180 181 /* offline submirror */ 182 if (meta_mirror_offline(sp, mirnp, submirnp, options, ep) != 0) { 183 mde_perror(ep, ""); 184 md_exit(sp, 1); 185 } 186 187 /* return success */ 188 md_exit(sp, 0); 189 /*NOTREACHED*/ 190 return (0); 191 } 192