Whamcloud - gitweb
f89d5c5940759e181889308c3a8e65c465ae07db
[fs/lustre-release.git] / lustre / utils / mount_utils.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  * Copyright (c) 2012 Whamcloud, Inc.
30  */
31 /*
32  * This file is part of Lustre, http://www.lustre.org/
33  * Lustre is a trademark of Sun Microsystems, Inc.
34  */
35
36 #if HAVE_CONFIG_H
37 #  include "config.h"
38 #endif /* HAVE_CONFIG_H */
39
40 #include <stdio.h>
41 #include <errno.h>
42 #include <string.h>
43 #include <config.h>
44 #include <lustre_disk.h>
45 #include <lustre_ver.h>
46 #include <sys/stat.h>
47 #include <sys/utsname.h>
48
49 extern char *progname;
50 extern int verbose;
51
52 #define vprint(fmt, arg...) if (verbose > 0) printf(fmt, ##arg)
53 #define verrprint(fmt, arg...) if (verbose >= 0) fprintf(stderr, fmt, ##arg)
54
55 void fatal(void)
56 {
57         verbose = 0;
58         fprintf(stderr, "\n%s FATAL: ", progname);
59 }
60
61 int run_command(char *cmd, int cmdsz)
62 {
63         char log[] = "/tmp/run_command_logXXXXXX";
64         int fd = -1, rc;
65
66         if ((cmdsz - strlen(cmd)) < 6) {
67                 fatal();
68                 fprintf(stderr, "Command buffer overflow: %.*s...\n",
69                         cmdsz, cmd);
70                 return ENOMEM;
71         }
72
73         if (verbose > 1) {
74                 printf("cmd: %s\n", cmd);
75         } else {
76                 if ((fd = mkstemp(log)) >= 0) {
77                         close(fd);
78                         strcat(cmd, " >");
79                         strcat(cmd, log);
80                 }
81         }
82         strcat(cmd, " 2>&1");
83
84         /* Can't use popen because we need the rv of the command */
85         rc = system(cmd);
86         if (rc && (fd >= 0)) {
87                 char buf[128];
88                 FILE *fp;
89                 fp = fopen(log, "r");
90                 if (fp) {
91                         while (fgets(buf, sizeof(buf), fp) != NULL) {
92                                 printf("   %s", buf);
93                         }
94                         fclose(fp);
95                 }
96         }
97         if (fd >= 0)
98                 remove(log);
99         return rc;
100 }
101
102 int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd)
103 {
104
105         char tmpdir[] = "/tmp/lustre_tmp.XXXXXX";
106         char cmd[256];
107         char filepnm[128];
108         FILE *filep;
109         int ret = 0;
110         int ret2 = 0;
111         int cmdsz = sizeof(cmd);
112
113         /* Make a temporary directory to hold Lustre data files. */
114         if (!mkdtemp(tmpdir)) {
115                 verrprint("%s: Can't create temporary directory %s: %s\n",
116                         progname, tmpdir, strerror(errno));
117                 return errno;
118         }
119
120         snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' %s",
121                  DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev);
122
123         ret = run_command(cmd, cmdsz);
124         if (ret) {
125                 verrprint("%s: Unable to dump %s dir (%d)\n",
126                           progname, MOUNT_CONFIGS_DIR, ret);
127                 goto out_rmdir;
128         }
129
130         sprintf(filepnm, "%s/mountdata", tmpdir);
131         filep = fopen(filepnm, "r");
132         if (filep) {
133                 size_t num_read;
134                 vprint("Reading %s\n", MOUNT_DATA_FILE);
135                 num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep);
136                 if (num_read < 1 && ferror(filep)) {
137                         fprintf(stderr, "%s: Unable to read from file (%s): %s\n",
138                                 progname, filepnm, strerror(errno));
139                         goto out_close;
140                 }
141         } else {
142                 verrprint("%s: Unable to read %d.%d config %s.\n",
143                           progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm);
144                 ret = 1;
145                 goto out_rmdir;
146         }
147
148 out_close:
149         fclose(filep);
150
151 out_rmdir:
152         snprintf(cmd, cmdsz, "rm -rf %s", tmpdir);
153         ret2 = run_command(cmd, cmdsz);
154         if (ret2) {
155                 verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2);
156                 /* failure return from run_command() is more important
157                  * than the failure to remove a dir */
158                 if (!ret)
159                         ret = ret2;
160         }
161
162         return ret;
163 }