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