version 1.6, 2011/08/27 17:38:16 |
version 1.21.16.1, 2019/06/10 22:05:33 |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
*/ |
|
|
|
#if HAVE_NBTOOL_CONFIG_H |
|
#include "nbtool_config.h" |
|
#endif |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
#ifdef __FBSDID |
#ifdef __FBSDID |
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $"); |
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $"); |
Line 43 __RCSID("$NetBSD$"); |
|
Line 47 __RCSID("$NetBSD$"); |
|
|
|
#include "map.h" |
#include "map.h" |
#include "gpt.h" |
#include "gpt.h" |
|
#include "gpt_private.h" |
|
|
static int all; |
static int cmd_remove(gpt_t, int, char *[]); |
static uuid_t type; |
|
static off_t block, size; |
|
static unsigned int entry; |
|
|
|
const char removemsg1[] = "remove -a device ..."; |
|
const char removemsg2[] = "remove [-b lba] [-i index] [-s lba] " |
|
"[-t type] device ..."; |
|
|
|
__dead static void |
static const char *removehelp[] = { |
usage_remove(void) |
"-a", |
{ |
"[-b blocknr] [-i index] [-L label] [-s sectors] [-t type]", |
|
}; |
|
|
|
struct gpt_cmd c_remove = { |
|
"remove", |
|
cmd_remove, |
|
removehelp, __arraycount(removehelp), |
|
GPT_SYNC, |
|
}; |
|
|
fprintf(stderr, |
#define usage() gpt_usage(NULL, &c_remove) |
"usage: %s %s\n" |
|
" %s %s\n", |
|
getprogname(), removemsg1, getprogname(), removemsg2); |
|
exit(1); |
|
} |
|
|
|
static void |
static void |
rem(int fd) |
change(struct gpt_ent *ent, void *v) |
{ |
{ |
uuid_t uuid; |
/* Remove the primary entry by clearing the partition type. */ |
map_t *gpt, *tpg; |
gpt_uuid_copy(ent->ent_type, gpt_uuid_nil); |
map_t *tbl, *lbt; |
|
map_t *m; |
|
struct gpt_hdr *hdr; |
|
struct gpt_ent *ent; |
|
unsigned int i; |
|
|
|
gpt = map_find(MAP_TYPE_PRI_GPT_HDR); |
|
if (gpt == NULL) { |
|
warnx("%s: error: no primary GPT header; run create or recover", |
|
device_name); |
|
return; |
|
} |
|
|
|
tpg = map_find(MAP_TYPE_SEC_GPT_HDR); |
|
if (tpg == NULL) { |
|
warnx("%s: error: no secondary GPT header; run recover", |
|
device_name); |
|
return; |
|
} |
|
|
|
tbl = map_find(MAP_TYPE_PRI_GPT_TBL); |
|
lbt = map_find(MAP_TYPE_SEC_GPT_TBL); |
|
if (tbl == NULL || lbt == NULL) { |
|
warnx("%s: error: run recover -- trust me", device_name); |
|
return; |
|
} |
|
|
|
/* Remove all matching entries in the map. */ |
|
for (m = map_first(); m != NULL; m = m->map_next) { |
|
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1) |
|
continue; |
|
if (entry > 0 && entry != m->map_index) |
|
continue; |
|
if (block > 0 && block != m->map_start) |
|
continue; |
|
if (size > 0 && size != m->map_size) |
|
continue; |
|
|
|
i = m->map_index - 1; |
|
|
|
hdr = gpt->map_data; |
|
ent = (void*)((char*)tbl->map_data + i * |
|
le32toh(hdr->hdr_entsz)); |
|
le_uuid_dec(&ent->ent_type, &uuid); |
|
if (!uuid_is_nil(&type, NULL) && |
|
!uuid_equal(&type, &uuid, NULL)) |
|
continue; |
|
|
|
/* Remove the primary entry by clearing the partition type. */ |
|
uuid_create_nil((uuid_t *)&ent->ent_type, NULL); |
|
|
|
hdr->hdr_crc_table = htole32(crc32(tbl->map_data, |
|
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz))); |
|
hdr->hdr_crc_self = 0; |
|
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size))); |
|
|
|
gpt_write(fd, gpt); |
|
gpt_write(fd, tbl); |
|
|
|
hdr = tpg->map_data; |
|
ent = (void*)((char*)lbt->map_data + i * |
|
le32toh(hdr->hdr_entsz)); |
|
|
|
/* Remove the secundary entry. */ |
|
uuid_create_nil((uuid_t *)&ent->ent_type, NULL); |
|
|
|
hdr->hdr_crc_table = htole32(crc32(lbt->map_data, |
|
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz))); |
|
hdr->hdr_crc_self = 0; |
|
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size))); |
|
|
|
gpt_write(fd, lbt); |
|
gpt_write(fd, tpg); |
|
#ifdef __FreeBSD__ |
|
printf("%sp%u removed\n", device_name, m->map_index); |
|
#endif |
|
#ifdef __NetBSD__ |
|
printf("partition %d removed from %s\n", m->map_index, |
|
device_name); |
|
#endif |
|
} |
|
} |
} |
|
|
int |
static int |
cmd_remove(int argc, char *argv[]) |
cmd_remove(gpt_t gpt, int argc, char *argv[]) |
{ |
{ |
char *p; |
int ch; |
int ch, fd; |
struct gpt_find find; |
|
|
/* Get the remove options */ |
memset(&find, 0, sizeof(find)); |
while ((ch = getopt(argc, argv, "ab:i:s:t:")) != -1) { |
find.msg = "removed"; |
switch(ch) { |
|
case 'a': |
|
if (all > 0) |
|
usage_remove(); |
|
all = 1; |
|
break; |
|
case 'b': |
|
if (block > 0) |
|
usage_remove(); |
|
block = strtoll(optarg, &p, 10); |
|
if (*p != 0 || block < 1) |
|
usage_remove(); |
|
break; |
|
case 'i': |
|
if (entry > 0) |
|
usage_remove(); |
|
entry = strtoul(optarg, &p, 10); |
|
if (*p != 0 || entry < 1) |
|
usage_remove(); |
|
break; |
|
case 's': |
|
if (size > 0) |
|
usage_remove(); |
|
size = strtoll(optarg, &p, 10); |
|
if (*p != 0 || size < 1) |
|
usage_remove(); |
|
break; |
|
case 't': |
|
if (!uuid_is_nil(&type, NULL)) |
|
usage_remove(); |
|
if (parse_uuid(optarg, &type) != 0) |
|
usage_remove(); |
|
break; |
|
default: |
|
usage_remove(); |
|
} |
|
} |
|
|
|
if (!all ^ |
|
(block > 0 || entry > 0 || size > 0 || !uuid_is_nil(&type, NULL))) |
|
usage_remove(); |
|
|
|
if (argc == optind) |
|
usage_remove(); |
|
|
|
while (optind < argc) { |
|
fd = gpt_open(argv[optind++]); |
|
if (fd == -1) { |
|
warn("unable to open device '%s'", device_name); |
|
continue; |
|
} |
|
|
|
rem(fd); |
/* Get the remove options */ |
|
while ((ch = getopt(argc, argv, GPT_FIND)) != -1) |
|
if (gpt_add_find(gpt, &find, ch) == -1) |
|
return usage(); |
|
|
gpt_close(fd); |
if (argc != optind) |
} |
return usage(); |
|
|
return (0); |
return gpt_change_ent(gpt, &find, change, NULL); |
} |
} |