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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Recover metadevice configurations that have been lost by scanning 28 * media, intelligent guessing, or other means. 29 */ 30 31 #include <meta.h> 32 #include <sdssc.h> 33 34 /* 35 * print usage message 36 */ 37 static void 38 usage( 39 mdsetname_t *sp, 40 int eval 41 ) 42 { 43 (void) fprintf(stderr, gettext( 44 "usage: %s [-s setname] [-v] raw-device -p\n"), myname); 45 (void) fprintf(stderr, gettext( 46 " %s [-s setname] [-v] [-n] raw-device -p -d\n"), myname); 47 (void) fprintf(stderr, gettext( 48 " %s [-s setname] [-v] [-n] raw-device -p -m\n"), myname); 49 50 md_exit(sp, eval); 51 } 52 53 int 54 main( 55 int argc, 56 char *argv[] 57 ) 58 { 59 char *sname = MD_LOCAL_NAME; 60 mdcmdopts_t options = (MDCMD_DOIT | MDCMD_PRINT); 61 62 mdsetname_t *sp = NULL; 63 md_error_t status = mdnullerror; 64 md_error_t *ep = &status; 65 mdname_t *namep; 66 char *devname; 67 int error; 68 int c; 69 70 /* 71 * Get the locale set up before calling any other routines 72 * with messages to ouput. Just in case we're not in a build 73 * environment, make sure that TEXT_DOMAIN gets set to 74 * something. 75 */ 76 #if !defined(TEXT_DOMAIN) 77 #define TEXT_DOMAIN "SYS_TEST" 78 #endif 79 (void) setlocale(LC_ALL, ""); 80 (void) textdomain(TEXT_DOMAIN); 81 82 if (sdssc_bind_library() == SDSSC_ERROR) { 83 (void) printf(gettext( 84 "%s: Interface error with libsds_sc.so\n"), argv[0]); 85 exit(1); 86 } 87 88 if (md_init(argc, argv, 0, 1, ep) != 0 || 89 meta_check_root(ep) != 0) { 90 mde_perror(ep, ""); 91 md_exit((mdsetname_t *)NULL, 1); 92 } 93 94 /* parse arguments */ 95 optind = 1; 96 opterr = 1; 97 while ((c = getopt(argc, argv, "s:hnv?")) != -1) { 98 switch (c) { 99 case 's': 100 sname = optarg; 101 break; 102 103 case 'h': 104 usage(sp, 0); 105 break; 106 107 case 'v': 108 options |= MDCMD_VERBOSE; 109 break; 110 111 case 'n': 112 options &= ~MDCMD_DOIT; 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 127 /* sname is MD_LOCAL_NAME if not specified on the command line */ 128 if ((sp = metasetname(sname, ep)) == NULL) { 129 mde_perror(ep, ""); 130 md_exit(sp, 1); 131 } 132 133 if ((argc == 0) || (argv[0] == NULL)) { 134 usage(sp, 1); 135 } 136 137 /* get raw device name */ 138 devname = Strdup(argv[0]); 139 argv++; 140 argc--; 141 142 if ((namep = metaname(&sp, devname, UNKNOWN, ep)) == NULL) { 143 mde_perror(ep, ""); 144 md_exit(sp, 1); 145 } 146 147 /* check for a valid component */ 148 if ((metagetsize(namep, ep) == MD_DISKADDR_ERROR)) { 149 mde_perror(ep, ""); 150 md_exit(sp, 1); 151 } 152 153 /* check for ownership */ 154 assert(sp != NULL); 155 if (meta_check_ownership(sp, ep) != 0) { 156 mde_perror(ep, ""); 157 md_exit(sp, 1); 158 } 159 160 /* 161 * If the component is not a metadevice and we have a named set 162 * make sure that the component is part of the named set. 163 */ 164 if (strcmp(sp->setname, MD_LOCAL_NAME) != 0) { 165 if (!metaismeta(namep)) { 166 if (! meta_is_drive_in_thisset(sp, namep->drivenamep, 167 FALSE, ep)) { 168 (void) mddeverror(ep, MDE_NOT_IN_SET, 169 namep->dev, namep->cname); 170 mde_perror(ep, ""); 171 md_exit(sp, 1); 172 } 173 } 174 } 175 176 /* parse command line -- currently only soft partitions are supported */ 177 if ((argc > 0) && (*argv != NULL) && strncmp(*argv, "-p", 2) == 0) { 178 error = meta_recover_sp(sp, namep, --argc, ++argv, options, ep); 179 } else { 180 usage(sp, 1); 181 } 182 183 if (error < 0) { 184 mde_perror(ep, ""); 185 md_exit(sp, 1); 186 } else { 187 if (meta_update_md_cf(sp, ep) != 0) { 188 mde_perror(ep, ""); 189 md_exit(sp, 1); 190 } 191 } 192 193 md_exit(sp, 0); 194 /*NOTREACHED*/ 195 return (0); 196 } 197