[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.37

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

CVSweb <webmaster@jp.NetBSD.org>