/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 only, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is included * in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. * * GPL HEADER END */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * Copyright (c) 2012 Whamcloud, Inc. */ /* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. */ #if HAVE_CONFIG_H # include "config.h" #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include extern char *progname; extern int verbose; #define vprint(fmt, arg...) if (verbose > 0) printf(fmt, ##arg) #define verrprint(fmt, arg...) if (verbose >= 0) fprintf(stderr, fmt, ##arg) void fatal(void) { verbose = 0; fprintf(stderr, "\n%s FATAL: ", progname); } int run_command(char *cmd, int cmdsz) { char log[] = "/tmp/run_command_logXXXXXX"; int fd = -1, rc; if ((cmdsz - strlen(cmd)) < 6) { fatal(); fprintf(stderr, "Command buffer overflow: %.*s...\n", cmdsz, cmd); return ENOMEM; } if (verbose > 1) { printf("cmd: %s\n", cmd); } else { if ((fd = mkstemp(log)) >= 0) { close(fd); strcat(cmd, " >"); strcat(cmd, log); } } strcat(cmd, " 2>&1"); /* Can't use popen because we need the rv of the command */ rc = system(cmd); if (rc && (fd >= 0)) { char buf[128]; FILE *fp; fp = fopen(log, "r"); if (fp) { while (fgets(buf, sizeof(buf), fp) != NULL) { printf(" %s", buf); } fclose(fp); } } if (fd >= 0) remove(log); return rc; } int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd) { char tmpdir[] = "/tmp/lustre_tmp.XXXXXX"; char cmd[256]; char filepnm[128]; FILE *filep; int ret = 0; int ret2 = 0; int cmdsz = sizeof(cmd); /* Make a temporary directory to hold Lustre data files. */ if (!mkdtemp(tmpdir)) { verrprint("%s: Can't create temporary directory %s: %s\n", progname, tmpdir, strerror(errno)); return errno; } snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' %s", DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev); ret = run_command(cmd, cmdsz); if (ret) { verrprint("%s: Unable to dump %s dir (%d)\n", progname, MOUNT_CONFIGS_DIR, ret); goto out_rmdir; } sprintf(filepnm, "%s/mountdata", tmpdir); filep = fopen(filepnm, "r"); if (filep) { size_t num_read; vprint("Reading %s\n", MOUNT_DATA_FILE); num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep); if (num_read < 1 && ferror(filep)) { fprintf(stderr, "%s: Unable to read from file (%s): %s\n", progname, filepnm, strerror(errno)); goto out_close; } } else { verrprint("%s: Unable to read %d.%d config %s.\n", progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm); ret = 1; goto out_rmdir; } out_close: fclose(filep); out_rmdir: snprintf(cmd, cmdsz, "rm -rf %s", tmpdir); ret2 = run_command(cmd, cmdsz); if (ret2) { verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2); /* failure return from run_command() is more important * than the failure to remove a dir */ if (!ret) ret = ret2; } return ret; }