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