Whamcloud - gitweb
LU-12845 utils: fix typos in 'lctl pcc' help
[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 <lustre/lustreapi.h>
55 #include <libcfs/util/param.h>
56
57 #define PROC_UUID_TMPL          "%s/%s/uuid"
58
59 static void print_nids(NIDList nidlist, int lookup, int enumerate, int indent);
60 static int lshowmount(int lookup, int enumerate, int verbose);
61 static void read_exports(char *exports, NIDList nidlist);
62
63 char *prog;
64
65 #define OPTIONS "ehlv"
66 static struct option long_opts[] = {
67         { .val = 'e',   .name = "enumerate",    .has_arg = no_argument },
68         { .val = 'h',   .name = "help",         .has_arg = no_argument },
69         { .val = 'l',   .name = "lookup",       .has_arg = no_argument },
70         { .val = 'v',   .name = "verbose",      .has_arg = no_argument },
71         { .name = NULL } };
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_opts,
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 = cfs_get_param_paths(&exp_list, "{mgs,mdt,obdfilter}/*/exports");
160         if (i < 0)
161                 return -errno;
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 }