Whamcloud - gitweb
- landing b_fid.
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *   Author: Peter J. Braam <braam@clusterfs.com>
6  *   Author: Phil Schwan <phil@clusterfs.com>
7  *   Author: Robert Read <rread@clusterfs.com>
8  *
9  *   This file is part of Lustre, http://www.lustre.org.
10  *
11  *   Lustre is free software; you can redistribute it and/or
12  *   modify it under the terms of version 2 of the GNU General Public
13  *   License as published by the Free Software Foundation.
14  *
15  *   Lustre is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25
26
27 /* for O_DIRECTORY */
28 #define _GNU_SOURCE
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stddef.h>
34 #include <sys/ioctl.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <errno.h>
38 #include <dirent.h>
39 #include <stdarg.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <linux/types.h>
43 #include <linux/unistd.h>
44
45 #include <liblustre.h>
46 #include <linux/obd.h>
47 #include <linux/lustre_lib.h>
48 #include <lustre/lustre_user.h>
49 #include <linux/obd_lov.h>
50
51 #include <portals/ptlctl.h>
52
53 static void err_msg(char *fmt, ...)
54 {
55         va_list args;
56         int tmp_errno = errno;
57
58         va_start(args, fmt);
59         vfprintf(stderr, fmt, args);
60         va_end(args);
61         fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
62 }
63
64 int llapi_file_create(char *name, long stripe_size, int stripe_offset,
65                       int stripe_count, int stripe_pattern)
66 {
67         struct lov_user_md lum = { 0 };
68         int fd, rc = 0;
69
70         /*  Initialize IOCTL striping pattern structure  */
71         lum.lmm_magic = LOV_USER_MAGIC;
72         lum.lmm_pattern = stripe_pattern;
73         lum.lmm_stripe_size = stripe_size;
74         lum.lmm_stripe_count = stripe_count;
75         lum.lmm_stripe_offset = stripe_offset;
76
77         fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
78         if (errno == EISDIR)
79                 fd = open(name, O_DIRECTORY | O_RDONLY);
80
81         if (fd < 0) {
82                 err_msg("unable to open '%s'",name);
83                 rc = -errno;
84                 return rc;
85         }
86
87         if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) {
88                 char *errmsg = "stripe already set";
89                 if (errno != EEXIST && errno != EALREADY)
90                         errmsg = strerror(errno);
91
92                 fprintf(stderr, "error on ioctl for '%s' (%d): %s\n",
93                         name, fd, errmsg);
94                 rc = -errno;
95         }
96         if (close(fd) < 0) {
97                 err_msg("error on close for '%s' (%d)", name, fd);
98                 if (rc == 0)
99                         rc = -errno;
100         }
101         return rc;
102 }
103
104 int op_create_dir(char *name, int stripe_count)
105 {
106         struct  ll_user_mkdir_stripe lums = { 0 };
107         int fd, rc = 0;
108         char *dot = ".";
109         char *dirname;
110
111         dirname = rindex(name, '/');
112         if (!dirname) {
113                 dirname = "name";
114                 name = dot;
115         } else {
116                 *dirname = 0;
117                 dirname++;
118         }
119         lums.lums_nstripes = stripe_count;
120         lums.lums_namelen = strlen(dirname);
121         lums.lums_name = dirname;
122         /* XXX: Probably users might want to specify permissions as well? */
123         lums.lums_mode = 0755;
124                 
125         fd = open(name, O_RDONLY|O_DIRECTORY);
126         if (name != dot)
127                 *(dirname-1) = '/';
128         if (fd < 0) {
129                 err_msg("unable to open '%s'",name);
130                 rc = -errno;
131                 return rc;
132         }
133         
134         if (ioctl(fd, LL_IOC_MDC_MKDIRSTRIPE, &lums)) {
135                 char *errmsg = strerror(errno);
136
137                 fprintf(stderr, "error on ioctl for '%s' (%d): %s\n",
138                         name, fd, errmsg);
139                 rc = -errno;
140         }
141         if (close(fd) < 0) {
142                 err_msg("error on close for '%s' (%d)", name, fd);
143                 if (rc == 0)
144                         rc = -errno;
145         }
146         return rc;
147 }
148
149 /* short term backwards compat only */
150 int op_create_file(char *name, long stripe_size, int stripe_offset,
151                    int stripe_count)
152 {
153         return llapi_file_create(name, stripe_size, stripe_offset,
154                                  stripe_count, 0);
155 }
156
157 struct find_param {
158         int                 recursive;
159         int                 verbose;
160         int                 quiet;
161         int                 showfid;
162         struct obd_uuid    *obduuid;
163         int                 datalen;
164         struct lov_user_md *data;
165         int                 got_uuids;
166         int                 obdindex;
167         __u32              *obdgens;
168 };
169
170 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
171 #define MAX_LOV_UUID_COUNT      1000
172 #define OBD_NOT_FOUND           (-1)
173
174 static int prepare_find(struct find_param *param)
175 {
176         if (param->showfid) {
177                 param->datalen = PATH_MAX + 1;
178                 if ((param->data = malloc(param->datalen)) == NULL) {
179                         err_msg("unable to allocate %d bytes of memory for ioctl",
180                                 param->datalen);
181                         return ENOMEM;
182                 }
183         } else {
184                 param->datalen = lov_mds_md_size(MAX_LOV_UUID_COUNT);
185                 if ((param->data = malloc(param->datalen)) == NULL) {
186                         err_msg("unable to allocate %d bytes of memory for ioctl",
187                                 param->datalen);
188                         return ENOMEM;
189                 }
190         }
191         param->got_uuids = 0;
192         param->obdindex = OBD_NOT_FOUND;
193         return 0;
194 }
195
196 static void cleanup_find(struct find_param *param)
197 {
198         if (param->obduuid)
199                 free(param->obduuid);
200         if (param->data)
201                 free(param->data);
202 }
203
204 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp,
205                         __u32 *obdgens, int *ost_count)
206 {
207         struct obd_ioctl_data data = { 0, };
208         struct lov_desc desc = { 0, };
209         char *buf = NULL;
210         int max_ost_count, rc;
211
212         max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) -
213                          size_round(sizeof(desc))) / 
214                         (sizeof(*uuidp) + sizeof(*obdgens));
215         if (max_ost_count > *ost_count)
216                 max_ost_count = *ost_count;
217
218         data.ioc_inllen1 = sizeof(desc);
219         data.ioc_inlbuf1 = (char *)&desc;
220         data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp));
221         data.ioc_inlbuf2 = (char *)uuidp;
222         data.ioc_inllen3 = size_round(max_ost_count * sizeof(*obdgens));
223         data.ioc_inlbuf3 = (char *)obdgens;
224
225         desc.ld_tgt_count = max_ost_count;
226
227         if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) {
228                 fprintf(stderr, "internal buffer error packing\n");
229                 rc = EINVAL;
230                 goto out;
231         }
232
233         rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
234         if (rc) {
235                 err_msg("error getting LOV config");
236                 rc = errno;
237                 goto out;
238         }
239
240         if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) {
241                 fprintf(stderr, "invalid reply from ioctl");
242                 rc = EINVAL;
243                 goto out;
244         }
245
246         *ost_count = desc.ld_tgt_count;
247 out:
248         free(buf);
249
250         return 0;
251 }
252
253 static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
254 {
255         struct obd_uuid uuids[1024], *uuidp;
256         __u32 obdgens[1024], *genp;
257         int obdcount = 1024;
258         int rc, i;
259
260         param->got_uuids = 1;
261
262         rc = llapi_lov_get_uuids(dirfd(dir), uuids, obdgens, &obdcount);
263         if (rc != 0)
264                 return (param->obduuid ? rc : 0);
265
266         if (obdcount == 0)
267                 return 0;
268
269         if (param->obduuid) {
270                 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
271                         if (strncmp(param->obduuid->uuid, uuidp->uuid,
272                                     sizeof(*uuidp)) == 0) {
273                                 param->obdindex = i;
274                                 break;
275                         }
276                 }
277                 if (param->obdindex == OBD_NOT_FOUND) {
278                         printf("unknown obduuid: %s\n", param->obduuid->uuid);
279                         return EINVAL;
280                 }
281         } else if (!param->quiet) {
282
283                 printf("OBDS:\tobdidx\t\tobdgen\t\t obduuid\n");
284                 uuidp = uuids;
285                 genp = obdgens;
286                 for (i = 0; i < obdcount; i++, uuidp++, genp++) {
287                         if (obd_uuid_empty(uuidp))
288                                 continue;
289                         printf("\t%6u\t%14u\t\t %s\n", i, *genp, uuidp->uuid);
290                 }    
291         }
292         return 0;
293 }
294
295 void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname,
296                           int obdindex, int quiet, int header, int body)
297 {
298         int i, obdstripe = 0;
299
300         if (obdindex != OBD_NOT_FOUND) {
301                 for (i = 0; i < lum->lmm_stripe_count; i++) {
302                         if (obdindex == lum->lmm_objects[i].l_ost_idx) {
303                                 printf("%s/%s\n", dname, fname);
304                                 obdstripe = 1;
305                                 break;
306                         }
307                 }
308         } else if (!quiet) {
309                 printf("%s/%s\n", dname, fname);
310                 obdstripe = 1;
311         }
312
313         /* if it's a directory */
314         if (*fname == '\0') {
315                 if (header && (obdstripe == 1)) {
316                         printf("count: %d, size: %d, offset: %d\n\n",
317                                lum->lmm_stripe_count, lum->lmm_stripe_size,
318                                (short int)lum->lmm_stripe_offset);
319                 }
320                 return;
321         }
322
323         if (header && (obdstripe == 1)) {
324                 printf("lmm_magic:          0x%08X\n",  lum->lmm_magic);
325                 printf("lmm_object_gr:      "LPX64"\n", lum->lmm_object_gr);
326                 printf("lmm_object_id:      "LPX64"\n", lum->lmm_object_id);
327                 printf("lmm_stripe_count:   %u\n", (int)lum->lmm_stripe_count);
328                 printf("lmm_stripe_size:    %u\n",      lum->lmm_stripe_size);
329                 printf("lmm_stripe_pattern: %x\n",      lum->lmm_pattern);
330         }
331
332         if (body) {
333                 if ((!quiet) && (obdstripe == 1))
334                         printf("\tobdidx\t\t obdgen\t\t objid\t\tobjid\t\t group\n");
335
336                 for (i = 0; i < lum->lmm_stripe_count; i++) {
337                         int idx = lum->lmm_objects[i].l_ost_idx;
338                         long long oid = lum->lmm_objects[i].l_object_id;
339                         int gen = lum->lmm_objects[i].l_ost_gen;
340                         long long gr = lum->lmm_objects[i].l_object_gr;
341                         if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
342                                 printf("\t%6u\t%14u\t%14llu\t%#13llx\t%14lld%s\n",
343                                         idx, gen, oid, oid, gr,
344                                         obdindex == idx ? " *" : "");
345                 }
346                 printf("\n");
347         }
348 }
349
350 void llapi_lov_dump_user_lmm(struct find_param *param, char *dname, char *fname)
351 {
352         switch(*(__u32 *)param->data) { /* lum->lmm_magic */
353         case LOV_USER_MAGIC_V1:
354                 lov_dump_user_lmm_v1(param->data, dname, fname, param->obdindex,
355                                      param->quiet, param->verbose,
356                                      (param->verbose || !param->obduuid));
357                 break;
358         default:
359                 printf("unknown lmm_magic:  0x%08X\n", *(__u32 *)param->data);
360                 return;
361         }
362 }
363
364 void llapi_dump_fid(struct find_param *param, char *dname, char *fname)
365 {
366         if (!param->quiet) {
367                 int n = 0;
368                 char path[PATH_MAX + 1];
369
370                 n = snprintf(path, PATH_MAX, "%s/%s",
371                              dname, fname);
372
373                 if (n > 40)
374                         n = 1;
375                 else
376                         n = 40 - n;
377                 
378                 printf("%s:%*s"DLID4"\n", path, n, "",
379                        OLID4((struct lustre_id *)param->data));
380         }
381 }
382
383 int llapi_file_get_stripe(char *path, struct lov_user_md *lum)
384 {
385         char *dname, *fname;
386         int fd, rc = 0;
387
388         fname = strrchr(path, '/');
389
390         /* It should be a file (or other non-directory) */
391         if (fname == NULL) {
392                 dname = (char *)malloc(2);
393                 if (dname == NULL)
394                         return ENOMEM;
395                 strcpy(dname, ".");
396                 fname = path;
397         } else {
398                 dname = (char *)malloc(fname - path + 1);
399                 if (dname == NULL)
400                         return ENOMEM;
401                 strncpy(dname, path, fname - path);
402                 dname[fname - path] = '\0';
403                 fname++;
404         }
405
406         if ((fd = open(dname, O_RDONLY)) == -1) {
407                 free(dname);
408                 return errno;
409         }
410
411         strncpy((char *)lum, fname, sizeof(*lum));
412         if (ioctl(fd, IOC_MDC_GETSTRIPE, (void *)lum) == -1) {
413                 close(fd);
414                 free(dname);
415                 return errno;
416         }
417
418         if (close(fd) == -1)
419                 rc = errno;
420
421         free(dname);
422
423         return rc;
424 }
425
426 int llapi_file_get_fid(char *path, void *data)
427 {
428         char *dname, *fname;
429         int fd, rc = 0;
430
431         fname = strrchr(path, '/');
432
433         if (fname == NULL) {
434                 dname = (char *)malloc(2);
435                 if (dname == NULL)
436                         return ENOMEM;
437                 strcpy(dname, ".");
438                 fname = path;
439         } else {
440                 dname = (char *)malloc(fname - path + 1);
441                 if (dname == NULL)
442                         return ENOMEM;
443                 strncpy(dname, path, fname - path);
444                 dname[fname - path] = '\0';
445                 fname++;
446
447                 if (!strlen(fname))
448                         fname = ".";
449         }
450
451         if ((fd = open(dname, O_RDONLY)) == -1) {
452                 free(dname);
453                 return errno;
454         }
455
456         strncpy((char *)data, fname, strlen(fname));
457         if (ioctl(fd, IOC_MDC_SHOWFID, (void *)data) == -1) {
458                 close(fd);
459                 free(dname);
460                 return errno;
461         }
462
463         if (close(fd) == -1)
464                 rc = errno;
465
466         free(dname);
467         return rc;
468 }
469
470 /* short term backwards compat only */
471 int op_get_file_stripe(char *path, struct lov_user_md *lum)
472 {
473         return llapi_file_get_stripe(path, lum);
474 }
475
476 static int process_file(DIR *dir, char *dname, char *fname,
477                         struct find_param *param)
478 {
479         int rc;
480
481         if (param->showfid) {
482                 char path[PATH_MAX + 1];
483
484                 snprintf(path, PATH_MAX, "%s/%s", dname, fname);
485                 rc = llapi_file_get_fid(path, (void *)param->data);
486                 if (rc) {
487                         err_msg("IOC_MDC_SHOWFID ioctl failed");
488                         return rc;
489                 }
490                 llapi_dump_fid(param, dname, fname);
491         } else {
492                 strncpy((char *)param->data, fname, param->datalen);
493                 rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->data);
494                 if (rc) {
495                         if (errno == ENODATA) {
496                                 if (!param->obduuid && !param->quiet)
497                                         fprintf(stderr,
498                                                 "%s/%s has no stripe info\n",
499                                                 dname, fname);
500                                 rc = 0;
501                         } else if (errno == EISDIR) {
502                                 fprintf(stderr, "process_file on directory %s/%s!\n",
503                                         dname, fname);
504                                 /* add fname to directory list; */
505                                 rc = errno;
506                         } else {
507                                 err_msg("IOC_MDC_GETSTRIPE ioctl failed");
508                                 rc = errno;
509                         }
510                         return rc;
511                 }
512                 llapi_lov_dump_user_lmm(param, dname, fname);
513         }
514         return 0;
515 }
516
517 /* some 64bit libcs implement readdir64() by calling sys_getdents().  the
518  * kernel's sys_getdents() doesn't return d_type.  */
519 unsigned char handle_dt_unknown(char *parent, char *entry)
520 {
521         char path[PATH_MAX + 1];
522         int fd, ret;
523
524         ret = snprintf(path, PATH_MAX, "%s/%s", parent, entry);
525         if (ret >= PATH_MAX)
526                 return DT_UNKNOWN;
527
528         fd = open(path, O_DIRECTORY|O_RDONLY);
529         if (fd < 0) {
530                 if (errno == ENOTDIR)
531                         return DT_REG; /* kind of a lie */
532                 return DT_UNKNOWN;
533         }
534         close(fd);
535         return DT_DIR;
536 }
537
538 static int process_dir(DIR *dir, char *dname, struct find_param *param)
539 {
540         char path[PATH_MAX + 1];
541         struct dirent64 *dirp;
542         DIR *subdir;
543         int rc;
544
545         /* retrieve dir's stripe info */
546         if (param->showfid) {
547                 rc = llapi_file_get_fid(dname, (void *)param->data);
548                 if (rc) {
549                         err_msg("IOC_MDC_SHOWFID ioctl failed");
550                         return rc;
551                 }
552                 llapi_dump_fid(param, dname, "");
553         } else {
554                 if (!param->got_uuids) {
555                         rc = setup_obd_uuids(dir, dname, param);
556                         if (rc)
557                                 return rc;
558                 }
559
560                 strncpy((char *)param->data, dname, param->datalen);
561                 rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->data);
562                 if (rc) {
563                         if (errno == ENODATA) {
564                                 if (!param->obduuid && param->verbose)
565                                         printf("%s/%s has no stripe info\n", dname, "");
566                                 rc = 0;
567                         } else {
568                                 err_msg("IOC_MDC_GETSTRIPE ioctl failed");
569                                 return errno;
570                         }
571                 } else {
572                         llapi_lov_dump_user_lmm(param, dname, "");
573                 }
574         }
575
576         /* Handle the contents of the directory */
577         while ((dirp = readdir64(dir)) != NULL) {
578                 if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
579                         continue;
580
581                 if (dirp->d_type == DT_UNKNOWN)
582                         dirp->d_type = handle_dt_unknown(dname, dirp->d_name);
583
584                 switch (dirp->d_type) {
585                 case DT_UNKNOWN:
586                         err_msg("\"%s\" is UNKNOWN type %d", dirp->d_name,
587                                 dirp->d_type);
588                         /* If we cared we could stat the file to determine
589                          * type and continue on here, but we don't since we
590                          * know d_type should be valid for lustre and this
591                          * tool only makes sense for lustre filesystems. */
592                         return EINVAL;
593                 case DT_DIR:
594                         if (!param->recursive)
595                                 break;
596                         strcpy(path, dname);
597                         strcat(path, "/");
598                         strcat(path, dirp->d_name);
599                         subdir = opendir(path);
600                         if (subdir == NULL) {
601                                 err_msg("\"%.40s\" opendir failed", path);
602                                 return errno;
603                         }
604                         rc = process_dir(subdir, path, param);
605                         closedir(subdir);
606                         if (rc)
607                                 return rc;
608                         break;
609                 case DT_REG:
610                         rc = process_file(dir, dname, dirp->d_name, param);
611                         if (rc)
612                                 return rc;
613                         break;
614                 default:
615                         break;
616                 }
617         }
618
619         return 0;
620 }
621
622 static int process_path(char *path, struct find_param *param)
623 {
624         char *fname, *dname;
625         DIR *dir;
626         int rc = 0;
627
628         fname = strrchr(path, '/');
629         if (fname != NULL && fname[1] == '\0') {
630                 /* Trailing '/', it must be a dir */
631                 *fname = '\0';
632                 dir = opendir(path);
633                 if (dir == NULL) {
634                         err_msg("\"%.40s\" opendir failed", path);
635                         rc = errno;
636                 } else {
637                         rc = process_dir(dir, path, param);
638                         closedir(dir);
639                 }
640         } else if ((dir = opendir(path)) != NULL) {
641                 /* No trailing '/', but it is still a dir */
642                 rc = process_dir(dir, path, param);
643                 closedir(dir);
644         } else {
645                 /* It must be a file (or other non-directory) */
646                 if (fname == NULL) {
647                         dname = ".";
648                         fname = path;
649                 } else {
650                         *fname = '\0';
651                         fname++;
652                         dname = path;
653                 }
654                 dir = opendir(dname);
655                 if (dir == NULL) {
656                         err_msg("\"%.40s\" opendir failed", dname);
657                         rc = errno;
658                 } else {
659                         if (!param->showfid) {
660                                 if (!param->got_uuids)
661                                         rc = setup_obd_uuids(dir, dname, param);
662                         }
663                         if (rc == 0)
664                                 rc = process_file(dir, dname, fname, param);
665                         closedir(dir);
666                 }
667         }
668
669         return rc;
670 }
671
672 int llapi_find(char *path, struct obd_uuid *obduuid, int recursive,
673                int verbose, int quiet, int showfid)
674 {
675         struct find_param param;
676         int ret = 0;
677
678         memset(&param, 0, sizeof(param));
679         param.recursive = recursive;
680         param.showfid = showfid;
681         param.verbose = verbose;
682         param.quiet = quiet;
683         if (obduuid) {
684                 param.obduuid = malloc(sizeof(*obduuid));
685                 if (param.obduuid == NULL) {
686                         ret = ENOMEM;
687                         goto out;
688                 }
689                 memcpy(param.obduuid, obduuid, sizeof(*obduuid));
690         }
691
692         ret = prepare_find(&param);
693         if (ret)
694                 goto out;
695
696         process_path(path, &param);
697 out:
698         cleanup_find(&param);
699         return ret;
700 }
701
702 #define MAX_STRING_SIZE 128
703 #define DEVICES_LIST "/proc/fs/lustre/devices"
704
705 int llapi_target_check(int type_num, char **obd_type, char *dir)
706 {
707         char buf[MAX_STRING_SIZE];
708         FILE *fp = fopen(DEVICES_LIST, "r");
709         int rc = 0;
710         int i;
711
712         if (fp == NULL) {
713                 fprintf(stderr, "error: %s opening "DEVICES_LIST"\n",
714                         strerror(rc =  errno));
715                 return rc;
716         }
717
718         while (fgets(buf, sizeof(buf), fp) != NULL) {
719                 char *obd_type_name = NULL;
720                 char *obd_name = NULL;
721                 char rawbuf[OBD_MAX_IOCTL_BUFFER];
722                 char *bufl = rawbuf;
723                 char *bufp = buf;
724                 int max = sizeof(rawbuf);
725                 struct obd_ioctl_data datal;
726                 struct obd_statfs osfs_buffer;
727
728                 while(bufp[0] == ' ')
729                         ++bufp;
730
731                 for(i = 0; i < 3; i++) {
732                         obd_type_name = strsep(&bufp, " ");
733                 }
734                 obd_name = strsep(&bufp, " ");
735
736                 memset(&osfs_buffer, 0, sizeof (osfs_buffer));
737
738                 memset(bufl, 0, sizeof(rawbuf));
739                 datal.ioc_pbuf1 = (char *)&osfs_buffer;
740                 datal.ioc_plen1 = sizeof(osfs_buffer);
741
742                 for (i = 0; i < type_num; i++)
743                         if (strcmp(obd_type_name, obd_type[i]) == 0) {
744                                 datal.ioc_inlbuf1 = obd_name;
745                                 datal.ioc_inllen1 = strlen(obd_name) + 1;
746
747                                 obd_ioctl_pack(&datal,&bufl,max);
748
749                                 rc = ioctl(dirfd(opendir(dir)), OBD_IOC_PING,
750                                            bufl);
751
752                                 if (rc) {
753                                         fprintf(stderr, "error: check %s: %s\n",
754                                                 obd_name, strerror(rc = errno));
755                                 } else {
756                                         printf("%s active.\n",obd_name);
757                                 }
758                         }
759
760         }
761         fclose(fp);
762         return rc;
763 }
764
765 #undef MAX_STRING_SIZE
766
767 int llapi_catinfo(char *dir, char *keyword, char *node_name)
768 {
769         char raw[OBD_MAX_IOCTL_BUFFER];
770         char out[LLOG_CHUNK_SIZE];
771         char *buf = raw;
772         struct obd_ioctl_data data;
773         char key[30];
774         DIR *root;
775         int rc;
776
777         sprintf(key, "%s", keyword);
778         memset(raw, 0, sizeof(buf));
779         memset(out, 0, sizeof(out));
780         data.ioc_inlbuf1 = key;
781         data.ioc_inllen1 = strlen(key) + 1;
782         if (node_name) {
783                 data.ioc_inlbuf2 = node_name;
784                 data.ioc_inllen2 = strlen(node_name) + 1;
785         }
786         data.ioc_pbuf1 = out;
787         data.ioc_plen1 = sizeof(out);
788         rc = obd_ioctl_pack(&data, &buf, sizeof(raw));
789         if (rc)
790                 return rc;
791
792         root = opendir(dir);
793         if (root == NULL) {
794                 err_msg("open %s failed", dir);
795                 return errno;
796         }
797
798         rc = ioctl(dirfd(root), OBD_IOC_LLOG_CATINFO, buf);
799         if (rc)
800                 err_msg("ioctl OBD_IOC_CATINFO failed");
801         else
802                 fprintf(stdout, "%s", data.ioc_pbuf1);
803
804         closedir(root);
805         return rc;
806 }
807
808 int llapi_is_lustre_mnttype(char *type)
809 {
810         return (strcmp(type,"lustre") == 0 || strcmp(type,"lustre_lite") == 0);
811 }