From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Tue, 14 May 2013 11:45:35 +0100 Subject: [Cluster-devel] [PATCH 4/6] mkfs.gfs2: Use libblkid for checking contents In-Reply-To: <1368528337-4236-1-git-send-email-anprice@redhat.com> References: <1368528337-4236-1-git-send-email-anprice@redhat.com> Message-ID: <1368528337-4236-5-git-send-email-anprice@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Use libblkid to probe the contents of the target device instead of execing 'file'. Signed-off-by: Andrew Price --- gfs2/mkfs/main_mkfs.c | 181 ++++++++++++++------------------------------------ 1 file changed, 51 insertions(+), 130 deletions(-) diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 9949a46..91c89d3 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -20,6 +20,7 @@ #include #include #include +#include #define _(String) gettext(String) @@ -123,6 +124,7 @@ static void opts_init(struct mkfs_opts *opts) opts->rgsize = GFS2_DEFAULT_RGSIZE; opts->lockproto = "lock_dlm"; opts->locktable = ""; + opts->confirm = 1; } #ifndef BLKDISCARD @@ -475,105 +477,6 @@ static void opts_check(struct mkfs_opts *opts) } -static int get_file_output(int fd, char *buffer, size_t buflen) -{ - struct pollfd pf = { .fd = fd, .events = POLLIN|POLLRDHUP }; - int flags; - int pos = 0; - int rv; - - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) - return flags; - - flags |= O_NONBLOCK; - rv = fcntl(fd, F_SETFL, flags); - if (rv < 0) - return rv; - - while (1) { - rv = poll(&pf, 1, 10 * 1000); - if (rv == 0) - break; - if (rv < 0) - return rv; - if (pf.revents & POLLIN) { - rv = read(fd, buffer + pos, - buflen - pos); - if (rv < 0) { - if (errno == EAGAIN) - continue; - return rv; - } - if (rv == 0) - break; - pos += rv; - if (pos >= buflen) - return -1; - buffer[pos] = 0; - continue; - } - if (pf.revents & (POLLRDHUP | POLLHUP | POLLERR)) - break; - } - return 0; -} - -static void check_dev_content(const char *devname) -{ - struct sigaction sa; - char content[1024] = { 0, }; - char * args[] = { - (char *)"/usr/bin/file", - (char *)"-bsL", - (char *)devname, - NULL }; - int p[2] = {-1, -1}; - int ret; - int pid; - - ret = sigaction(SIGCHLD, NULL, &sa); - if (ret) - return; - sa.sa_handler = SIG_IGN; - sa.sa_flags |= (SA_NOCLDSTOP | SA_NOCLDWAIT); - ret = sigaction(SIGCHLD, &sa, NULL); - if (ret) - goto fail; - - ret = pipe(p); - if (ret) - goto fail; - - pid = fork(); - - if (pid < 0) { - close(p[1]); - goto fail; - } - - if (pid) { - close(p[1]); - ret = get_file_output(p[0], content, sizeof(content)); - if (ret) { -fail: - printf( _("Content of file or device unknown (do you have GNU fileutils installed?)\n")); - } else { - if (*content == 0) - goto fail; - printf( _("It appears to contain: %s"), content); - } - if (p[0] >= 0) - close(p[0]); - return; - } - - close(p[0]); - dup2(p[1], STDOUT_FILENO); - close(STDIN_FILENO); - exit(execv(args[0], args)); -} - static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size, struct mkfs_opts *opts, unsigned char uuid[16]) { @@ -594,30 +497,27 @@ static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size, printf("%-27s%s\n", _("UUID:"), str_uuid(uuid)); } -/** - * If path is a symlink, return 1 with *abspath pointing to the absolute path, - * otherwise return 0. Exit on errors. The caller must free the memory pointed - * to by *abspath. - */ -static int is_symlink(const char *path, char **abspath) +static void warn_of_destruction(const char *path) { struct stat lnkstat; + char *abspath = NULL; if (lstat(path, &lnkstat) == -1) { perror(_("Failed to lstat the device")); exit(EXIT_FAILURE); } - if (!S_ISLNK(lnkstat.st_mode)) { - return 0; - } - *abspath = canonicalize_file_name(path); - if (*abspath == NULL) { - perror(_("Could not find the absolute path of the device")); - exit(EXIT_FAILURE); + if (S_ISLNK(lnkstat.st_mode)) { + abspath = canonicalize_file_name(path); + if (abspath == NULL) { + perror(_("Could not find the absolute path of the device")); + exit(EXIT_FAILURE); + } + /* Translators: Example: "/dev/vg/lv is a symbolic link to /dev/dm-2" */ + printf( _("%s is a symbolic link to %s\n"), path, abspath); + path = abspath; } - /* Translators: Example: "/dev/vg/lv is a symbolic link to /dev/dm-2" */ - printf( _("%s is a symbolic link to %s\n"), path, *abspath); - return 1; + printf(_("This will destroy any data on %s\n"), path); + free(abspath); } static int writerg(int fd, const struct rgrp_tree *rgt, const unsigned bsize) @@ -751,6 +651,38 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_ } } +static int probe_contents(int fd) +{ + int ret; + const char *contents; + blkid_probe pr = blkid_new_probe(); + if (pr == NULL || blkid_probe_set_device(pr, fd, 0, 0) != 0 + || blkid_probe_enable_superblocks(pr, TRUE) != 0 + || blkid_probe_enable_partitions(pr, TRUE) != 0) { + fprintf(stderr, _("Failed to create probe\n")); + return -1; + } + + ret = blkid_do_fullprobe(pr); + if (ret == -1) { + fprintf(stderr, _("Failed to probe device\n")); + return -1; + } + + if (ret == 1) + return 0; + + if (!blkid_probe_lookup_value(pr, "TYPE", &contents, NULL)) { + printf(_("It appears to contain an existing filesystem (%s)\n"), contents); + } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &contents, NULL)) { + printf(_("It appears to contain a partition table (%s).\n"), contents); + } + + blkid_free_probe(pr); + + return 0; +} + void main_mkfs(int argc, char *argv[]) { struct gfs2_sbd sbd; @@ -758,9 +690,6 @@ void main_mkfs(int argc, char *argv[]) struct lgfs2_dev_info dinfo; int error; unsigned char uuid[16]; - char *absname = NULL; - char *fdpath = NULL; - int islnk = 0; int fd; opts_init(&opts); @@ -783,21 +712,13 @@ void main_mkfs(int argc, char *argv[]) } opts_check(&opts); - sbd_init(&sbd, &opts, &dinfo, fd); + warn_of_destruction(opts.device); - if (asprintf(&fdpath, "/proc/%d/fd/%d", getpid(), fd) < 0) { - perror(_("Failed to build string")); + error = probe_contents(fd); + if (error) exit(EXIT_FAILURE); - } - if (!opts.override) { - islnk = is_symlink(opts.device, &absname); - printf(_("This will destroy any data on %s.\n"), islnk ? absname : opts.device); - free(absname); - check_dev_content(fdpath); - opts.confirm = 1; - } - free(fdpath); + sbd_init(&sbd, &opts, &dinfo, fd); if (opts.confirm && !opts.override) are_you_sure(); -- 1.8.1.4