geom_stripe.c revision 131879
1/*- 2 * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sbin/geom/class/stripe/geom_stripe.c 131879 2004-07-09 14:41:51Z pjd $"); 29 30#include <sys/param.h> 31#include <errno.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <stdint.h> 35#include <string.h> 36#include <strings.h> 37#include <assert.h> 38#include <libgeom.h> 39#include <geom/stripe/g_stripe.h> 40 41#include "core/geom.h" 42#include "misc/subr.h" 43 44 45uint32_t lib_version = G_LIB_VERSION; 46uint32_t version = G_STRIPE_VERSION; 47 48static intmax_t stripesize = 4096; 49 50static void stripe_main(struct gctl_req *req, unsigned flags); 51static void stripe_label(struct gctl_req *req); 52static void stripe_clear(struct gctl_req *req); 53 54struct g_command class_commands[] = { 55 { "clear", G_FLAG_VERBOSE, stripe_main, G_NULL_OPTS }, 56 { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL, 57 { 58 { 's', "stripesize", &stripesize, G_TYPE_NUMBER }, 59 G_OPT_SENTINEL 60 } 61 }, 62 { "destroy", G_FLAG_VERBOSE, NULL, 63 { 64 { 'f', "force", NULL, G_TYPE_NONE }, 65 G_OPT_SENTINEL 66 } 67 }, 68 { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, stripe_main, 69 { 70 { 's', "stripesize", &stripesize, G_TYPE_NUMBER }, 71 G_OPT_SENTINEL 72 } 73 }, 74 { "stop", G_FLAG_VERBOSE, NULL, 75 { 76 { 'f', "force", NULL, G_TYPE_NONE }, 77 G_OPT_SENTINEL 78 } 79 }, 80 G_CMD_SENTINEL 81}; 82 83static int verbose = 0; 84 85void usage(const char *name); 86void 87usage(const char *name) 88{ 89 90 fprintf(stderr, "usage: %s create [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name); 91 fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name); 92 fprintf(stderr, " %s label [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name); 93 fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name); 94 fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name); 95} 96 97static void 98stripe_main(struct gctl_req *req, unsigned flags) 99{ 100 const char *name; 101 102 if ((flags & G_FLAG_VERBOSE) != 0) 103 verbose = 1; 104 105 name = gctl_get_asciiparam(req, "verb"); 106 if (name == NULL) { 107 gctl_error(req, "No '%s' argument.", "verb"); 108 return; 109 } 110 if (strcmp(name, "label") == 0) 111 stripe_label(req); 112 else if (strcmp(name, "clear") == 0) 113 stripe_clear(req); 114 else 115 gctl_error(req, "Unknown command: %s.", name); 116} 117 118static void 119stripe_label(struct gctl_req *req) 120{ 121 struct g_stripe_metadata md; 122 intmax_t *stripesizep; 123 u_char sector[512]; 124 const char *name; 125 char param[16]; 126 unsigned i; 127 int *nargs, error; 128 129 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 130 if (nargs == NULL) { 131 gctl_error(req, "No '%s' argument.", "nargs"); 132 return; 133 } 134 if (*nargs <= 2) { 135 gctl_error(req, "Too few arguments."); 136 return; 137 } 138 139 /* 140 * Clear last sector first to spoil all components if device exists. 141 */ 142 for (i = 1; i < (unsigned)*nargs; i++) { 143 snprintf(param, sizeof(param), "arg%u", i); 144 name = gctl_get_asciiparam(req, param); 145 146 error = g_metadata_clear(name, NULL); 147 if (error != 0) { 148 gctl_error(req, "Can't store metadata on %s: %s.", name, 149 strerror(error)); 150 return; 151 } 152 } 153 154 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