13 #include <arpa/inet.h>
16 #include "lshowmount.h"
20 #define PROGNAME "lshowmount"
23 static int enumerate = 0;
24 static int lookup = 0;
25 static int verbose = 0;
27 static int totalexports = 0;
28 static int totalfailures = 0;
30 static struct option long_options[] = {
31 {"enumerate", 0, 0, 'e'},
33 {"lookup", 0, 0, 'l'},
34 {"verbose", 0, 0, 'v'},
39 lshowmount_hash_strcmp(const void *key1, const void *key2)
41 return strcmp((char *) key1, (char *) key2);
45 lshowmount_hash_hostlist_freeitem(void *data)
53 hl = (hostlist_t) data;
58 is_ipaddress(const char *str)
63 rc = sscanf(str, "%d.%d.%d.%d", &quad[0], &quad[1], &quad[2], &quad[3]);
71 lshowmount_gethostname(const char *src, char *dst, int dstsize)
73 struct hostent *hostptr = NULL;
77 memset(dst, 0, sizeof(char) * dstsize);
78 if (lookup && is_ipaddress(src)) {
79 rc = inet_pton(AF_INET, src, tmpsrc);
82 strncpy(dst, src, dstsize);
86 hostptr = gethostbyaddr(tmpsrc, 4, AF_INET);
87 if (hostptr == NULL) {
88 strncpy(dst, src, dstsize);
92 strncpy(dst, hostptr->h_name, dstsize);
97 strncpy(dst, src, dstsize);
101 lshowmount_print_hosts(char** network,
104 hostlist_t hl = NULL;
105 hostlist_iterator_t itr = NULL;
107 int numnets = 0, numhosts = 0, i = 0;
109 if (network == NULL || network_hash == NULL) {
113 numnets = hash_count(network_hash);
114 for (i = 0; i < numnets; i++) {
116 hl = hash_remove(network_hash, network[i]);
121 numhosts = hostlist_count(hl);
125 itr = hostlist_iterator_create(hl);
128 while ((hosts = hostlist_next(itr)) != NULL) {
129 printf(" %s@%s\n", hosts, network[i]);
131 hostlist_iterator_destroy(itr);
134 hosts = malloc(sizeof(char) * (numhosts) * (NID_MAX+1));
136 fprintf(stderr, "warning: could not allocate buffer "
137 "to print hostrange\n");
140 hostlist_ranged_string(hl, sizeof(char) *
143 printf(" %s@%s\n", hosts, network[i]);
148 memset(network[i], 0, sizeof(char) * (LNET_NETWORK_TYPE_MAX+1));
149 lshowmount_hash_hostlist_freeitem(hl);
155 fprintf(stderr, "usage: %s [-e] [-h] [-l] [-v]\n", PROGNAME);
158 int getclients(char* procpath,
163 struct dirent *dp, *dp2;
164 char path[PATH_MAX+1];
165 char nid[NID_MAX+1], addr[NID_MAX+1];
166 int size = PATH_MAX+1, sizeleft, sizeleft2;
167 int tmplen, tmplen2, idx, rc = 0;
171 if (procpath == NULL) {
175 /* It is not an error if we cannot open
176 * procpath since we are not sure if this
177 * node is an mgs, mds, and/or oss */
179 dirp = opendir(procpath);
188 if (dp->d_type != DT_DIR ||
189 strncmp(dp->d_name, ".", 2) == 0 ||
190 strncmp(dp->d_name, "..", 3) == 0) {
196 memset(tmp, 0, sizeof(char) * sizeleft);
198 strncpy(tmp, procpath, sizeleft);
199 tmplen = strnlen(tmp, sizeleft);
203 strncpy(tmp, "/", sizeleft);
204 tmplen = strnlen(tmp, sizeleft);
208 strncpy(tmp, dp->d_name, sizeleft);
209 tmplen = strnlen(tmp, sizeleft);
213 strncpy(tmp, "/", sizeleft);
214 tmplen = strnlen(tmp, sizeleft);
218 strncpy(tmp, PROC_EXPORTS, sizeleft);
219 tmplen = strnlen(tmp, sizeleft);
224 dirp2 = opendir(path);
226 fprintf(stderr, "error: could not open: %s\n", path);
233 dp2 = readdir(dirp2);
235 if (strncmp(dp2->d_name, ".", 2) == 0 ||
236 strncmp(dp2->d_name, "..", 3) == 0 ||
237 dp2->d_type != DT_DIR) {
242 sizeleft2 = sizeleft;
244 memset(tmp2, 0, sizeof(char) * sizeleft2);
246 strncpy(tmp2, "/", sizeleft2);
247 tmplen2 = strnlen(tmp2, sizeleft2);
248 sizeleft2 -= tmplen2;
251 strncpy(tmp2, dp2->d_name, sizeleft2);
252 tmplen2 = strnlen(tmp2, sizeleft2);
253 sizeleft2 -= tmplen2;
256 memset(nid, 0, sizeof(char) * (NID_MAX+1));
257 strncpy(nid, basename(path), sizeof(char) * (NID_MAX+1));
258 tmp2 = strrchr(nid, '@');
265 /* Note that tmp2 should now hold the lnet network */
267 /* Check to see if this lnet network already has a hostset
268 * associated with it */
270 hl = hash_find(network_hash, tmp2);
272 if (hash_count(network_hash) >= NETWORK_MAX) {
273 (void)closedir(dirp2);
277 /* Create a new hostset for this hash table and
278 * insert the first part of the nid into it */
279 idx = hash_count(network_hash);
280 strncpy(network[idx], tmp2, LNET_NETWORK_TYPE_MAX);
281 lshowmount_gethostname(nid, addr, NID_MAX+1);
282 hl = hostlist_create(addr);
283 hash_insert(network_hash, network[idx], hl);
286 lshowmount_gethostname(nid, addr, NID_MAX+1);
287 hostlist_push_host(hl, addr);
290 } while (dp2 != NULL);
291 (void) closedir(dirp2);
293 /* If the verbose option is set we want to print
294 * out the hostlist for each mgs, mds, obdfilter */
296 printf("%s:\n", dp->d_name);
297 if (totalfailures > 0) {
298 fprintf(stderr, "failures %d of %d exports\n",
299 totalfailures, totalexports);
302 if (!rc && totalfailures > 0) {
306 totalexports = totalfailures = 0;
307 lshowmount_print_hosts(network, network_hash);
310 } while (dp != NULL);
311 (void) closedir(dirp);
313 if (!rc && totalfailures > 0) {
320 int main(int argc, char **argv)
324 int i = 0, rc = 0, rc2 = 0, rc3 = 0;
325 hash_t network_hash = NULL;
326 char** network = NULL;
328 while ((opt = getopt_long(argc, argv, "ehlv",long_options, &optidx)) != -1) {
351 /* Allocate memory for NETWORK_MAX total possible
352 * lnet networks. Each network will have its own
353 * hash table so that we can possibly create a ranged
355 network = malloc(sizeof(char *) * NETWORK_MAX);
356 if (network == NULL) {
360 memset(network, 0, sizeof(char *) * NETWORK_MAX);
361 for (i = 0; i < NETWORK_MAX; i++) {
362 network[i] = malloc(sizeof(char) * (LNET_NETWORK_TYPE_MAX+1));
363 if (network[i] == NULL) {
367 memset(network[i], 0, sizeof(char) * (LNET_NETWORK_TYPE_MAX+1));
370 /* Initialize the network_hash. This hash table will map
371 * a particular network say elan1 or tcp2 to a hostset */
372 network_hash = hash_create(0,
373 (hash_key_f) hash_key_string,
374 lshowmount_hash_strcmp,
375 lshowmount_hash_hostlist_freeitem);
377 rc = getclients(PROC_DIR_MGS, network, network_hash);
378 rc2 = getclients(PROC_DIR_MDS, network, network_hash);
379 rc3 = getclients(PROC_DIR_OST, network, network_hash);
380 if (rc || rc2 || rc3) {
381 rc = rc2 > rc ? rc2 : rc;
382 rc = rc3 > rc ? rc3 : rc;
386 if (totalfailures > 0) {
387 fprintf(stderr, "failures %d of %d exports\n",
388 totalfailures, totalexports);
390 lshowmount_print_hosts(network, network_hash);
394 hash_destroy(network_hash);
395 if (network != NULL) {
396 for (i = 0; i < NETWORK_MAX; i++) {
397 if (network[i] != NULL) {
410 * vi:tabstop=4 shiftwidth=4 expandtab