1b33a7e92SMatthew Dillon /*
2fd8fd3dfSMatthew Dillon * Copyright (c) 2011-2015 The DragonFly Project. All rights reserved.
3b33a7e92SMatthew Dillon *
4b33a7e92SMatthew Dillon * This code is derived from software contributed to The DragonFly Project
5b33a7e92SMatthew Dillon * by Matthew Dillon <dillon@dragonflybsd.org>
6b33a7e92SMatthew Dillon *
7b33a7e92SMatthew Dillon * Redistribution and use in source and binary forms, with or without
8b33a7e92SMatthew Dillon * modification, are permitted provided that the following conditions
9b33a7e92SMatthew Dillon * are met:
10b33a7e92SMatthew Dillon *
11b33a7e92SMatthew Dillon * 1. Redistributions of source code must retain the above copyright
12b33a7e92SMatthew Dillon * notice, this list of conditions and the following disclaimer.
13b33a7e92SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
14b33a7e92SMatthew Dillon * notice, this list of conditions and the following disclaimer in
15b33a7e92SMatthew Dillon * the documentation and/or other materials provided with the
16b33a7e92SMatthew Dillon * distribution.
17b33a7e92SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
18b33a7e92SMatthew Dillon * contributors may be used to endorse or promote products derived
19b33a7e92SMatthew Dillon * from this software without specific, prior written permission.
20b33a7e92SMatthew Dillon *
21b33a7e92SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22b33a7e92SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23b33a7e92SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24b33a7e92SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25b33a7e92SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26b33a7e92SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27b33a7e92SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28b33a7e92SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29b33a7e92SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30b33a7e92SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31b33a7e92SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32b33a7e92SMatthew Dillon * SUCH DAMAGE.
33b33a7e92SMatthew Dillon */
34b33a7e92SMatthew Dillon
35b33a7e92SMatthew Dillon #include <sys/types.h>
36b33a7e92SMatthew Dillon
37b33a7e92SMatthew Dillon #include <stdio.h>
38b33a7e92SMatthew Dillon #include <stdlib.h>
39b33a7e92SMatthew Dillon #include <stddef.h>
40b33a7e92SMatthew Dillon #include <unistd.h>
41b33a7e92SMatthew Dillon #include <string.h>
4260e242c5STomohiro Kusumi #include <assert.h>
43b33a7e92SMatthew Dillon #include <err.h>
44b33a7e92SMatthew Dillon
452d60b848STomohiro Kusumi #include "mkfs_hammer2.h"
4689d864a2SMatthew Dillon
472dc244c9STomohiro Kusumi static void parse_fs_size(hammer2_mkfs_options_t *, const char *);
48b33a7e92SMatthew Dillon static void usage(void);
49b33a7e92SMatthew Dillon
50b33a7e92SMatthew Dillon int
main(int ac,char ** av)51b33a7e92SMatthew Dillon main(int ac, char **av)
52b33a7e92SMatthew Dillon {
532d60b848STomohiro Kusumi hammer2_mkfs_options_t opt;
54b33a7e92SMatthew Dillon int ch;
552d60b848STomohiro Kusumi int label_specified = 0;
5689d864a2SMatthew Dillon
57b33a7e92SMatthew Dillon /*
582d60b848STomohiro Kusumi * Initialize option structure.
59b33a7e92SMatthew Dillon */
602d60b848STomohiro Kusumi hammer2_mkfs_init(&opt);
61b33a7e92SMatthew Dillon
62b33a7e92SMatthew Dillon /*
632d60b848STomohiro Kusumi * Parse arguments.
64b33a7e92SMatthew Dillon */
656dd91095STomohiro Kusumi while ((ch = getopt(ac, av, "L:b:r:V:s:d")) != -1) {
66b33a7e92SMatthew Dillon switch(ch) {
672d60b848STomohiro Kusumi case 'b':
682d60b848STomohiro Kusumi opt.BootAreaSize = getsize(optarg,
692d60b848STomohiro Kusumi HAMMER2_NEWFS_ALIGN,
702d60b848STomohiro Kusumi HAMMER2_BOOT_MAX_BYTES, 2);
712d60b848STomohiro Kusumi break;
722d60b848STomohiro Kusumi case 'r':
732d60b848STomohiro Kusumi opt.AuxAreaSize = getsize(optarg,
742d60b848STomohiro Kusumi HAMMER2_NEWFS_ALIGN,
752d60b848STomohiro Kusumi HAMMER2_AUX_MAX_BYTES, 2);
762d60b848STomohiro Kusumi break;
772d60b848STomohiro Kusumi case 'V':
782d60b848STomohiro Kusumi opt.Hammer2Version = strtol(optarg, NULL, 0);
792d60b848STomohiro Kusumi if (opt.Hammer2Version < HAMMER2_VOL_VERSION_MIN ||
802d60b848STomohiro Kusumi opt.Hammer2Version >= HAMMER2_VOL_VERSION_WIP) {
812d60b848STomohiro Kusumi errx(1, "I don't understand how to format "
822d60b848STomohiro Kusumi "HAMMER2 version %d",
832d60b848STomohiro Kusumi opt.Hammer2Version);
842d60b848STomohiro Kusumi }
852d60b848STomohiro Kusumi break;
86b33a7e92SMatthew Dillon case 'L':
872d60b848STomohiro Kusumi label_specified = 1;
8889d864a2SMatthew Dillon if (strcasecmp(optarg, "none") == 0) {
8989d864a2SMatthew Dillon break;
9089d864a2SMatthew Dillon }
912d60b848STomohiro Kusumi if (opt.NLabels >= MAXLABELS) {
92234b2171STomohiro Kusumi errx(1, "Limit of %d local labels",
935cebbe36SMatthew Dillon MAXLABELS - 1);
9489d864a2SMatthew Dillon }
95eabc9a2cSMatthew Dillon if (strlen(optarg) == 0) {
962e1975d5STomohiro Kusumi errx(1, "Volume label '%s' cannot be 0-length",
97eabc9a2cSMatthew Dillon optarg);
98b33a7e92SMatthew Dillon }
99eabc9a2cSMatthew Dillon if (strlen(optarg) >= HAMMER2_INODE_MAXNAME) {
100eabc9a2cSMatthew Dillon errx(1, "Volume label '%s' is too long "
1012e1975d5STomohiro Kusumi "(%d chars max)",
102eabc9a2cSMatthew Dillon optarg,
103eabc9a2cSMatthew Dillon HAMMER2_INODE_MAXNAME - 1);
104eabc9a2cSMatthew Dillon }
1052d60b848STomohiro Kusumi opt.Label[opt.NLabels++] = strdup(optarg);
106b33a7e92SMatthew Dillon break;
1076dd91095STomohiro Kusumi case 's':
1082dc244c9STomohiro Kusumi parse_fs_size(&opt, optarg);
1096dd91095STomohiro Kusumi break;
1100b738157STomohiro Kusumi case 'd':
1112d60b848STomohiro Kusumi opt.DebugOpt = 1;
1120b738157STomohiro Kusumi break;
113b33a7e92SMatthew Dillon default:
114b33a7e92SMatthew Dillon usage();
115b33a7e92SMatthew Dillon break;
116b33a7e92SMatthew Dillon }
117b33a7e92SMatthew Dillon }
118b33a7e92SMatthew Dillon
119b33a7e92SMatthew Dillon ac -= optind;
120b33a7e92SMatthew Dillon av += optind;
121b33a7e92SMatthew Dillon
1220b738157STomohiro Kusumi if (ac == 0)
1230b738157STomohiro Kusumi errx(1, "You must specify at least one disk device");
1240b738157STomohiro Kusumi if (ac > HAMMER2_MAX_VOLUMES)
1250b738157STomohiro Kusumi errx(1, "The maximum number of volumes is %d",
1260b738157STomohiro Kusumi HAMMER2_MAX_VOLUMES);
127fd8fd3dfSMatthew Dillon
128fd8fd3dfSMatthew Dillon /*
1292d60b848STomohiro Kusumi * Check default label type.
130fd8fd3dfSMatthew Dillon */
1312d60b848STomohiro Kusumi if (!label_specified) {
132fd8fd3dfSMatthew Dillon char c = av[0][strlen(av[0]) - 1];
133fd8fd3dfSMatthew Dillon if (c == 'a')
1342d60b848STomohiro Kusumi opt.DefaultLabelType = HAMMER2_LABEL_BOOT;
135fd8fd3dfSMatthew Dillon else if (c == 'd')
1362d60b848STomohiro Kusumi opt.DefaultLabelType = HAMMER2_LABEL_ROOT;
137fd8fd3dfSMatthew Dillon else
1382d60b848STomohiro Kusumi opt.DefaultLabelType = HAMMER2_LABEL_DATA;
139fd8fd3dfSMatthew Dillon }
140fd8fd3dfSMatthew Dillon
141fd8fd3dfSMatthew Dillon /*
1422d60b848STomohiro Kusumi * Create Hammer2 filesystem.
143fd8fd3dfSMatthew Dillon */
144a071436bSTomohiro Kusumi assert(opt.CompType == HAMMER2_COMP_DEFAULT);
145*9046282cSTomohiro Kusumi assert(opt.CheckType == HAMMER2_CHECK_DEFAULT);
1462d60b848STomohiro Kusumi hammer2_mkfs(ac, av, &opt);
147b33a7e92SMatthew Dillon
148b33a7e92SMatthew Dillon /*
1492d60b848STomohiro Kusumi * Cleanup option structure.
150b33a7e92SMatthew Dillon */
1512d60b848STomohiro Kusumi hammer2_mkfs_cleanup(&opt);
1520b738157STomohiro Kusumi
153b33a7e92SMatthew Dillon return(0);
154b33a7e92SMatthew Dillon }
155b33a7e92SMatthew Dillon
156b33a7e92SMatthew Dillon static
157b33a7e92SMatthew Dillon void
parse_fs_size(hammer2_mkfs_options_t * opt,const char * arg)1582dc244c9STomohiro Kusumi parse_fs_size(hammer2_mkfs_options_t *opt, const char *arg)
1592dc244c9STomohiro Kusumi {
1602dc244c9STomohiro Kusumi char *o, *p, *s;
1612dc244c9STomohiro Kusumi
1622dc244c9STomohiro Kusumi opt->NFileSystemSizes = 0;
1632dc244c9STomohiro Kusumi o = p = strdup(arg);
1642dc244c9STomohiro Kusumi
1652dc244c9STomohiro Kusumi while ((s = p) != NULL) {
1662dc244c9STomohiro Kusumi if ((p = strchr(p, ':')) != NULL)
1672dc244c9STomohiro Kusumi *p++ = 0;
1682dc244c9STomohiro Kusumi /* XXX 0x7fffffffffffffff isn't limitation of HAMMER2 */
1692dc244c9STomohiro Kusumi opt->FileSystemSize[opt->NFileSystemSizes++] = getsize(s,
1702dc244c9STomohiro Kusumi HAMMER2_FREEMAP_LEVEL1_SIZE,
1712dc244c9STomohiro Kusumi 0x7fffffffffffffff, 2);
172af73f535STomohiro Kusumi if (opt->NFileSystemSizes >= HAMMER2_MAX_VOLUMES)
173af73f535STomohiro Kusumi break;
1742dc244c9STomohiro Kusumi }
1752dc244c9STomohiro Kusumi free(o);
1762dc244c9STomohiro Kusumi }
1772dc244c9STomohiro Kusumi
1782dc244c9STomohiro Kusumi static
1792dc244c9STomohiro Kusumi void
usage(void)180b33a7e92SMatthew Dillon usage(void)
181b33a7e92SMatthew Dillon {
182b33a7e92SMatthew Dillon fprintf(stderr,
1837b2944d3STomohiro Kusumi "usage: newfs_hammer2 [-b bootsize] [-r auxsize] "
1846dd91095STomohiro Kusumi "[-V version] [-L label ...] [-s size] special ...\n"
185b33a7e92SMatthew Dillon );
186b33a7e92SMatthew Dillon exit(1);
187b33a7e92SMatthew Dillon }
188