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