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