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 * online sub-mirrors 31 */ 32 33 #include <meta.h> 34 #include <sdssc.h> 35 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] mirror submirror\n"), 47 myname); 48 md_exit(sp, eval); 49 } 50 51 /* 52 * Metaonline: to online 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:?")) != -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 '?': 117 if (optopt == '?') 118 usage(sp, 0); 119 /*FALLTHROUGH*/ 120 default: 121 usage(sp, 1); 122 break; 123 } 124 } 125 argc -= optind; 126 argv += optind; 127 if (argc != 2) 128 usage(sp, 1); 129 130 if (sname != NULL) { 131 if ((sp = metasetname(sname, ep)) == NULL) { 132 mde_perror(ep, ""); 133 md_exit(sp, 1); 134 } 135 } 136 137 /* get names */ 138 if (((mirnp = metaname(&sp, argv[0], ep)) == NULL) || 139 ((submirnp = metaname(&sp, argv[1], ep)) == NULL)) { 140 mde_perror(ep, ""); 141 md_exit(sp, 1); 142 } 143 144 assert(sp != NULL); 145 146 if ((called_thru_rpc == FALSE) && 147 meta_is_mn_name(&sp, argv[0], ep)) { 148 /* 149 * If we are dealing with a MN set and we were not 150 * called thru an rpc call, we are just to send this 151 * command string to the master of the set and let it 152 * deal with it. 153 * Note that if sp is NULL, meta_is_mn_name() derives sp 154 * from argv[0] which is the metadevice arg 155 * If this fails, the master must panic as the mddb may be 156 * inconsistent. 157 */ 158 int result; 159 result = meta_mn_send_command(sp, origargc, origargv, 160 MD_DISP_STDERR | MD_PANIC_WHEN_INCONSISTENT, 161 NO_CONTEXT_STRING, ep); 162 /* 163 * Unlike non-MN sets, the metaonline command does not actually 164 * start a resync, it simply updates the state on all of the 165 * nodes. Therefore, to start a resync we send a resync starting 166 * message for the metadevice 167 */ 168 if (result == 0) { 169 if ((result = meta_mn_send_resync_starting(mirnp, ep)) 170 != 0) 171 mde_perror(ep, "Unable to start resync"); 172 } 173 md_exit(sp, result); 174 } 175 176 /* grab set lock */ 177 if (meta_lock(sp, TRUE, ep)) { 178 mde_perror(ep, ""); 179 md_exit(sp, 1); 180 } 181 182 /* check for ownership */ 183 if (meta_check_ownership(sp, ep) != 0) { 184 mde_perror(ep, ""); 185 md_exit(sp, 1); 186 } 187 188 /* online submirror */ 189 if (meta_mirror_online(sp, mirnp, submirnp, options, ep) != 0) { 190 mde_perror(ep, ""); 191 md_exit(sp, 1); 192 } 193 194 /* return success */ 195 md_exit(sp, 0); 196 /*NOTREACHED*/ 197 return (0); 198 } 199