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