Whamcloud - gitweb
02835cdbed7ce11674768b71c3f94e69f2ffb168
[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  2008 Sun Microsystems, Inc. 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                 vprint("Reading %s\n", MOUNT_DATA_FILE);
135                 fread(mo_ldd, sizeof(*mo_ldd), 1, filep);
136         } else {
137                 verrprint("%s: Unable to read %d.%d config %s.\n",
138                           progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm);
139                 goto out_close;
140         }       
141
142 out_close:
143         fclose(filep);
144
145 out_rmdir:
146         snprintf(cmd, cmdsz, "rm -rf %s", tmpdir);
147         ret2 = run_command(cmd, cmdsz);
148         if (ret2) {
149                 verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2);
150                 /* failure return from run_command() is more important
151                  * than the failure to remove a dir */
152                 if (!ret)
153                         ret = ret2;
154         }
155
156         return ret;
157 }
158
159 #define PARENT_URN "urn:uuid:2bb5bdbf-6c4b-11dc-9b8e-080020a9ed93"
160 #define PARENT_PRODUCT "Lustre"
161
162 static int stclient(char *type, char *arch)
163 {
164
165         char product[64];
166         char *urn = NULL;
167         char cmd[1024];
168         FILE *fp;
169         int i;
170
171         if (strcmp(type, "Client") == 0)
172                 urn = CLIENT_URN;
173         else if (strcmp(type, "MDS") == 0)
174                 urn = MDS_URN;
175         else if (strcmp(type, "MGS") == 0)
176                 urn = MGS_URN;
177         else if (strcmp(type, "OSS") == 0)
178                 urn = OSS_URN;
179
180         snprintf(product, 64, "Lustre %s %d.%d.%d", type, LUSTRE_MAJOR,
181                  LUSTRE_MINOR, LUSTRE_PATCH); 
182
183         /* need to see if the entry exists first */
184         snprintf(cmd, 1024,
185                  "/opt/sun/servicetag/bin/stclient -f -t '%s' ", urn);
186         fp = popen(cmd, "r");
187         if (!fp) {
188                 if (verbose)
189                         fprintf(stderr, "%s: trying to run stclient -f: %s\n",
190                                 progname, strerror(errno));
191                 return 0;
192         }
193
194         i = fread(cmd, 1, sizeof(cmd), fp);
195         if (i) {
196                 cmd[i] = 0;
197                 if (strcmp(cmd, "Record not found\n") != 0) {
198                         /* exists, just return */
199                         pclose(fp);
200                         return 0;
201                 }
202         }
203         pclose(fp);
204
205         snprintf(cmd, 1024, "/opt/sun/servicetag/bin/stclient -a -p '%s' "
206                "-e %d.%d.%d -t '%s' -S mount -F '%s' -P '%s' -m SUN "
207                "-A %s -z global", product, LUSTRE_MAJOR, LUSTRE_MINOR,
208                LUSTRE_PATCH, urn, PARENT_URN, PARENT_PRODUCT, arch);
209
210         return(run_command(cmd, sizeof(cmd)));
211 }
212
213 void register_service_tags(char *usource, char *source, char *target)
214 {
215         struct lustre_disk_data mo_ldd;
216         struct utsname utsname_buf;
217         struct stat stat_buf;
218         char stclient_loc[] = "/opt/sun/servicetag/bin/stclient";
219         int rc;
220
221         rc = stat(stclient_loc, &stat_buf);
222
223         if (rc == 0) {
224                 /* call the service tags stclient to show that we use Lustre on
225                    this system */
226
227                 rc = uname(&utsname_buf);
228                 if (rc) {
229                         if (verbose)
230                                 fprintf(stderr,
231                                         "%s: trying to get uname failed: %s, "
232                                         "inventory tags will not be created\n",
233                                         progname, strerror(errno));
234                 } else {
235
236                         /* client or server? */
237                         if (strchr(usource, ':')) {
238                                 stclient("Client", utsname_buf.machine);
239                         } else {
240                                 /* first figure what type of device it is */
241                                 rc = get_mountdata(source, &mo_ldd);
242                                 if (rc) {
243                                         if (verbose)
244                                                 fprintf(stderr,
245                                                         "%s: trying to read mountdata from %s "
246                                                         "failed: %s, inventory tags will not "
247                                                         "be created\n",
248                                                         progname, target, strerror(errno));
249                                 } else {
250
251                                         if (IS_MDT(&mo_ldd))
252                                                 stclient("MDS", utsname_buf.machine);
253
254                                         if (IS_MGS(&mo_ldd))
255                                                 stclient("MGS", utsname_buf.machine);
256
257                                         if (IS_OST(&mo_ldd))
258                                                 stclient("OSS", utsname_buf.machine);
259                                 }
260                         }
261                 }
262         } else {
263                 if (errno != ENOENT && verbose) {
264                         fprintf(stderr,
265                                 "%s: trying to stat stclient failed: %s\n",
266                                 progname, strerror(errno));
267                 }
268         }
269 }