geom_label.c revision 330737
1177867Sjfv/*- 2169240Sjfv * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3190872Sjfv * All rights reserved. 4169240Sjfv * 5169240Sjfv * Redistribution and use in source and binary forms, with or without 6169240Sjfv * modification, are permitted provided that the following conditions 7169240Sjfv * are met: 8169240Sjfv * 1. Redistributions of source code must retain the above copyright 9169240Sjfv * notice, this list of conditions and the following disclaimer. 10169240Sjfv * 2. Redistributions in binary form must reproduce the above copyright 11169240Sjfv * notice, this list of conditions and the following disclaimer in the 12169240Sjfv * documentation and/or other materials provided with the distribution. 13169240Sjfv * 14169240Sjfv * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15169240Sjfv * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16169240Sjfv * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17169240Sjfv * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18169240Sjfv * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19169240Sjfv * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20169240Sjfv * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21169240Sjfv * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22169240Sjfv * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23169240Sjfv * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24169240Sjfv * SUCH DAMAGE. 25169240Sjfv */ 26169240Sjfv 27169240Sjfv#include <sys/cdefs.h> 28169240Sjfv__FBSDID("$FreeBSD: stable/10/sbin/geom/class/label/geom_label.c 330737 2018-03-10 04:17:01Z asomers $"); 29169240Sjfv 30169240Sjfv#include <sys/param.h> 31169240Sjfv#include <errno.h> 32177867Sjfv#include <stdio.h> 33177867Sjfv#include <stdlib.h> 34169240Sjfv#include <string.h> 35185353Sjfv#include <strings.h> 36185353Sjfv#include <assert.h> 37185353Sjfv#include <libgeom.h> 38185353Sjfv#include <geom/label/g_label.h> 39185353Sjfv 40185353Sjfv#include "core/geom.h" 41185353Sjfv#include "misc/subr.h" 42169240Sjfv 43169240Sjfv#ifdef STATIC_GEOM_CLASSES 44169589Sjfv#define PUBSYM(x) glabel_##x 45169240Sjfv#else 46177867Sjfv#define PUBSYM(x) x 47177867Sjfv#endif 48177867Sjfv 49177867Sjfvuint32_t PUBSYM(lib_version) = G_LIB_VERSION; 50177867Sjfvuint32_t PUBSYM(version) = G_LABEL_VERSION; 51177867Sjfv 52169240Sjfvstatic void label_main(struct gctl_req *req, unsigned flags); 53177867Sjfvstatic void label_clear(struct gctl_req *req); 54177867Sjfvstatic void label_dump(struct gctl_req *req); 55177867Sjfvstatic void label_label(struct gctl_req *req); 56177867Sjfv 57177867Sjfvstruct g_command PUBSYM(class_commands)[] = { 58173788Sjfv { "clear", G_FLAG_VERBOSE, label_main, G_NULL_OPTS, 59177867Sjfv "[-v] dev ..." 60177867Sjfv }, 61177867Sjfv { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL, G_NULL_OPTS, 62169240Sjfv "[-v] name dev" 63173788Sjfv }, 64169240Sjfv { "destroy", G_FLAG_VERBOSE, NULL, 65177867Sjfv { 66169240Sjfv { 'f', "force", NULL, G_TYPE_BOOL }, 67173788Sjfv G_OPT_SENTINEL 68169240Sjfv }, 69169240Sjfv "[-fv] name ..." 70169240Sjfv }, 71169240Sjfv { "dump", 0, label_main, G_NULL_OPTS, 72169240Sjfv "dev ..." 73169240Sjfv }, 74169240Sjfv { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, label_main, G_NULL_OPTS, 75169240Sjfv "[-v] name dev" 76169240Sjfv }, 77169240Sjfv { "stop", G_FLAG_VERBOSE, NULL, 78169240Sjfv { 79169240Sjfv { 'f', "force", NULL, G_TYPE_BOOL }, 80169240Sjfv G_OPT_SENTINEL 81169240Sjfv }, 82169589Sjfv "[-fv] name ..." 83169240Sjfv }, 84177867Sjfv G_CMD_SENTINEL 85169240Sjfv}; 86169240Sjfv 87169240Sjfvstatic int verbose = 0; 88169240Sjfv 89169240Sjfvstatic void 90169240Sjfvlabel_main(struct gctl_req *req, unsigned flags) 91177867Sjfv{ 92177867Sjfv const char *name; 93177867Sjfv 94177867Sjfv if ((flags & G_FLAG_VERBOSE) != 0) 95169240Sjfv verbose = 1; 96169240Sjfv 97177867Sjfv name = gctl_get_ascii(req, "verb"); 98177867Sjfv if (name == NULL) { 99177867Sjfv gctl_error(req, "No '%s' argument.", "verb"); 100177867Sjfv return; 101177867Sjfv } 102177867Sjfv if (strcmp(name, "label") == 0) 103177867Sjfv label_label(req); 104177867Sjfv else if (strcmp(name, "clear") == 0) 105177867Sjfv label_clear(req); 106177867Sjfv else if (strcmp(name, "dump") == 0) 107177867Sjfv label_dump(req); 108169240Sjfv else 109169240Sjfv gctl_error(req, "Unknown command: %s.", name); 110169240Sjfv} 111169240Sjfv 112169240Sjfvstatic void 113169240Sjfvlabel_label(struct gctl_req *req) 114169240Sjfv{ 115169240Sjfv struct g_label_metadata md; 116169240Sjfv const char *name, *label; 117169240Sjfv u_char sector[512]; 118169240Sjfv int error, nargs; 119169240Sjfv 120169240Sjfv bzero(sector, sizeof(sector)); 121169240Sjfv nargs = gctl_get_int(req, "nargs"); 122169240Sjfv if (nargs != 2) { 123169240Sjfv gctl_error(req, "Invalid number of arguments."); 124169240Sjfv return; 125169589Sjfv } 126169240Sjfv 127177867Sjfv /* 128169240Sjfv * Clear last sector first to spoil all components if device exists. 129169240Sjfv */ 130169240Sjfv name = gctl_get_ascii(req, "arg1"); 131169240Sjfv error = g_metadata_clear(name, NULL); 132169240Sjfv if (error != 0) { 133169240Sjfv gctl_error(req, "Can't store metadata on %s: %s.", name, 134169240Sjfv strerror(error)); 135169240Sjfv return; 136169240Sjfv } 137169240Sjfv 138169240Sjfv strlcpy(md.md_magic, G_LABEL_MAGIC, sizeof(md.md_magic)); 139169240Sjfv md.md_version = G_LABEL_VERSION; 140169240Sjfv label = gctl_get_ascii(req, "arg0"); 141169240Sjfv bzero(md.md_label, sizeof(md.md_label)); 142169240Sjfv strlcpy(md.md_label, label, sizeof(md.md_label)); 143169240Sjfv md.md_provsize = g_get_mediasize(name); 144169240Sjfv if (md.md_provsize == 0) { 145169240Sjfv gctl_error(req, "Can't get mediasize of %s: %s.", name, 146169240Sjfv strerror(errno)); 147169240Sjfv return; 148169240Sjfv } 149169240Sjfv 150169240Sjfv /* 151169240Sjfv * Ok, store metadata. 152169240Sjfv */ 153169240Sjfv label_metadata_encode(&md, sector); 154169240Sjfv error = g_metadata_store(name, sector, sizeof(sector)); 155169240Sjfv if (error != 0) { 156169240Sjfv fprintf(stderr, "Can't store metadata on %s: %s.\n", name, 157169240Sjfv strerror(error)); 158169240Sjfv gctl_error(req, "Not done."); 159169240Sjfv } 160169240Sjfv if (verbose) 161169240Sjfv printf("Metadata value stored on %s.\n", name); 162169240Sjfv} 163169240Sjfv 164169240Sjfvstatic void 165169240Sjfvlabel_clear(struct gctl_req *req) 166169240Sjfv{ 167169240Sjfv const char *name; 168169240Sjfv int error, i, nargs; 169177867Sjfv 170177867Sjfv nargs = gctl_get_int(req, "nargs"); 171177867Sjfv if (nargs < 1) { 172177867Sjfv gctl_error(req, "Too few arguments."); 173177867Sjfv return; 174177867Sjfv } 175177867Sjfv 176169240Sjfv for (i = 0; i < nargs; i++) { 177173788Sjfv name = gctl_get_ascii(req, "arg%d", i); 178173788Sjfv error = g_metadata_clear(name, G_LABEL_MAGIC); 179169240Sjfv if (error != 0) { 180169240Sjfv fprintf(stderr, "Can't clear metadata on %s: %s.\n", 181169240Sjfv name, strerror(error)); 182169240Sjfv gctl_error(req, "Not fully done."); 183169240Sjfv continue; 184177867Sjfv } 185169240Sjfv if (verbose) 186169240Sjfv printf("Metadata cleared on %s.\n", name); 187169240Sjfv } 188173788Sjfv} 189173788Sjfv 190169240Sjfvstatic void 191169240Sjfvlabel_metadata_dump(const struct g_label_metadata *md) 192169240Sjfv{ 193169240Sjfv 194169240Sjfv printf(" Magic string: %s\n", md->md_magic); 195169240Sjfv printf("Metadata version: %u\n", (u_int)md->md_version); 196169240Sjfv printf(" Label: %s\n", md->md_label); 197169240Sjfv} 198169240Sjfv 199169240Sjfvstatic void 200169240Sjfvlabel_dump(struct gctl_req *req) 201169240Sjfv{ 202169240Sjfv struct g_label_metadata md, tmpmd; 203169240Sjfv const char *name; 204169240Sjfv int error, i, nargs; 205169240Sjfv 206177867Sjfv nargs = gctl_get_int(req, "nargs"); 207177867Sjfv if (nargs < 1) { 208177867Sjfv gctl_error(req, "Too few arguments."); 209177867Sjfv return; 210177867Sjfv } 211177867Sjfv 212177867Sjfv for (i = 0; i < nargs; i++) { 213169240Sjfv name = gctl_get_ascii(req, "arg%d", i); 214169240Sjfv error = g_metadata_read(name, (u_char *)&tmpmd, sizeof(tmpmd), 215169240Sjfv G_LABEL_MAGIC); 216169240Sjfv if (error != 0) { 217169240Sjfv fprintf(stderr, "Can't read metadata from %s: %s.\n", 218169240Sjfv name, strerror(error)); 219169240Sjfv gctl_error(req, "Not fully done."); 220169240Sjfv continue; 221169589Sjfv } 222169240Sjfv label_metadata_decode((u_char *)&tmpmd, &md); 223177867Sjfv printf("Metadata on %s:\n", name); 224169240Sjfv label_metadata_dump(&md); 225169240Sjfv printf("\n"); 226169240Sjfv } 227169240Sjfv} 228169240Sjfv