Whamcloud - gitweb
LU-9934 build: address issues raised by gcc7
[fs/lustre-release.git] / lustre / utils / lshowmount.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  *
29  * lustre/utils/lshowmount.h
30  *
31  * Author: Herb Wartens <wartens2@llnl.gov>
32  * Author: Jim Garlick <garlick@llnl.gov>
33  */
34
35 #ifndef _GNU_SOURCE
36 #define _GNU_SOURCE
37 #endif
38
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <getopt.h>
43 #include <dirent.h>
44 #include <string.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <arpa/inet.h>
48 #include <netdb.h>
49 #include <errno.h>
50 #include <libgen.h>
51
52 #include <linux/lustre/lustre_user.h>
53 #include "nidlist.h"
54 #include "lustreapi_internal.h"
55
56 #define PROC_UUID_TMPL          "%s/%s/uuid"
57
58 static void print_nids(NIDList nidlist, int lookup, int enumerate, int indent);
59 static int lshowmount(int lookup, int enumerate, int verbose);
60 static void read_exports(char *exports, NIDList nidlist);
61
62 char *prog;
63
64 #define OPTIONS "ehlv"
65 static struct option long_opts[] = {
66         { .val = 'e',   .name = "enumerate",    .has_arg = no_argument },
67         { .val = 'h',   .name = "help",         .has_arg = no_argument },
68         { .val = 'l',   .name = "lookup",       .has_arg = no_argument },
69         { .val = 'v',   .name = "verbose",      .has_arg = no_argument },
70         { .name = NULL } };
71
72 static void usage(void)
73 {
74         fprintf(stderr, "usage: %s [-e] [-h] [-l] [-v]\n", prog);
75         exit(1);
76 }
77
78 int main(int argc, char **argv)
79 {
80         int opt, optidx = 0;
81         int lopt = 0;
82         int vopt = 0;
83         int eopt = 0;
84
85         prog = basename(argv[0]);
86
87         while ((opt = getopt_long(argc, argv, OPTIONS, long_opts,
88                                   &optidx)) != -1) {
89                 switch (opt) {
90                 case 'e':       /* --enumerate */
91                         eopt = 1;
92                         break;
93                 case 'l':       /* --lookup */
94                         lopt = 1;
95                         break;
96                 case 'v':       /* --verbose */
97                         vopt = 1;
98                         break;
99                 case 'h':       /* --help */
100                 default:
101                         usage();
102                 }
103         }
104
105         if (lshowmount(lopt, eopt, vopt) == 0) {
106                 fprintf(stderr, "%s: lustre server modules not loaded\n", prog);
107                 exit(1);
108         }
109         exit(0);
110 }
111
112
113 static void print_expname(const char *path)
114 {
115         char *hp, buf[PATH_MAX + 1];
116
117         strncpy(buf, path, PATH_MAX);
118         buf[PATH_MAX] = '\0';
119         hp = strstr(buf, "exports");
120         if (hp && hp > buf) {
121                 *(--hp) = '\0';
122                 for (; *hp == '/' && hp > buf; hp--)
123                         ;
124                 for (; *hp != '/' && hp > buf; hp--)
125                         ;
126                 printf("%s:\n", hp + 1);
127         }
128 }
129
130 static void print_nids(NIDList nidlist, int lookup, int enumerate, int indent)
131 {
132         char *s, *sep = "\n", *pfx = "";
133
134         if (lookup)
135                 nl_lookup_ip(nidlist);
136         nl_sort(nidlist);
137         nl_uniq(nidlist);
138         if (nl_count(nidlist) > 0) {
139                 if (indent) {
140                         sep = "\n    ";
141                         pfx = "    ";
142                 }
143                 if (enumerate)
144                         s = nl_string(nidlist, sep);
145                 else
146                         s = nl_xstring(nidlist, sep);
147                 printf("%s%s\n", pfx, s);
148                 free(s);
149         }
150 }
151
152 static int lshowmount(int lookup, int enumerate, int verbose)
153 {
154         NIDList nidlist = NULL;
155         glob_t exp_list;
156         int i;
157
158         i = get_lustre_param_path("{mgs,mdt,obdfilter}", "*",
159                                    FILTER_BY_EXACT, "exports", &exp_list);
160         if (i < 0)
161                 return i;
162         if (!verbose)
163                 nidlist = nl_create();
164         for (i = 0; i < exp_list.gl_pathc; i++) {
165                 if (verbose) {
166                         nidlist = nl_create();
167                         read_exports(exp_list.gl_pathv[i], nidlist);
168                         print_expname(exp_list.gl_pathv[i]);
169                         print_nids(nidlist, lookup, enumerate, 1);
170                         nl_destroy(nidlist);
171                 } else
172                         read_exports(exp_list.gl_pathv[i], nidlist);
173         }
174         if (!verbose) {
175                 print_nids(nidlist, lookup, enumerate, 0);
176                 nl_destroy(nidlist);
177         }
178         cfs_free_param_data(&exp_list);
179         return i;
180 }
181
182 static int empty_proc_file(char *path)
183 {
184         int empty = 0;
185         char buf[36];
186         int fd;
187
188         fd = open(path, O_RDONLY);
189         if (fd < 0 || read(fd, buf, sizeof(buf)) <= 0)
190                 empty = 1;
191         if (fd >= 0)
192                 close(fd);
193         return empty;
194 }
195
196 static void read_exports(char *exports, NIDList nidlist)
197 {
198         DIR *dirp;
199         struct dirent *dp;
200         char path[PATH_MAX + 1];
201
202         dirp = opendir(exports);
203         if (dirp) {
204                 while ((dp = readdir(dirp))) {
205                         if (dp->d_type != DT_DIR)
206                                 continue;
207                         if (!strcmp(dp->d_name, "."))
208                                 continue;
209                         if (!strcmp(dp->d_name, ".."))
210                                 continue;
211                         if (strchr(dp->d_name, '@') == NULL)
212                                 continue;
213                         snprintf(path, sizeof(path), PROC_UUID_TMPL, exports,
214                                  dp->d_name);
215                         if (empty_proc_file(path))
216                                 continue;
217
218                         nl_add(nidlist, dp->d_name);
219                 }
220                 closedir(dirp);
221         }
222 }