]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_format.c
Rename from bcache-tools to bcachefs-tools
[bcachefs-tools-debian] / cmd_format.c
1 /*
2  * Authors: Kent Overstreet <kent.overstreet@gmail.com>
3  *          Gabriel de Perthuis <g2p.code@gmail.com>
4  *          Jacob Malevich <jam@datera.io>
5  *
6  * GPLv2
7  */
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <getopt.h>
11 #include <stdbool.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20 #include <uuid/uuid.h>
21
22 #include "ccan/darray/darray.h"
23
24 #include "cmds.h"
25 #include "libbcachefs.h"
26 #include "crypto.h"
27 #include "opts.h"
28 #include "util.h"
29
30 #define OPTS                                                                    \
31 t("bcachefs format - create a new bcachefs filesystem on one or more devices")  \
32 t("Usage: bcachefs format [OPTION]... <devices>")                                       \
33 t("")                                                                           \
34 x('b',  block_size,             "size",                 NULL)                   \
35 x(0,    btree_node_size,        "size",                 "Default 256k")         \
36 x(0,    metadata_checksum_type, "(none|crc32c|crc64)",  NULL)                   \
37 x(0,    data_checksum_type,     "(none|crc32c|crc64)",  NULL)                   \
38 x(0,    compression_type,       "(none|lz4|gzip)",      NULL)                   \
39 x(0,    data_replicas,          "#",                    NULL)                   \
40 x(0,    metadata_replicas,      "#",                    NULL)                   \
41 x(0,    encrypted,              NULL,                   "Enable whole filesystem encryption (chacha20/poly1305)")\
42 x(0,    no_passphrase,          NULL,                   "Don't encrypt master encryption key")\
43 x('e',  error_action,           "(continue|readonly|panic)", NULL)              \
44 x(0,    max_journal_entry_size, "size",                 NULL)                   \
45 x('L',  label,                  "label",                NULL)                   \
46 x('U',  uuid,                   "uuid",                 NULL)                   \
47 x('f',  force,                  NULL,                   NULL)                   \
48 t("")                                                                           \
49 t("Device specific options:")                                                   \
50 x(0,    fs_size,                "size",                 "Size of filesystem on device")\
51 x(0,    bucket_size,            "size",                 "Bucket size")          \
52 x('t',  tier,                   "#",                    "Higher tier indicates slower devices")\
53 x(0,    discard,                NULL,                   NULL)                   \
54 t("Device specific options must come before corresponding devices, e.g.")       \
55 t("  bcachefs format --tier 0 /dev/sdb --tier 1 /dev/sdc")                      \
56 t("")                                                                           \
57 x('q',  quiet,                  NULL,                   "Only print errors")    \
58 x('h',  help,                   NULL,                   "Display this help and exit")
59
60 static void usage(void)
61 {
62 #define t(text)                         puts(text "\n")
63 #define x(shortopt, longopt, arg, help) do {                            \
64         OPTS
65 #undef x
66 #undef t
67
68         puts("bcachefs format - create a new bcachefs filesystem on one or more devices\n"
69              "Usage: bcachefs format [OPTION]... <devices>\n"
70              "\n"
71              "Options:\n"
72              "  -b, --block=size\n"
73              "      --btree_node=size       Btree node size, default 256k\n"
74              "      --metadata_checksum_type=(none|crc32c|crc64)\n"
75              "      --data_checksum_type=(none|crc32c|crc64)\n"
76              "      --compression_type=(none|lz4|gzip)\n"
77              "      --data_replicas=#       Number of data replicas\n"
78              "      --metadata_replicas=#   Number of metadata replicas\n"
79              "      --encrypted             Enable whole filesystem encryption (chacha20/poly1305)\n"
80              "      --no_passphrase         Don't encrypt master encryption key\n"
81              "      --error_action=(continue|readonly|panic)\n"
82              "                              Action to take on filesystem error\n"
83              "      --max_journal_entry_size=size\n"
84              "  -l, --label=label\n"
85              "      --uuid=uuid\n"
86              "  -f, --force\n"
87              "\n"
88              "Device specific options:\n"
89              "      --fs_size=size          Size of filesystem on device\n"
90              "      --bucket=size           Bucket size\n"
91              "      --discard               Enable discards\n"
92              "  -t, --tier=#                Higher tier (e.g. 1) indicates slower devices\n"
93              "\n"
94              "  -q, --quiet                 Only print errors\n"
95              "  -h, --help                  Display this help and exit\n"
96              "\n"
97              "Device specific options must come before corresponding devices, e.g.\n"
98              "  bcachefs format --tier 0 /dev/sdb --tier 1 /dev/sdc\n"
99              "\n"
100              "Report bugs to <linux-bcache@vger.kernel.org>");
101 }
102
103 enum {
104         O_no_opt = 1,
105 #define t(text)
106 #define x(shortopt, longopt, arg, help) O_##longopt,
107         OPTS
108 #undef x
109 #undef t
110 };
111
112 static const struct option format_opts[] = {
113 #define t(text)
114 #define x(shortopt, longopt, arg, help) {                               \
115         .name           = #longopt,                                     \
116         .has_arg        = arg ? required_argument : no_argument,        \
117         .flag           = NULL,                                         \
118         .val            = O_##longopt,                                  \
119 },
120         OPTS
121 #undef x
122 #undef t
123         { NULL }
124 };
125
126 int cmd_format(int argc, char *argv[])
127 {
128         darray(struct dev_opts) devices;
129         struct format_opts opts = format_opts_default();
130         struct dev_opts dev_opts = { 0 }, *dev;
131         bool force = false, no_passphrase = false, quiet = false;
132         int opt;
133
134         darray_init(devices);
135
136         while ((opt = getopt_long(argc, argv,
137                                   "-b:e:L:U:ft:qh",
138                                   format_opts,
139                                   NULL)) != -1)
140                 switch (opt) {
141                 case O_block_size:
142                 case 'b':
143                         opts.block_size =
144                                 hatoi_validate(optarg, "block size");
145                         break;
146                 case O_btree_node_size:
147                         opts.btree_node_size =
148                                 hatoi_validate(optarg, "btree node size");
149                         break;
150                 case O_metadata_checksum_type:
151                         opts.meta_csum_type =
152                                 read_string_list_or_die(optarg,
153                                                 bch2_csum_types, "checksum type");
154                         break;
155                 case O_data_checksum_type:
156                         opts.data_csum_type =
157                                 read_string_list_or_die(optarg,
158                                                 bch2_csum_types, "checksum type");
159                         break;
160                 case O_compression_type:
161                         opts.compression_type =
162                                 read_string_list_or_die(optarg,
163                                                 bch2_compression_types,
164                                                 "compression type");
165                         break;
166                 case O_data_replicas:
167                         if (kstrtouint(optarg, 10, &opts.data_replicas) ||
168                             dev_opts.tier >= BCH_REPLICAS_MAX)
169                                 die("invalid replicas");
170                         break;
171                 case O_metadata_replicas:
172                         if (kstrtouint(optarg, 10, &opts.meta_replicas) ||
173                             dev_opts.tier >= BCH_REPLICAS_MAX)
174                                 die("invalid replicas");
175                         break;
176                 case O_encrypted:
177                         opts.encrypted = true;
178                         break;
179                 case O_no_passphrase:
180                         no_passphrase = true;
181                         break;
182                 case O_error_action:
183                 case 'e':
184                         opts.on_error_action =
185                                 read_string_list_or_die(optarg,
186                                                 bch2_error_actions, "error action");
187                         break;
188                 case O_max_journal_entry_size:
189                         opts.max_journal_entry_size =
190                                 hatoi_validate(optarg, "journal entry size");
191                         break;
192                 case O_label:
193                 case 'L':
194                         opts.label = strdup(optarg);
195                         break;
196                 case O_uuid:
197                 case 'U':
198                         if (uuid_parse(optarg, opts.uuid.b))
199                                 die("Bad uuid");
200                         break;
201                 case O_force:
202                 case 'f':
203                         force = true;
204                         break;
205                 case O_fs_size:
206                         if (bch2_strtoull_h(optarg, &dev_opts.size))
207                                 die("invalid filesystem size");
208
209                         dev_opts.size >>= 9;
210                         break;
211                 case O_bucket_size:
212                         dev_opts.bucket_size =
213                                 hatoi_validate(optarg, "bucket size");
214                         break;
215                 case O_tier:
216                 case 't':
217                         if (kstrtouint(optarg, 10, &dev_opts.tier) ||
218                             dev_opts.tier >= BCH_TIER_MAX)
219                                 die("invalid tier");
220                         break;
221                 case O_discard:
222                         dev_opts.discard = true;
223                         break;
224                 case O_no_opt:
225                         dev_opts.path = strdup(optarg);
226                         darray_append(devices, dev_opts);
227                         dev_opts.size = 0;
228                         break;
229                 case O_quiet:
230                 case 'q':
231                         quiet = true;
232                         break;
233                 case O_help:
234                 case 'h':
235                         usage();
236                         exit(EXIT_SUCCESS);
237                         break;
238                 }
239
240         if (!darray_size(devices))
241                 die("Please supply a device");
242
243         if (opts.encrypted && !no_passphrase) {
244                 opts.passphrase = read_passphrase("Enter passphrase: ");
245
246                 if (isatty(STDIN_FILENO)) {
247                         char *pass2 =
248                                 read_passphrase("Enter same passphrase again: ");
249
250                         if (strcmp(opts.passphrase, pass2)) {
251                                 memzero_explicit(opts.passphrase,
252                                                  strlen(opts.passphrase));
253                                 memzero_explicit(pass2, strlen(pass2));
254                                 die("Passphrases do not match");
255                         }
256
257                         memzero_explicit(pass2, strlen(pass2));
258                         free(pass2);
259                 }
260         }
261
262         darray_foreach(dev, devices)
263                 dev->fd = open_for_format(dev->path, force);
264
265         struct bch_sb *sb =
266                 bcache_format(opts, devices.item, darray_size(devices));
267
268         if (!quiet)
269                 bcache_super_print(sb, HUMAN_READABLE);
270         free(sb);
271
272         if (opts.passphrase) {
273                 memzero_explicit(opts.passphrase, strlen(opts.passphrase));
274                 free(opts.passphrase);
275         }
276
277         return 0;
278 }
279
280 int cmd_show_super(int argc, char *argv[])
281 {
282         struct bch_sb *sb;
283
284         if (argc != 2)
285                 die("please supply a single device");
286
287         sb = bcache_super_read(argv[1]);
288         bcache_super_print(sb, HUMAN_READABLE);
289         return 0;
290 }