[BACK]Return to recover.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / gpt

Annotation of src/sbin/gpt/recover.c, Revision 1.4.20.1

1.1       christos    1: /*-
                      2:  * Copyright (c) 2002 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:
1.4.20.1! snj        27: #if HAVE_NBTOOL_CONFIG_H
        !            28: #include "nbtool_config.h"
        !            29: #endif
        !            30:
1.1       christos   31: #include <sys/cdefs.h>
1.2       christos   32: #ifdef __FBSDID
1.1       christos   33: __FBSDID("$FreeBSD: src/sbin/gpt/recover.c,v 1.8 2005/08/31 01:47:19 marcel Exp $");
1.2       christos   34: #endif
                     35: #ifdef __RCSID
1.4.20.1! snj        36: __RCSID("$NetBSD: recover.c,v 1.4 2011/08/27 17:38:16 joerg Exp $");
1.2       christos   37: #endif
1.1       christos   38:
                     39: #include <sys/types.h>
                     40:
                     41: #include <err.h>
                     42: #include <stddef.h>
                     43: #include <stdio.h>
                     44: #include <stdlib.h>
                     45: #include <string.h>
                     46: #include <unistd.h>
                     47:
                     48: #include "map.h"
                     49: #include "gpt.h"
                     50:
                     51: static int recoverable;
                     52:
1.3       riz        53: const char recovermsg[] = "recover device ...";
                     54:
1.4       joerg      55: __dead static void
1.1       christos   56: usage_recover(void)
                     57: {
                     58:
                     59:        fprintf(stderr,
1.3       riz        60:            "usage: %s %s\n", getprogname(), recovermsg);
1.1       christos   61:        exit(1);
                     62: }
                     63:
                     64: static void
                     65: recover(int fd)
                     66: {
                     67:        off_t last;
                     68:        map_t *gpt, *tpg;
                     69:        map_t *tbl, *lbt;
                     70:        struct gpt_hdr *hdr;
                     71:
                     72:        if (map_find(MAP_TYPE_MBR) != NULL) {
                     73:                warnx("%s: error: device contains a MBR", device_name);
                     74:                return;
                     75:        }
                     76:
                     77:        gpt = map_find(MAP_TYPE_PRI_GPT_HDR);
                     78:        tpg = map_find(MAP_TYPE_SEC_GPT_HDR);
                     79:        tbl = map_find(MAP_TYPE_PRI_GPT_TBL);
                     80:        lbt = map_find(MAP_TYPE_SEC_GPT_TBL);
                     81:
                     82:        if (gpt == NULL && tpg == NULL) {
                     83:                warnx("%s: no primary or secondary GPT headers, can't recover",
                     84:                    device_name);
                     85:                return;
                     86:        }
                     87:        if (tbl == NULL && lbt == NULL) {
                     88:                warnx("%s: no primary or secondary GPT tables, can't recover",
                     89:                    device_name);
                     90:                return;
                     91:        }
                     92:
                     93:        last = mediasz / secsz - 1LL;
                     94:
                     95:        if (tbl != NULL && lbt == NULL) {
                     96:                lbt = map_add(last - tbl->map_size, tbl->map_size,
                     97:                    MAP_TYPE_SEC_GPT_TBL, tbl->map_data);
                     98:                if (lbt == NULL) {
                     99:                        warnx("%s: adding secondary GPT table failed",
                    100:                            device_name);
                    101:                        return;
                    102:                }
                    103:                gpt_write(fd, lbt);
                    104:                warnx("%s: recovered secondary GPT table from primary",
                    105:                    device_name);
                    106:        } else if (tbl == NULL && lbt != NULL) {
                    107:                tbl = map_add(2LL, lbt->map_size, MAP_TYPE_PRI_GPT_TBL,
                    108:                    lbt->map_data);
                    109:                if (tbl == NULL) {
                    110:                        warnx("%s: adding primary GPT table failed",
                    111:                            device_name);
                    112:                        return;
                    113:                }
                    114:                gpt_write(fd, tbl);
                    115:                warnx("%s: recovered primary GPT table from secondary",
                    116:                    device_name);
                    117:        }
                    118:
                    119:        if (gpt != NULL && tpg == NULL) {
                    120:                tpg = map_add(last, 1LL, MAP_TYPE_SEC_GPT_HDR,
                    121:                    calloc(1, secsz));
                    122:                if (tpg == NULL) {
                    123:                        warnx("%s: adding secondary GPT header failed",
                    124:                            device_name);
                    125:                        return;
                    126:                }
                    127:                memcpy(tpg->map_data, gpt->map_data, secsz);
                    128:                hdr = tpg->map_data;
                    129:                hdr->hdr_lba_self = htole64(tpg->map_start);
                    130:                hdr->hdr_lba_alt = htole64(gpt->map_start);
                    131:                hdr->hdr_lba_table = htole64(lbt->map_start);
                    132:                hdr->hdr_crc_self = 0;
                    133:                hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
                    134:                gpt_write(fd, tpg);
                    135:                warnx("%s: recovered secondary GPT header from primary",
                    136:                    device_name);
                    137:        } else if (gpt == NULL && tpg != NULL) {
                    138:                gpt = map_add(1LL, 1LL, MAP_TYPE_PRI_GPT_HDR,
                    139:                    calloc(1, secsz));
                    140:                if (gpt == NULL) {
                    141:                        warnx("%s: adding primary GPT header failed",
                    142:                            device_name);
                    143:                        return;
                    144:                }
                    145:                memcpy(gpt->map_data, tpg->map_data, secsz);
                    146:                hdr = gpt->map_data;
                    147:                hdr->hdr_lba_self = htole64(gpt->map_start);
                    148:                hdr->hdr_lba_alt = htole64(tpg->map_start);
                    149:                hdr->hdr_lba_table = htole64(tbl->map_start);
                    150:                hdr->hdr_crc_self = 0;
                    151:                hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
                    152:                gpt_write(fd, gpt);
                    153:                warnx("%s: recovered primary GPT header from secondary",
                    154:                    device_name);
                    155:        }
                    156: }
                    157:
                    158: int
                    159: cmd_recover(int argc, char *argv[])
                    160: {
                    161:        int ch, fd;
                    162:
                    163:        while ((ch = getopt(argc, argv, "r")) != -1) {
                    164:                switch(ch) {
                    165:                case 'r':
                    166:                        recoverable = 1;
                    167:                        break;
                    168:                default:
                    169:                        usage_recover();
                    170:                }
                    171:        }
                    172:
                    173:        if (argc == optind)
                    174:                usage_recover();
                    175:
                    176:        while (optind < argc) {
                    177:                fd = gpt_open(argv[optind++]);
                    178:                if (fd == -1) {
                    179:                        warn("unable to open device '%s'", device_name);
                    180:                        continue;
                    181:                }
                    182:
                    183:                recover(fd);
                    184:
                    185:                gpt_close(fd);
                    186:        }
                    187:
                    188:        return (0);
                    189: }

CVSweb <webmaster@jp.NetBSD.org>