]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_format.c
format: document -U (used by many mkfs.*)
[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 "libbcachefs/opts.h"
28 #include "libbcachefs/super-io.h"
29 #include "libbcachefs/util.h"
30
31 #define OPTS                                                                    \
32 t("bcachefs format - create a new bcachefs filesystem on one or more devices")  \
33 t("Usage: bcachefs format [OPTION]... <devices>")                                       \
34 t("")                                                                           \
35 x('b',  block_size,             "size",                 NULL)                   \
36 x(0,    btree_node_size,        "size",                 "Default 256k")         \
37 x(0,    metadata_checksum_type, "(none|crc32c|crc64)",  NULL)                   \
38 x(0,    data_checksum_type,     "(none|crc32c|crc64)",  NULL)                   \
39 x(0,    compression_type,       "(none|lz4|gzip)",      NULL)                   \
40 x(0,    replicas,               "#",                    NULL)                   \
41 x(0,    data_replicas,          "#",                    NULL)                   \
42 x(0,    metadata_replicas,      "#",                    NULL)                   \
43 x(0,    encrypted,              NULL,                   "Enable whole filesystem encryption (chacha20/poly1305)")\
44 x(0,    no_passphrase,          NULL,                   "Don't encrypt master encryption key")\
45 x('e',  error_action,           "(continue|readonly|panic)", NULL)              \
46 x('L',  label,                  "label",                NULL)                   \
47 x('U',  uuid,                   "uuid",                 NULL)                   \
48 x('f',  force,                  NULL,                   NULL)                   \
49 t("")                                                                           \
50 t("Device specific options:")                                                   \
51 x(0,    fs_size,                "size",                 "Size of filesystem on device")\
52 x(0,    bucket_size,            "size",                 "Bucket size")          \
53 x('t',  tier,                   "#",                    "Higher tier indicates slower devices")\
54 x(0,    discard,                NULL,                   NULL)                   \
55 x(0,    data_allowed,           "journal,btree,data",   "Allowed types of data on this device")\
56 t("Device specific options must come before corresponding devices, e.g.")       \
57 t("  bcachefs format --tier 0 /dev/sdb --tier 1 /dev/sdc")                      \
58 t("")                                                                           \
59 x('q',  quiet,                  NULL,                   "Only print errors")    \
60 x('h',  help,                   NULL,                   "Display this help and exit")
61
62 static void usage(void)
63 {
64 #define t(text)                         puts(text "\n")
65 #define x(shortopt, longopt, arg, help) do {                            \
66         OPTS
67 #undef x
68 #undef t
69
70         puts("bcachefs format - create a new bcachefs filesystem on one or more devices\n"
71              "Usage: bcachefs format [OPTION]... <devices>\n"
72              "\n"
73              "Options:\n"
74              "  -b, --block=size\n"
75              "      --btree_node=size       Btree node size, default 256k\n"
76              "      --metadata_checksum_type=(none|crc32c|crc64)\n"
77              "      --data_checksum_type=(none|crc32c|crc64)\n"
78              "      --compression_type=(none|lz4|gzip)\n"
79              "      --data_replicas=#       Number of data replicas\n"
80              "      --metadata_replicas=#   Number of metadata replicas\n"
81              "      --replicas=#            Sets both data and metadata replicas\n"
82              "      --encrypted             Enable whole filesystem encryption (chacha20/poly1305)\n"
83              "      --no_passphrase         Don't encrypt master encryption key\n"
84              "      --error_action=(continue|readonly|panic)\n"
85              "                              Action to take on filesystem error\n"
86              "  -L, --label=label\n"
87              "  -U, --uuid=uuid\n"
88              "  -f, --force\n"
89              "\n"
90              "Device specific options:\n"
91              "      --fs_size=size          Size of filesystem on device\n"
92              "      --bucket=size           Bucket size\n"
93              "      --discard               Enable discards\n"
94              "  -t, --tier=#                Higher tier (e.g. 1) indicates slower devices\n"
95              "\n"
96              "  -q, --quiet                 Only print errors\n"
97              "  -h, --help                  Display this help and exit\n"
98              "\n"
99              "Device specific options must come before corresponding devices, e.g.\n"
100              "  bcachefs format --tier 0 /dev/sdb --tier 1 /dev/sdc\n"
101              "\n"
102              "Report bugs to <linux-bcache@vger.kernel.org>");
103 }
104
105 enum {
106         O_no_opt = 1,
107 #define t(text)
108 #define x(shortopt, longopt, arg, help) O_##longopt,
109         OPTS
110 #undef x
111 #undef t
112 };
113
114 static const struct option format_opts[] = {
115 #define t(text)
116 #define x(shortopt, longopt, arg, help) {                               \
117         .name           = #longopt,                                     \
118         .has_arg        = arg ? required_argument : no_argument,        \
119         .flag           = NULL,                                         \
120         .val            = O_##longopt,                                  \
121 },
122         OPTS
123 #undef x
124 #undef t
125         { NULL }
126 };
127
128 u64 read_flag_list_or_die(char *opt, const char * const list[],
129                           const char *msg)
130 {
131         u64 v = bch2_read_flag_list(opt, list);
132         if (v == (u64) -1)
133                 die("Bad %s %s", msg, opt);
134
135         return v;
136 }
137
138 int cmd_format(int argc, char *argv[])
139 {
140         darray(struct dev_opts) devices;
141         struct format_opts opts = format_opts_default();
142         struct dev_opts dev_opts = dev_opts_default(), *dev;
143         bool force = false, no_passphrase = false, quiet = false;
144         int opt;
145
146         darray_init(devices);
147
148         while ((opt = getopt_long(argc, argv,
149                                   "-b:e:L:U:ft:qh",
150                                   format_opts,
151                                   NULL)) != -1)
152                 switch (opt) {
153                 case O_block_size:
154                 case 'b':
155                         opts.block_size =
156                                 hatoi_validate(optarg, "block size");
157                         break;
158                 case O_btree_node_size:
159                         opts.btree_node_size =
160                                 hatoi_validate(optarg, "btree node size");
161                         break;
162                 case O_metadata_checksum_type:
163                         opts.meta_csum_type =
164                                 read_string_list_or_die(optarg,
165                                                 bch2_csum_types, "checksum type");
166                         break;
167                 case O_data_checksum_type:
168                         opts.data_csum_type =
169                                 read_string_list_or_die(optarg,
170                                                 bch2_csum_types, "checksum type");
171                         break;
172                 case O_compression_type:
173                         opts.compression_type =
174                                 read_string_list_or_die(optarg,
175                                                 bch2_compression_types,
176                                                 "compression type");
177                         break;
178                 case O_data_replicas:
179                         if (kstrtouint(optarg, 10, &opts.data_replicas) ||
180                             opts.data_replicas >= BCH_REPLICAS_MAX)
181                                 die("invalid replicas");
182                         break;
183                 case O_metadata_replicas:
184                         if (kstrtouint(optarg, 10, &opts.meta_replicas) ||
185                             opts.meta_replicas >= BCH_REPLICAS_MAX)
186                                 die("invalid replicas");
187                         break;
188                 case O_replicas:
189                         if (kstrtouint(optarg, 10, &opts.data_replicas) ||
190                             opts.data_replicas >= BCH_REPLICAS_MAX)
191                                 die("invalid replicas");
192                         opts.meta_replicas = opts.data_replicas;
193                         break;
194                 case O_encrypted:
195                         opts.encrypted = true;
196                         break;
197                 case O_no_passphrase:
198                         no_passphrase = true;
199                         break;
200                 case O_error_action:
201                 case 'e':
202                         opts.on_error_action =
203                                 read_string_list_or_die(optarg,
204                                                 bch2_error_actions, "error action");
205                         break;
206                 case O_label:
207                 case 'L':
208                         opts.label = strdup(optarg);
209                         break;
210                 case O_uuid:
211                 case 'U':
212                         if (uuid_parse(optarg, opts.uuid.b))
213                                 die("Bad uuid");
214                         break;
215                 case O_force:
216                 case 'f':
217                         force = true;
218                         break;
219                 case O_fs_size:
220                         if (bch2_strtoull_h(optarg, &dev_opts.size))
221                                 die("invalid filesystem size");
222
223                         dev_opts.size >>= 9;
224                         break;
225                 case O_bucket_size:
226                         dev_opts.bucket_size =
227                                 hatoi_validate(optarg, "bucket size");
228                         break;
229                 case O_tier:
230                 case 't':
231                         if (kstrtouint(optarg, 10, &dev_opts.tier) ||
232                             dev_opts.tier >= BCH_TIER_MAX)
233                                 die("invalid tier");
234                         break;
235                 case O_discard:
236                         dev_opts.discard = true;
237                         break;
238                 case O_data_allowed:
239                         dev_opts.data_allowed =
240                                 read_flag_list_or_die(optarg,
241                                         bch2_data_types, "data type");
242                         break;
243                 case O_no_opt:
244                         dev_opts.path = strdup(optarg);
245                         darray_append(devices, dev_opts);
246                         dev_opts.size = 0;
247                         break;
248                 case O_quiet:
249                 case 'q':
250                         quiet = true;
251                         break;
252                 case O_help:
253                 case 'h':
254                         usage();
255                         exit(EXIT_SUCCESS);
256                         break;
257                 }
258
259         if (!darray_size(devices))
260                 die("Please supply a device");
261
262         if (opts.encrypted && !no_passphrase)
263                 opts.passphrase = read_passphrase_twice("Enter passphrase: ");
264
265         darray_foreach(dev, devices)
266                 dev->fd = open_for_format(dev->path, force);
267
268         struct bch_sb *sb =
269                 bch2_format(opts, devices.item, darray_size(devices));
270
271         if (!quiet)
272                 bch2_sb_print(sb, false, 1 << BCH_SB_FIELD_members, HUMAN_READABLE);
273         free(sb);
274
275         if (opts.passphrase) {
276                 memzero_explicit(opts.passphrase, strlen(opts.passphrase));
277                 free(opts.passphrase);
278         }
279
280         return 0;
281 }
282
283 static void show_super_usage(void)
284 {
285         puts("bcachefs show-super \n"
286              "Usage: bcachefs show-super [OPTION].. device\n"
287              "\n"
288              "Options:\n"
289              "  -f, --fields=(fields)       list of sections to print\n"
290              "  -l, --layout                print superblock layout\n"
291              "  -h, --help                  display this help and exit\n"
292              "Report bugs to <linux-bcache@vger.kernel.org>");
293         exit(EXIT_SUCCESS);
294 }
295
296 int cmd_show_super(int argc, char *argv[])
297 {
298         static const struct option longopts[] = {
299                 { "fields",                     1, NULL, 'f' },
300                 { "layout",                     0, NULL, 'l' },
301                 { "help",                       0, NULL, 'h' },
302                 { NULL }
303         };
304         unsigned fields = 1 << BCH_SB_FIELD_members;
305         bool print_layout = false;
306         int opt;
307
308         while ((opt = getopt_long(argc, argv, "f:lh", longopts, NULL)) != -1)
309                 switch (opt) {
310                 case 'f':
311                         fields = !strcmp(optarg, "all")
312                                 ? ~0
313                                 : read_flag_list_or_die(optarg,
314                                         bch2_sb_fields, "superblock field");
315                         break;
316                 case 'l':
317                         print_layout = true;
318                         break;
319                 case 'h':
320                         show_super_usage();
321                         break;
322                 }
323         args_shift(optind);
324
325         char *dev = arg_pop();
326         if (!dev)
327                 die("please supply a device");
328         if (argc)
329                 die("too many arguments");
330
331         struct bch_opts opts = bch2_opts_empty();
332
333         opt_set(opts, noexcl,   true);
334         opt_set(opts, nochanges, true);
335
336         struct bch_sb_handle sb;
337         int ret = bch2_read_super(dev, &opts, &sb);
338         if (ret)
339                 die("Error opening %s: %s", dev, strerror(-ret));
340
341         bch2_sb_print(sb.sb, print_layout, fields, HUMAN_READABLE);
342         bch2_free_super(&sb);
343         return 0;
344 }