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

Annotation of src/sbin/gpt/add.c, Revision 1.38

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.25      christos   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
                     33: __FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
                     34: #endif
                     35: #ifdef __RCSID
1.38    ! christos   36: __RCSID("$NetBSD: add.c,v 1.37 2015/12/02 11:20:34 jnemeth Exp $");
1.2       christos   37: #endif
1.1       christos   38:
                     39: #include <sys/types.h>
1.31      christos   40: #include <sys/param.h>
                     41: #include <sys/stat.h>
1.1       christos   42:
                     43: #include <err.h>
                     44: #include <stddef.h>
                     45: #include <stdio.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48: #include <unistd.h>
                     49:
                     50: #include "map.h"
                     51: #include "gpt.h"
1.31      christos   52: #include "gpt_private.h"
1.1       christos   53:
1.32      christos   54: static int cmd_add(gpt_t, int, char *[]);
1.1       christos   55:
1.32      christos   56: static const char *addhelp[] = {
1.38    ! christos   57:        "[-a alignment] [-b blocknr] [-i index] [-l label]",
        !            58:        "[-s size] [-t type]",
1.32      christos   59: };
                     60:
                     61: struct gpt_cmd c_add = {
                     62:        "add",
                     63:        cmd_add,
                     64:        addhelp, __arraycount(addhelp),
                     65:        0,
                     66: };
1.5       riz        67:
1.32      christos   68: #define usage() gpt_usage(NULL, &c_add)
1.1       christos   69:
1.35      christos   70: static void
                     71: ent_set(struct gpt_ent *ent, const map_t map, const gpt_uuid_t xtype,
                     72:     const uint8_t *xname)
                     73: {
                     74:        gpt_uuid_copy(ent->ent_type, xtype);
                     75:        ent->ent_lba_start = htole64(map->map_start);
                     76:        ent->ent_lba_end = htole64(map->map_start + map->map_size - 1LL);
1.36      christos   77:        if (xname == NULL)
                     78:                return;
                     79:        utf8_to_utf16(xname, ent->ent_name, __arraycount(ent->ent_name));
1.35      christos   80: }
                     81:
1.31      christos   82: static int
1.38    ! christos   83: add(gpt_t gpt, off_t alignment, off_t block, off_t sectors, off_t size,
        !            84:     u_int entry, uint8_t *name, gpt_uuid_t type)
1.1       christos   85: {
1.31      christos   86:        map_t map;
1.1       christos   87:        struct gpt_hdr *hdr;
1.35      christos   88:        struct gpt_ent *ent;
1.1       christos   89:        unsigned int i;
1.15      jnemeth    90:        off_t alignsecs;
1.33      christos   91:        char buf[128];
1.15      jnemeth    92:
1.31      christos   93:        if ((hdr = gpt_hdr(gpt)) == NULL)
                     94:                return -1;
1.1       christos   95:
1.3       he         96:        ent = NULL;
1.1       christos   97:
                     98:        if (entry > le32toh(hdr->hdr_entries)) {
1.31      christos   99:                gpt_warnx(gpt, "index %u out of range (%u max)",
1.1       christos  100:                    entry, le32toh(hdr->hdr_entries));
1.31      christos  101:                return -1;
1.1       christos  102:        }
                    103:
                    104:        if (entry > 0) {
                    105:                i = entry - 1;
1.31      christos  106:                ent = gpt_ent_primary(gpt, i);
1.27      christos  107:                if (!gpt_uuid_is_nil(ent->ent_type)) {
1.31      christos  108:                        gpt_warnx(gpt, "Entry at index %u is not free", entry);
                    109:                        return -1;
1.1       christos  110:                }
                    111:        } else {
                    112:                /* Find empty slot in GPT table. */
                    113:                for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
1.31      christos  114:                        ent = gpt_ent_primary(gpt, i);
1.27      christos  115:                        if (gpt_uuid_is_nil(ent->ent_type))
1.1       christos  116:                                break;
                    117:                }
                    118:                if (i == le32toh(hdr->hdr_entries)) {
1.31      christos  119:                        gpt_warnx(gpt, "No available table entries");
                    120:                        return -1;
1.1       christos  121:                }
                    122:        }
                    123:
1.15      jnemeth   124:        if (alignment > 0) {
1.31      christos  125:                alignsecs = alignment / gpt->secsz;
                    126:                map = map_alloc(gpt, block, sectors, alignsecs);
1.15      jnemeth   127:                if (map == NULL) {
1.31      christos  128:                        gpt_warnx(gpt, "Not enough space available on "
                    129:                              "device for an aligned partition");
                    130:                        return -1;
1.15      jnemeth   131:                }
                    132:        } else {
1.31      christos  133:                map = map_alloc(gpt, block, sectors, 0);
1.15      jnemeth   134:                if (map == NULL) {
1.31      christos  135:                        gpt_warnx(gpt, "Not enough space available on device");
                    136:                        return -1;
1.15      jnemeth   137:                }
1.1       christos  138:        }
                    139:
1.35      christos  140:        ent_set(ent, map, type, name);
1.31      christos  141:        gpt_write_primary(gpt);
1.1       christos  142:
1.31      christos  143:        ent = gpt_ent_backup(gpt, i);
1.35      christos  144:        ent_set(ent, map, type, name);
1.31      christos  145:        gpt_write_backup(gpt);
1.1       christos  146:
1.33      christos  147:        gpt_uuid_snprintf(buf, sizeof(buf), "%d", type);
                    148:        gpt_msg(gpt, "Partition %d added: %s %" PRIu64 " %" PRIu64, i + 1,
                    149:            buf, map->map_start, map->map_size);
1.31      christos  150:        return 0;
1.1       christos  151: }
                    152:
1.32      christos  153: static int
1.31      christos  154: cmd_add(gpt_t gpt, int argc, char *argv[])
1.1       christos  155: {
1.31      christos  156:        int ch;
1.38    ! christos  157:        off_t alignment = 0, block = 0, sectors = 0, size = 0;
        !           158:        unsigned int entry = 0;
        !           159:        uint8_t *name = NULL;
        !           160:        gpt_uuid_t type;
        !           161:
        !           162:        gpt_uuid_copy(type, gpt_uuid_nil);
1.1       christos  163:
1.37      jnemeth   164:        while ((ch = getopt(argc, argv, GPT_AIS "b:l:t:")) != -1) {
1.1       christos  165:                switch(ch) {
                    166:                case 'b':
1.34      christos  167:                        if (gpt_human_get(&block) == -1)
1.32      christos  168:                                return usage();
1.1       christos  169:                        break;
1.15      jnemeth   170:                case 'l':
1.34      christos  171:                        if (gpt_name_get(gpt, &name) == -1)
1.32      christos  172:                                return usage();
1.15      jnemeth   173:                        break;
1.1       christos  174:                case 't':
1.34      christos  175:                        if (gpt_uuid_get(gpt, &type) == -1)
1.32      christos  176:                                return usage();
1.1       christos  177:                        break;
                    178:                default:
1.33      christos  179:                        if (gpt_add_ais(gpt, &alignment, &entry, &size, ch)
                    180:                            == -1)
                    181:                                return usage();
                    182:                        break;
1.1       christos  183:                }
                    184:        }
                    185:
1.33      christos  186:        if (argc != optind)
1.32      christos  187:                return usage();
1.1       christos  188:
1.9       jakllsch  189:        /* Create NetBSD FFS partitions by default. */
1.34      christos  190:        if (gpt_uuid_is_nil(type))
1.27      christos  191:                gpt_uuid_create(GPT_TYPE_NETBSD_FFS, type, NULL, 0);
1.1       christos  192:
1.31      christos  193:        if (optind != argc)
1.32      christos  194:                return usage();
1.1       christos  195:
1.35      christos  196:        if ((sectors = gpt_check_ais(gpt, alignment, ~0, size)) == -1)
1.31      christos  197:                return -1;
1.1       christos  198:
1.38    ! christos  199:        return add(gpt, alignment, block, sectors, size, entry, name, type);
1.1       christos  200: }

CVSweb <webmaster@jp.NetBSD.org>