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 * clear metadevices 30 */ 31 32 #include <meta.h> 33 34 /* 35 * clear a metadevice. 36 */ 37 int 38 meta_reset( 39 mdsetname_t *sp, 40 mdname_t *np, 41 mdcmdopts_t options, 42 md_error_t *ep 43 ) 44 { 45 char *miscname; 46 md_i_reset_t mir; 47 48 /* should have a set */ 49 assert(sp != NULL); 50 assert(sp->setno == MD_MIN2SET(meta_getminor(np->dev))); 51 /* clear device */ 52 if ((miscname = metagetmiscname(np, ep)) == NULL) 53 return (-1); 54 if (meta_isopen(sp, np, ep, options) != 0) { 55 return (mdmderror(ep, MDE_IS_OPEN, meta_getminor(np->dev), 56 np->cname)); 57 } 58 (void) memset(&mir, '\0', sizeof (mir)); 59 MD_SETDRIVERNAME(&mir, miscname, sp->setno); 60 mir.mnum = meta_getminor(np->dev); 61 mir.force = (options & MDCMD_FORCE) ? 1 : 0; 62 if (metaioctl(MD_IOCRESET, &mir, &mir.mde, np->cname) != 0) 63 return (mdstealerror(ep, &mir.mde)); 64 65 /* 66 * Wait for the /dev to be cleaned up. Ignore the return 67 * value since there's not much we can do. 68 */ 69 (void) meta_update_devtree(meta_getminor(np->dev)); 70 71 /* return success */ 72 return (0); 73 } 74 75 /* 76 * reset all the metadevice and hotspares 77 */ 78 int 79 meta_reset_all( 80 mdsetname_t *sp, 81 mdcmdopts_t options, 82 md_error_t *ep 83 ) 84 { 85 options |= MDCMD_RECURSE; 86 87 /* 88 * since soft partitions can appear at the top and bottom 89 * of the stack, we call meta_sp_reset twice to handle all 90 * cases. 91 */ 92 if (meta_trans_reset(sp, NULL, options, ep) != 0) 93 return (-1); 94 if (meta_sp_reset(sp, NULL, options, ep) != 0) 95 return (-1); 96 if (meta_raid_reset(sp, NULL, options, ep) != 0) 97 return (-1); 98 if (meta_mirror_reset(sp, NULL, options, ep) != 0) 99 return (-1); 100 if (meta_stripe_reset(sp, NULL, options, ep) != 0) 101 return (-1); 102 if (meta_hsp_reset(sp, NULL, options, ep) != 0) 103 return (-1); 104 if (meta_sp_reset(sp, NULL, options, ep) != 0) 105 return (-1); 106 107 return (0); 108 } 109 110 /* 111 * reset named device 112 */ 113 int 114 meta_reset_by_name( 115 mdsetname_t *sp, 116 mdname_t *np, 117 mdcmdopts_t options, 118 md_error_t *ep 119 ) 120 { 121 char *miscname; 122 int rval = 0; 123 124 /* should have a set */ 125 assert(sp != NULL); 126 assert(sp->setno == MD_MIN2SET(meta_getminor(np->dev))); 127 128 /* get type */ 129 if (metachkmeta(np, ep) != 0) 130 return (-1); 131 if ((miscname = metagetmiscname(np, ep)) == NULL) 132 return (-1); 133 /* dispatch */ 134 if (strcmp(miscname, MD_STRIPE) == 0) { 135 rval = meta_stripe_reset(sp, np, options, ep); 136 } else if (strcmp(miscname, MD_MIRROR) == 0) { 137 rval = meta_mirror_reset(sp, np, options, ep); 138 } else if (strcmp(miscname, MD_TRANS) == 0) { 139 rval = meta_trans_reset(sp, np, options, ep); 140 } else if (strcmp(miscname, MD_RAID) == 0) { 141 rval = meta_raid_reset(sp, np, options, ep); 142 } else if (strcmp(miscname, MD_SP) == 0) { 143 rval = meta_sp_reset(sp, np, options, ep); 144 } else { 145 rval = mdmderror(ep, MDE_UNKNOWN_TYPE, meta_getminor(np->dev), 146 np->cname); 147 } 148 149 /* cleanup */ 150 return (rval); 151 } 152