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