Whamcloud - gitweb
LU-867 gss: adapt to 2.6.32 kernel changes cache_detail
[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  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #if HAVE_CONFIG_H
38 #  include "config.h"
39 #endif /* HAVE_CONFIG_H */
40
41 #include <stdio.h>
42 #include <errno.h>
43 #include <string.h>
44 #include <config.h>
45 #include <lustre_disk.h>
46 #include <lustre_ver.h>
47 #include <sys/stat.h>
48 #include <sys/utsname.h>
49
50 extern char *progname;
51 extern int verbose;
52
53 #define vprint(fmt, arg...) if (verbose > 0) printf(fmt, ##arg)
54 #define verrprint(fmt, arg...) if (verbose >= 0) fprintf(stderr, fmt, ##arg)
55
56 void fatal(void)
57 {
58         verbose = 0;
59         fprintf(stderr, "\n%s FATAL: ", progname);
60 }
61
62 int run_command(char *cmd, int cmdsz)
63 {
64         char log[] = "/tmp/run_command_logXXXXXX";
65         int fd = -1, rc;
66
67         if ((cmdsz - strlen(cmd)) < 6) {
68                 fatal();
69                 fprintf(stderr, "Command buffer overflow: %.*s...\n",
70                         cmdsz, cmd);
71                 return ENOMEM;
72         }
73
74         if (verbose > 1) {
75                 printf("cmd: %s\n", cmd);
76         } else {
77                 if ((fd = mkstemp(log)) >= 0) {
78                         close(fd);
79                         strcat(cmd, " >");
80                         strcat(cmd, log);
81                 }
82         }
83         strcat(cmd, " 2>&1");
84
85         /* Can't use popen because we need the rv of the command */
86         rc = system(cmd);
87         if (rc && (fd >= 0)) {
88                 char buf[128];
89                 FILE *fp;
90                 fp = fopen(log, "r");
91                 if (fp) {
92                         while (fgets(buf, sizeof(buf), fp) != NULL) {
93                                 printf("   %s", buf);
94                         }
95                         fclose(fp);
96                 }
97         }
98         if (fd >= 0)
99                 remove(log);
100         return rc;
101 }
102
103 int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd)
104 {
105
106         char tmpdir[] = "/tmp/lustre_tmp.XXXXXX";
107         char cmd[256];
108         char filepnm[128];
109         FILE *filep;
110         int ret = 0;
111         int ret2 = 0;
112         int cmdsz = sizeof(cmd);
113
114         /* Make a temporary directory to hold Lustre data files. */
115         if (!mkdtemp(tmpdir)) {
116                 verrprint("%s: Can't create temporary directory %s: %s\n",
117                         progname, tmpdir, strerror(errno));
118                 return errno;
119         }
120
121         snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' %s",
122                  DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev);
123
124         ret = run_command(cmd, cmdsz);
125         if (ret) {
126                 verrprint("%s: Unable to dump %s dir (%d)\n",
127                           progname, MOUNT_CONFIGS_DIR, ret);
128                 goto out_rmdir;
129         }
130
131         sprintf(filepnm, "%s/mountdata", tmpdir);
132         filep = fopen(filepnm, "r");
133         if (filep) {
134                 size_t num_read;
135                 vprint("Reading %s\n", MOUNT_DATA_FILE);
136                 num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep);
137                 if (num_read < 1 && ferror(filep)) {
138                         fprintf(stderr, "%s: Unable to read from file (%s): %s\n",
139                                 progname, filepnm, strerror(errno));
140                         goto out_close;
141                 }
142         } else {
143                 verrprint("%s: Unable to read %d.%d config %s.\n",
144                           progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm);
145                 ret = 1;
146                 goto out_rmdir;
147         }
148
149 out_close:
150         fclose(filep);
151
152 out_rmdir:
153         snprintf(cmd, cmdsz, "rm -rf %s", tmpdir);
154         ret2 = run_command(cmd, cmdsz);
155         if (ret2) {
156                 verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2);
157                 /* failure return from run_command() is more important
158                  * than the failure to remove a dir */
159                 if (!ret)
160                         ret = ret2;
161         }
162
163         return ret;
164 }
165
166 #define PARENT_URN "urn:uuid:2bb5bdbf-6c4b-11dc-9b8e-080020a9ed93"
167 #define PARENT_PRODUCT "Lustre"
168
169 static int stclient(char *type, char *arch)
170 {
171
172         char product[64];
173         char *urn = NULL;
174         char cmd[1024];
175         FILE *fp;
176         int i;
177
178         if (strcmp(type, "Client") == 0)
179                 urn = CLIENT_URN;
180         else if (strcmp(type, "MDS") == 0)
181                 urn = MDS_URN;
182         else if (strcmp(type, "MGS") == 0)
183                 urn = MGS_URN;
184         else if (strcmp(type, "OSS") == 0)
185                 urn = OSS_URN;
186
187         snprintf(product, 64, "Lustre %s %d.%d.%d", type, LUSTRE_MAJOR,
188                  LUSTRE_MINOR, LUSTRE_PATCH);
189
190         /* need to see if the entry exists first */
191         snprintf(cmd, 1024,
192                  "/opt/sun/servicetag/bin/stclient -f -t '%s' ", urn);
193         fp = popen(cmd, "r");
194         if (!fp) {
195                 if (verbose)
196                         fprintf(stderr, "%s: trying to run stclient -f: %s\n",
197                                 progname, strerror(errno));
198                 return 0;
199         }
200
201         i = fread(cmd, 1, sizeof(cmd), fp);
202         if (i) {
203                 cmd[i] = 0;
204                 if (strcmp(cmd, "Record not found\n") != 0) {
205                         /* exists, just return */
206                         pclose(fp);
207                         return 0;
208                 }
209         }
210         pclose(fp);
211
212         snprintf(cmd, 1024, "/opt/sun/servicetag/bin/stclient -a -p '%s' "
213                  "-e %d.%d.%d -t '%s' -S mount -F '%s' -P '%s' -m SUN "
214                  "-A %s -z global", product, LUSTRE_MAJOR, LUSTRE_MINOR,
215                  LUSTRE_PATCH, urn, PARENT_URN, PARENT_PRODUCT, arch);
216
217         return(run_command(cmd, sizeof(cmd)));
218 }
219
220 void register_service_tags(char *usource, char *source, char *target)
221 {
222         struct lustre_disk_data mo_ldd;
223         struct utsname utsname_buf;
224         struct stat stat_buf;
225         char stclient_loc[] = "/opt/sun/servicetag/bin/stclient";
226         int rc;
227
228         rc = stat(stclient_loc, &stat_buf);
229
230         if (rc) {
231                 if (errno != ENOENT && verbose) {
232                         fprintf(stderr,
233                                 "%s: trying to stat stclient failed: %s\n",
234                                 progname, strerror(errno));
235                 }
236
237                 return;
238         }
239
240         /* call service tags stclient to show Lustre is in use on this system */
241         rc = uname(&utsname_buf);
242         if (rc) {
243                 if (verbose)
244                         fprintf(stderr,
245                                 "%s: trying to get uname failed: %s, "
246                                 "inventory tags will not be created\n",
247                                 progname, strerror(errno));
248                 return;
249         }
250
251         /* client or server? */
252         if (strchr(usource, ':')) {
253                 stclient("Client", utsname_buf.machine);
254         } else {
255                 /* first figure what type of device it is */
256                 rc = get_mountdata(source, &mo_ldd);
257                 if (rc) {
258                         if (verbose)
259                                 fprintf(stderr,
260                                         "%s: trying to read mountdata from %s "
261                                         "failed: %s, inventory tags will not "
262                                         "be created\n",
263                                         progname, target, strerror(errno));
264                         return;
265                 }
266
267                 if (IS_MDT(&mo_ldd))
268                         stclient("MDS", utsname_buf.machine);
269
270                 if (IS_MGS(&mo_ldd))
271                         stclient("MGS", utsname_buf.machine);
272
273                 if (IS_OST(&mo_ldd))
274                         stclient("OSS", utsname_buf.machine);
275         }
276 }