Annotation of src/sbin/gpt/remove.c, Revision 1.6.8.1
1.1 christos 1: /*-
2: * Copyright (c) 2004 Marcel Moolenaar
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: *
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: #include <sys/cdefs.h>
1.2 christos 28: #ifdef __FBSDID
1.1 christos 29: __FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $");
1.2 christos 30: #endif
31: #ifdef __RCSID
1.6.8.1 ! tls 32: __RCSID("$NetBSD$");
1.2 christos 33: #endif
1.1 christos 34:
35: #include <sys/types.h>
36:
37: #include <err.h>
38: #include <stddef.h>
39: #include <stdio.h>
40: #include <stdlib.h>
41: #include <string.h>
42: #include <unistd.h>
43:
44: #include "map.h"
45: #include "gpt.h"
46:
47: static int all;
48: static uuid_t type;
49: static off_t block, size;
50: static unsigned int entry;
51:
1.4 riz 52: const char removemsg1[] = "remove -a device ...";
53: const char removemsg2[] = "remove [-b lba] [-i index] [-s lba] "
1.5 uebayasi 54: "[-t type] device ...";
1.4 riz 55:
1.6 joerg 56: __dead static void
1.1 christos 57: usage_remove(void)
58: {
59:
60: fprintf(stderr,
1.4 riz 61: "usage: %s %s\n"
62: " %s %s\n",
63: getprogname(), removemsg1, getprogname(), removemsg2);
1.1 christos 64: exit(1);
65: }
66:
67: static void
68: rem(int fd)
69: {
70: uuid_t uuid;
71: map_t *gpt, *tpg;
72: map_t *tbl, *lbt;
73: map_t *m;
74: struct gpt_hdr *hdr;
75: struct gpt_ent *ent;
76: unsigned int i;
77:
78: gpt = map_find(MAP_TYPE_PRI_GPT_HDR);
79: if (gpt == NULL) {
80: warnx("%s: error: no primary GPT header; run create or recover",
81: device_name);
82: return;
83: }
84:
85: tpg = map_find(MAP_TYPE_SEC_GPT_HDR);
86: if (tpg == NULL) {
87: warnx("%s: error: no secondary GPT header; run recover",
88: device_name);
89: return;
90: }
91:
92: tbl = map_find(MAP_TYPE_PRI_GPT_TBL);
93: lbt = map_find(MAP_TYPE_SEC_GPT_TBL);
94: if (tbl == NULL || lbt == NULL) {
95: warnx("%s: error: run recover -- trust me", device_name);
96: return;
97: }
98:
99: /* Remove all matching entries in the map. */
100: for (m = map_first(); m != NULL; m = m->map_next) {
101: if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
102: continue;
103: if (entry > 0 && entry != m->map_index)
104: continue;
105: if (block > 0 && block != m->map_start)
106: continue;
107: if (size > 0 && size != m->map_size)
108: continue;
109:
110: i = m->map_index - 1;
111:
112: hdr = gpt->map_data;
113: ent = (void*)((char*)tbl->map_data + i *
114: le32toh(hdr->hdr_entsz));
1.6.8.1 ! tls 115: le_uuid_dec(ent->ent_type, &uuid);
1.1 christos 116: if (!uuid_is_nil(&type, NULL) &&
117: !uuid_equal(&type, &uuid, NULL))
118: continue;
119:
120: /* Remove the primary entry by clearing the partition type. */
1.6.8.1 ! tls 121: uuid_create_nil(&uuid, NULL);
! 122: le_uuid_enc(ent->ent_type, &uuid);
1.1 christos 123:
124: hdr->hdr_crc_table = htole32(crc32(tbl->map_data,
125: le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
126: hdr->hdr_crc_self = 0;
127: hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
128:
129: gpt_write(fd, gpt);
130: gpt_write(fd, tbl);
131:
132: hdr = tpg->map_data;
133: ent = (void*)((char*)lbt->map_data + i *
134: le32toh(hdr->hdr_entsz));
135:
1.6.8.1 ! tls 136: /* Remove the secondary entry. */
! 137: le_uuid_enc(ent->ent_type, &uuid);
1.1 christos 138:
139: hdr->hdr_crc_table = htole32(crc32(lbt->map_data,
140: le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
141: hdr->hdr_crc_self = 0;
142: hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
143:
144: gpt_write(fd, lbt);
145: gpt_write(fd, tpg);
1.2 christos 146: #ifdef __FreeBSD__
1.1 christos 147: printf("%sp%u removed\n", device_name, m->map_index);
1.2 christos 148: #endif
149: #ifdef __NetBSD__
150: printf("partition %d removed from %s\n", m->map_index,
151: device_name);
152: #endif
1.1 christos 153: }
154: }
155:
156: int
157: cmd_remove(int argc, char *argv[])
158: {
159: char *p;
160: int ch, fd;
161:
162: /* Get the remove options */
163: while ((ch = getopt(argc, argv, "ab:i:s:t:")) != -1) {
164: switch(ch) {
165: case 'a':
166: if (all > 0)
167: usage_remove();
168: all = 1;
169: break;
170: case 'b':
171: if (block > 0)
172: usage_remove();
173: block = strtoll(optarg, &p, 10);
174: if (*p != 0 || block < 1)
175: usage_remove();
176: break;
177: case 'i':
178: if (entry > 0)
179: usage_remove();
1.3 riz 180: entry = strtoul(optarg, &p, 10);
1.1 christos 181: if (*p != 0 || entry < 1)
182: usage_remove();
183: break;
184: case 's':
185: if (size > 0)
186: usage_remove();
187: size = strtoll(optarg, &p, 10);
188: if (*p != 0 || size < 1)
189: usage_remove();
190: break;
191: case 't':
192: if (!uuid_is_nil(&type, NULL))
193: usage_remove();
194: if (parse_uuid(optarg, &type) != 0)
195: usage_remove();
196: break;
197: default:
198: usage_remove();
199: }
200: }
201:
202: if (!all ^
203: (block > 0 || entry > 0 || size > 0 || !uuid_is_nil(&type, NULL)))
204: usage_remove();
205:
206: if (argc == optind)
207: usage_remove();
208:
209: while (optind < argc) {
210: fd = gpt_open(argv[optind++]);
211: if (fd == -1) {
212: warn("unable to open device '%s'", device_name);
213: continue;
214: }
215:
216: rem(fd);
217:
218: gpt_close(fd);
219: }
220:
221: return (0);
222: }
CVSweb <webmaster@jp.NetBSD.org>