geom_stripe.c revision 131649
1234353Sdim/*- 2195340Sed * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3353358Sdim * All rights reserved. 4353358Sdim * 5353358Sdim * Redistribution and use in source and binary forms, with or without 6195340Sed * modification, are permitted provided that the following conditions 7195340Sed * are met: 8195340Sed * 1. Redistributions of source code must retain the above copyright 9195340Sed * notice, this list of conditions and the following disclaimer. 10195340Sed * 2. Redistributions in binary form must reproduce the above copyright 11195340Sed * notice, this list of conditions and the following disclaimer in the 12195340Sed * documentation and/or other materials provided with the distribution. 13321369Sdim * 14280031Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15195340Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16195340Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17249423Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18234353Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19195340Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20195340Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21195340Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22198892Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23288943Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24195340Sed * SUCH DAMAGE. 25321369Sdim */ 26321369Sdim 27234353Sdim#include <sys/cdefs.h> 28288943Sdim__FBSDID("$FreeBSD: head/sbin/geom/class/stripe/geom_stripe.c 131649 2004-07-05 21:16:37Z pjd $"); 29288943Sdim 30288943Sdim#include <sys/param.h> 31288943Sdim#include <errno.h> 32234353Sdim#include <stdio.h> 33234353Sdim#include <stdlib.h> 34198090Srdivacky#include <stdint.h> 35198090Srdivacky#include <string.h> 36198090Srdivacky#include <strings.h> 37195340Sed#include <assert.h> 38210299Sed#include <libgeom.h> 39309124Sdim#include <geom/stripe/g_stripe.h> 40360784Sdim 41360784Sdim#include "core/geom.h" 42280031Sdim#include "misc/subr.h" 43280031Sdim 44288943Sdim 45280031Sdimuint32_t lib_version = G_LIB_VERSION; 46210299Seduint32_t version = G_STRIPE_VERSION; 47210299Sed 48280031Sdimstatic intmax_t stripesize = 65536; 49280031Sdim 50280031Sdimstatic void stripe_main(struct gctl_req *req, unsigned flags); 51321369Sdimstatic void stripe_label(struct gctl_req *req); 52321369Sdimstatic void stripe_clear(struct gctl_req *req); 53321369Sdim 54280031Sdimstruct g_command class_commands[] = { 55321369Sdim { "clear", G_FLAG_VERBOSE, stripe_main, G_NULL_OPTS }, 56321369Sdim { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL, 57280031Sdim { 58321369Sdim { 's', "stripesize", &stripesize, G_TYPE_NUMBER }, 59321369Sdim G_OPT_SENTINEL 60321369Sdim } 61321369Sdim }, 62321369Sdim { "destroy", G_FLAG_VERBOSE, NULL, 63321369Sdim { 64321369Sdim { 'f', "force", NULL, G_TYPE_NONE }, 65321369Sdim G_OPT_SENTINEL 66321369Sdim } 67280031Sdim }, 68321369Sdim { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, stripe_main, 69321369Sdim { 70321369Sdim { 's', "stripesize", &stripesize, G_TYPE_NUMBER }, 71321369Sdim G_OPT_SENTINEL 72321369Sdim } 73321369Sdim }, 74280031Sdim { "stop", G_FLAG_VERBOSE, NULL, 75195340Sed { 76195340Sed { 'f', "force", NULL, G_TYPE_NONE }, 77195340Sed G_OPT_SENTINEL 78195340Sed } 79195340Sed }, 80208599Srdivacky G_CMD_SENTINEL 81208599Srdivacky}; 82239462Sdim 83360784Sdimstatic int verbose = 0; 84360784Sdim 85195340Sedvoid usage(const char *name); 86239462Sdimvoid 87360784Sdimusage(const char *name) 88208599Srdivacky{ 89208599Srdivacky 90208599Srdivacky fprintf(stderr, "usage: %s create [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name); 91198892Srdivacky fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name); 92314564Sdim fprintf(stderr, " %s label [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name); 93296417Sdim fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name); 94296417Sdim fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name); 95296417Sdim} 96321369Sdim 97321369Sdimstatic void 98321369Sdimstripe_main(struct gctl_req *req, unsigned flags) 99321369Sdim{ 100321369Sdim const char *name; 101321369Sdim 102195340Sed if ((flags & G_FLAG_VERBOSE) != 0) 103195340Sed verbose = 1; 104195340Sed 105195340Sed name = gctl_get_asciiparam(req, "verb"); 106195340Sed if (name == NULL) { 107195340Sed gctl_error(req, "No '%s' argument.", "verb"); 108208599Srdivacky return; 109208599Srdivacky } 110360784Sdim if (strcmp(name, "label") == 0) 111360784Sdim stripe_label(req); 112360784Sdim else if (strcmp(name, "clear") == 0) 113360784Sdim stripe_clear(req); 114195340Sed else 115341825Sdim gctl_error(req, "Unknown command: %s.", name); 116360784Sdim} 117208599Srdivacky 118208599Srdivackystatic void 119208599Srdivackystripe_label(struct gctl_req *req) 120198892Srdivacky{ 121314564Sdim struct g_stripe_metadata md; 122296417Sdim intmax_t *stripesizep; 123296417Sdim u_char sector[512]; 124296417Sdim const char *name; 125321369Sdim char param[16]; 126321369Sdim unsigned i; 127321369Sdim int *nargs, error; 128321369Sdim 129321369Sdim nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 130195340Sed if (nargs == NULL) { 131195340Sed gctl_error(req, "No '%s' argument.", "nargs"); 132280031Sdim return; 133309124Sdim } 134309124Sdim if (*nargs <= 2) { 135309124Sdim gctl_error(req, "Too few arguments."); 136309124Sdim return; 137309124Sdim } 138309124Sdim 139280031Sdim /* 140309124Sdim * Clear last sector first to spoil all components if device exists. 141280031Sdim */ 142328817Sdim for (i = 1; i < (unsigned)*nargs; i++) { 143328817Sdim snprintf(param, sizeof(param), "arg%u", i); 144328817Sdim name = gctl_get_asciiparam(req, param); 145328817Sdim 146328817Sdim error = g_metadata_clear(name, NULL); 147328817Sdim if (error != 0) { 148328817Sdim gctl_error(req, "Can't store metadata on %s: %s.", name, 149328817Sdim strerror(error)); 150328817Sdim return; 151328817Sdim } 152328817Sdim } 153328817Sdim 154328817Sdim strlcpy(md.md_magic, G_STRIPE_MAGIC, sizeof(md.md_magic)); 155 md.md_version = G_STRIPE_VERSION; 156 name = gctl_get_asciiparam(req, "arg0"); 157 if (name == NULL) { 158 gctl_error(req, "No 'arg%u' argument.", 0); 159 return; 160 } 161 strlcpy(md.md_name, name, sizeof(md.md_name)); 162 md.md_id = arc4random(); 163 md.md_all = *nargs - 1; 164 stripesizep = gctl_get_paraml(req, "stripesize", sizeof(*stripesizep)); 165 if (stripesizep == NULL) { 166 gctl_error(req, "No '%s' argument.", "stripesize"); 167 return; 168 } 169 md.md_stripesize = *stripesizep; 170 171 /* 172 * Ok, store metadata. 173 */ 174 for (i = 1; i < (unsigned)*nargs; i++) { 175 snprintf(param, sizeof(param), "arg%u", i); 176 name = gctl_get_asciiparam(req, param); 177 178 md.md_no = i - 1; 179 stripe_metadata_encode(&md, sector); 180 error = g_metadata_store(name, sector, sizeof(sector)); 181 if (error != 0) { 182 fprintf(stderr, "Can't store metadata on %s: %s.\n", 183 name, strerror(error)); 184 gctl_error(req, "Not fully done."); 185 continue; 186 } 187 if (verbose) 188 printf("Metadata value stored on %s.\n", name); 189 } 190} 191 192static void 193stripe_clear(struct gctl_req *req) 194{ 195 const char *name; 196 char param[16]; 197 unsigned i; 198 int *nargs, error; 199 200 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 201 if (nargs == NULL) { 202 gctl_error(req, "No '%s' argument.", "nargs"); 203 return; 204 } 205 if (*nargs < 1) { 206 gctl_error(req, "Too few arguments."); 207 return; 208 } 209 210 for (i = 0; i < (unsigned)*nargs; i++) { 211 snprintf(param, sizeof(param), "arg%u", i); 212 name = gctl_get_asciiparam(req, param); 213 214 error = g_metadata_clear(name, G_STRIPE_MAGIC); 215 if (error != 0) { 216 fprintf(stderr, "Can't clear metadata on %s: %s.\n", 217 name, strerror(error)); 218 gctl_error(req, "Not fully done."); 219 continue; 220 } 221 if (verbose) 222 printf("Metadata cleared on %s.\n", name); 223 } 224} 225