diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-09 09:13:45 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-09 09:26:56 -0900 |
commit | 07ddcf0bef7ea7dfe4885b29d1c727ae32a29dcf (patch) | |
tree | b5c85dc294e7b0f07bb7d6833b9cdd043f91dee2 /tools-util.c | |
parent | ac1b32acb4ca8c59c0e4911a8d3b27fd72dc54af (diff) | |
download | bcachefs-tools-07ddcf0bef7ea7dfe4885b29d1c727ae32a29dcf.tar.gz |
cmd_device_add improvements
Diffstat (limited to 'tools-util.c')
-rw-r--r-- | tools-util.c | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/tools-util.c b/tools-util.c index 07fb82d1..bb2ac47c 100644 --- a/tools-util.c +++ b/tools-util.c @@ -13,6 +13,7 @@ #include <sys/types.h> #include <unistd.h> +#include <blkid.h> #include <uuid/uuid.h> #include "ccan/crc/crc.h" @@ -60,11 +61,13 @@ struct units_buf __pr_units(u64 v, enum units units) char *read_file_str(int dirfd, const char *path) { int fd = xopenat(dirfd, path, O_RDONLY); - size_t len = xfstat(fd).st_size; + ssize_t len = xfstat(fd).st_size; - char *buf = malloc(len + 1); + char *buf = xmalloc(len + 1); - xpread(fd, buf, len, 0); + len = read(fd, buf, len); + if (len < 0) + die("read error: %s", strerror(errno)); buf[len] = '\0'; if (len && buf[len - 1] == '\n') @@ -78,10 +81,11 @@ char *read_file_str(int dirfd, const char *path) u64 read_file_u64(int dirfd, const char *path) { char *buf = read_file_str(dirfd, path); - u64 ret = strtoll(buf, NULL, 10); - + u64 v; + if (kstrtou64(buf, 10, &v)) + die("read_file_u64: error parsing %s (got %s)", path, buf); free(buf); - return ret; + return v; } /* String list options: */ @@ -122,6 +126,46 @@ unsigned get_blocksize(const char *path, int fd) return ret >> 9; } +/* Open a block device, do magic blkid stuff to probe for existing filesystems: */ +int open_for_format(const char *dev, bool force) +{ + blkid_probe pr; + const char *fs_type = NULL, *fs_label = NULL; + size_t fs_type_len, fs_label_len; + + int fd = xopen(dev, O_RDWR|O_EXCL); + + if (force) + return fd; + + if (!(pr = blkid_new_probe())) + die("blkid error 1"); + if (blkid_probe_set_device(pr, fd, 0, 0)) + die("blkid error 2"); + if (blkid_probe_enable_partitions(pr, true)) + die("blkid error 3"); + if (blkid_do_fullprobe(pr) < 0) + die("blkid error 4"); + + blkid_probe_lookup_value(pr, "TYPE", &fs_type, &fs_type_len); + blkid_probe_lookup_value(pr, "LABEL", &fs_label, &fs_label_len); + + if (fs_type) { + if (fs_label) + printf("%s contains a %s filesystem labelled '%s'\n", + dev, fs_type, fs_label); + else + printf("%s contains a %s filesystem\n", + dev, fs_type); + fputs("Proceed anyway?", stdout); + if (!ask_yn()) + exit(EXIT_FAILURE); + } + + blkid_free_probe(pr); + return fd; +} + /* Global control device: */ int bcachectl_open(void) { @@ -270,3 +314,24 @@ const char *strcmp_prefix(const char *a, const char *a_prefix) } return *a_prefix ? NULL : a; } + +unsigned hatoi_validate(const char *s, const char *msg) +{ + u64 v; + + if (bch_strtoull_h(s, &v)) + die("bad %s %s", msg, s); + + if (v & (v - 1)) + die("%s must be a power of two", msg); + + v /= 512; + + if (v > USHRT_MAX) + die("%s too large\n", msg); + + if (!v) + die("%s too small\n", msg); + + return v; +} |