Whamcloud - gitweb
LU-8769 lnet: removal of obsolete LNDs
[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 <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_options[] = {
66         {"enumerate", no_argument, 0, 'e'},
67         {"help",      no_argument, 0, 'h'},
68         {"lookup",    no_argument, 0, 'l'},
69         {"verbose",   no_argument, 0, 'v'},
70         {0, 0, 0, 0},
71 };
72
73 static void usage(void)
74 {
75         fprintf(stderr, "usage: %s [-e] [-h] [-l] [-v]\n", prog);
76         exit(1);
77 }
78
79 int main(int argc, char **argv)
80 {
81         int opt, optidx = 0;
82         int lopt = 0;
83         int vopt = 0;
84         int eopt = 0;
85
86         prog = basename(argv[0]);
87
88         while ((opt = getopt_long(argc, argv, OPTIONS, long_options,
89                                   &optidx)) != -1) {
90                 switch (opt) {
91                 case 'e':       /* --enumerate */
92                         eopt = 1;
93                         break;
94                 case 'l':       /* --lookup */
95                         lopt = 1;
96                         break;
97                 case 'v':       /* --verbose */
98                         vopt = 1;
99                         break;
100                 case 'h':       /* --help */
101                 default:
102                         usage();
103                 }
104         }
105
106         if (lshowmount(lopt, eopt, vopt) == 0) {
107                 fprintf(stderr, "%s: lustre server modules not loaded\n", prog);
108                 exit(1);
109         }
110         exit(0);
111 }
112
113
114 static void print_expname(const char *path)
115 {
116         char *hp, buf[PATH_MAX + 1];
117
118         strncpy(buf, path, PATH_MAX);
119         buf[PATH_MAX] = '\0';
120         hp = strstr(buf, "exports");
121         if (hp && hp > buf) {
122                 *(--hp) = '\0';
123                 for (; *hp == '/' && hp > buf; hp--)
124                         ;
125                 for (; *hp != '/' && hp > buf; hp--)
126                         ;
127                 printf("%s:\n", hp + 1);
128         }
129 }
130
131 static void print_nids(NIDList nidlist, int lookup, int enumerate, int indent)
132 {
133         char *s, *sep = "\n", *pfx = "";
134
135         if (lookup)
136                 nl_lookup_ip(nidlist);
137         nl_sort(nidlist);
138         nl_uniq(nidlist);
139         if (nl_count(nidlist) > 0) {
140                 if (indent) {
141                         sep = "\n    ";
142                         pfx = "    ";
143                 }
144                 if (enumerate)
145                         s = nl_string(nidlist, sep);
146                 else
147                         s = nl_xstring(nidlist, sep);
148                 printf("%s%s\n", pfx, s);
149                 free(s);
150         }
151 }
152
153 static int lshowmount(int lookup, int enumerate, int verbose)
154 {
155         NIDList nidlist = NULL;
156         glob_t exp_list;
157         int i;
158
159         i = get_lustre_param_path("{mgs,mdt,obdfilter}", "*",
160                                    FILTER_BY_EXACT, "exports", &exp_list);
161         if (i < 0)
162                 return i;
163         if (!verbose)
164                 nidlist = nl_create();
165         for (i = 0; i < exp_list.gl_pathc; i++) {
166                 if (verbose) {
167                         nidlist = nl_create();
168                         read_exports(exp_list.gl_pathv[i], nidlist);
169                         print_expname(exp_list.gl_pathv[i]);
170                         print_nids(nidlist, lookup, enumerate, 1);
171                         nl_destroy(nidlist);
172                 } else
173                         read_exports(exp_list.gl_pathv[i], nidlist);
174         }
175         if (!verbose) {
176                 print_nids(nidlist, lookup, enumerate, 0);
177                 nl_destroy(nidlist);
178         }
179         cfs_free_param_data(&exp_list);
180         return i;
181 }
182
183 static int empty_proc_file(char *path)
184 {
185         int empty = 0;
186         char buf[36];
187         int fd;
188
189         fd = open(path, O_RDONLY);
190         if (fd < 0 || read(fd, buf, sizeof(buf)) <= 0)
191                 empty = 1;
192         if (fd >= 0)
193                 close(fd);
194         return empty;
195 }
196
197 static void read_exports(char *exports, NIDList nidlist)
198 {
199         DIR *dirp;
200         struct dirent *dp;
201         char path[PATH_MAX + 1];
202
203         dirp = opendir(exports);
204         if (dirp) {
205                 while ((dp = readdir(dirp))) {
206                         if (dp->d_type != DT_DIR)
207                                 continue;
208                         if (!strcmp(dp->d_name, "."))
209                                 continue;
210                         if (!strcmp(dp->d_name, ".."))
211                                 continue;
212                         if (strchr(dp->d_name, '@') == NULL)
213                                 continue;
214                         snprintf(path, sizeof(path), PROC_UUID_TMPL, exports,
215                                  dp->d_name);
216                         if (empty_proc_file(path))
217                                 continue;
218
219                         nl_add(nidlist, dp->d_name);
220                 }
221                 closedir(dirp);
222         }
223 }