Whamcloud - gitweb
* pass in the 3rd parameter for obdgens while getting lov stripe config.
[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         struct  obd_uuid        *obduuid;
162         int     lumlen;
163         struct  lov_user_md     *lum;
164         int     got_uuids;
165         int     obdindex;
166 };
167
168 /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
169 #define MAX_LOV_UUID_COUNT      1000
170 #define OBD_NOT_FOUND           (-1)
171
172 static int prepare_find(struct find_param *param)
173 {
174         param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT);
175         if ((param->lum = malloc(param->lumlen)) == NULL) {
176                 err_msg("unable to allocate %d bytes of memory for ioctl",
177                         param->lumlen);
178                 return ENOMEM;
179         }
180
181         param->got_uuids = 0;
182         param->obdindex = OBD_NOT_FOUND;
183
184         return 0;
185 }
186
187 static void cleanup_find(struct find_param *param)
188 {
189         if (param->obduuid)
190                 free(param->obduuid);
191         if (param->lum)
192                 free(param->lum);
193 }
194
195 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
196 {
197         struct obd_ioctl_data data = { 0, };
198         struct lov_desc desc = { 0, };
199         char *buf = NULL;
200         int max_ost_count, rc;
201         __u32 *obdgens;
202
203         max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) -
204                          size_round(sizeof(desc))) / 
205                         (sizeof(*uuidp) + sizeof(*obdgens));
206         if (max_ost_count > *ost_count)
207                 max_ost_count = *ost_count;
208
209         obdgens = malloc(size_round(max_ost_count * sizeof(*obdgens)));
210         if (!obdgens) {
211                 err_msg("no memory for %d generation #'s", max_ost_count);
212                 return(-ENOMEM);
213         }
214
215         data.ioc_inllen1 = sizeof(desc);
216         data.ioc_inlbuf1 = (char *)&desc;
217         data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp));
218         data.ioc_inlbuf2 = (char *)uuidp;
219         data.ioc_inllen3 = size_round(max_ost_count * sizeof(*obdgens));
220         data.ioc_inlbuf3 = (char *)obdgens;
221
222         desc.ld_tgt_count = max_ost_count;
223
224         if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) {
225                 fprintf(stderr, "internal buffer error packing\n");
226                 rc = EINVAL;
227                 goto out;
228         }
229
230         rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
231         if (rc) {
232                 err_msg("error getting LOV config");
233                 rc = errno;
234                 goto out;
235         }
236
237         if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) {
238                 fprintf(stderr, "invalid reply from ioctl");
239                 rc = EINVAL;
240                 goto out;
241         }
242
243         *ost_count = desc.ld_tgt_count;
244 out:
245         free(buf);
246         free(obdgens);
247
248         return 0;
249 }
250
251 static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
252 {
253         struct obd_uuid uuids[1024], *uuidp;
254         int obdcount = 1024;
255         int rc, i;
256
257         param->got_uuids = 1;
258
259         rc = llapi_lov_get_uuids(dirfd(dir), uuids, &obdcount);
260         if (rc != 0)
261                 return (param->obduuid ? rc : 0);
262
263         if (obdcount == 0)
264                 return 0;
265
266         if (param->obduuid) {
267                 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
268                         if (strncmp(param->obduuid->uuid, uuidp->uuid,
269                                     sizeof(*uuidp)) == 0) {
270                                 param->obdindex = i;
271                                 break;
272                         }
273                 }
274                 if (param->obdindex == OBD_NOT_FOUND) {
275                         printf("unknown obduuid: %s\n", param->obduuid->uuid);
276                         return EINVAL;
277                 }
278         } else if (!param->quiet) {
279                 printf("OBDS:\n");
280                 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
281                         printf("%4d: %s\n", i, uuidp->uuid);
282         }
283
284         return 0;
285 }
286
287 void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname,
288                           int obdindex, int quiet, int header, int body)
289 {
290         int i, obdstripe = 0;
291
292         if (obdindex != OBD_NOT_FOUND) {
293                 for (i = 0; i < lum->lmm_stripe_count; i++) {
294                         if (obdindex == lum->lmm_objects[i].l_ost_idx) {
295                                 printf("%s/%s\n", dname, fname);
296                                 obdstripe = 1;
297                                 break;
298                         }
299                 }
300         } else if (!quiet) {
301                 printf("%s/%s\n", dname, fname);
302                 obdstripe = 1;
303         }
304
305         /* if it's a directory */
306         if (*fname == '\0') {
307                 if (header && (obdstripe == 1)) {
308                         printf("count: %d, size: %d, offset: %d\n\n",
309                                lum->lmm_stripe_count, lum->lmm_stripe_size,
310                                (short int)lum->lmm_stripe_offset);
311                 }
312                 return;
313         }
314
315         if (header && (obdstripe == 1)) {
316                 printf("lmm_magic:          0x%08X\n",  lum->lmm_magic);
317                 printf("lmm_object_gr:      "LPX64"\n", lum->lmm_object_gr);
318                 printf("lmm_object_id:      "LPX64"\n", lum->lmm_object_id);
319                 printf("lmm_stripe_count:   %u\n", (int)lum->lmm_stripe_count);
320                 printf("lmm_stripe_size:    %u\n",      lum->lmm_stripe_size);
321                 printf("lmm_stripe_pattern: %x\n",      lum->lmm_pattern);
322         }
323
324         if (body) {
325                 if ((!quiet) && (obdstripe == 1))
326                         printf("\tobdidx\t\t objid\t\tobjid\t\t group\n");
327
328                 for (i = 0; i < lum->lmm_stripe_count; i++) {
329                         int idx = lum->lmm_objects[i].l_ost_idx;
330                         long long oid = lum->lmm_objects[i].l_object_id;
331                         long long gr = lum->lmm_objects[i].l_object_gr;
332                         if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
333                                 printf("\t%6u\t%14llu\t%#13llx\t%14llu%s\n",
334                                        idx, oid, oid, gr,
335                                        obdindex == idx ? " *" : "");
336                 }
337                 printf("\n");
338         }
339 }
340
341 void llapi_lov_dump_user_lmm(struct find_param *param, char *dname, char *fname)
342 {
343         switch(*(__u32 *)param->lum) { /* lum->lmm_magic */
344         case LOV_USER_MAGIC_V1:
345                 lov_dump_user_lmm_v1(param->lum, dname, fname, param->obdindex,
346                                      param->quiet, param->verbose,
347                                      (param->verbose || !param->obduuid));
348                 break;
349         default:
350                 printf("unknown lmm_magic:  0x%08X\n", *(__u32 *)param->lum);
351                 return;
352         }
353 }
354
355 int llapi_file_get_stripe(char *path, struct lov_user_md *lum)
356 {
357         char *dname, *fname;
358         int fd, rc = 0;
359
360         fname = strrchr(path, '/');
361
362         /* It should be a file (or other non-directory) */
363         if (fname == NULL) {
364                 dname = (char *)malloc(2);
365                 if (dname == NULL)
366                         return ENOMEM;
367                 strcpy(dname, ".");
368                 fname = path;
369         } else {
370                 dname = (char *)malloc(fname - path + 1);
371                 if (dname == NULL)
372                         return ENOMEM;
373                 strncpy(dname, path, fname - path);
374                 dname[fname - path + 1] = '\0';
375                 fname++;
376         }
377
378         if ((fd = open(dname, O_RDONLY)) == -1) {
379                 free(dname);
380                 return errno;
381         }
382
383         strncpy((char *)lum, fname, sizeof(*lum));
384         if (ioctl(fd, IOC_MDC_GETSTRIPE, (void *)lum) == -1) {
385                 close(fd);
386                 free(dname);
387                 return errno;
388         }
389
390         if (close(fd) == -1)
391                 rc = errno;
392
393         free(dname);
394
395         return rc;
396 }
397
398 /* short term backwards compat only */
399 int op_get_file_stripe(char *path, struct lov_user_md *lum)
400 {
401         return llapi_file_get_stripe(path, lum);
402 }
403
404 static int process_file(DIR *dir, char *dname, char *fname,
405                         struct find_param *param)
406 {
407         int rc;
408
409         strncpy((char *)param->lum, fname, param->lumlen);
410
411         rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->lum);
412         if (rc) {
413                 if (errno == ENODATA) {
414                         if (!param->obduuid && !param->quiet)
415                                 fprintf(stderr,
416                                         "%s/%s has no stripe info\n",
417                                         dname, fname);
418                         rc = 0;
419                 } else if (errno == EISDIR) {
420                         fprintf(stderr, "process_file on directory %s/%s!\n",
421                                 dname, fname);
422                         /* add fname to directory list; */
423                         rc = errno;
424                 } else {
425                         err_msg("IOC_MDC_GETSTRIPE ioctl failed");
426                         rc = errno;
427                 }
428                 return rc;
429         }
430
431         llapi_lov_dump_user_lmm(param, dname, fname);
432
433         return 0;
434 }
435
436 /* some 64bit libcs implement readdir64() by calling sys_getdents().  the
437  * kernel's sys_getdents() doesn't return d_type.  */
438 unsigned char handle_dt_unknown(char *parent, char *entry)
439 {
440         char path[PATH_MAX + 1];
441         int fd, ret;
442
443         ret = snprintf(path, PATH_MAX, "%s/%s", parent, entry);
444         if (ret >= PATH_MAX)
445                 return DT_UNKNOWN;
446
447         fd = open(path, O_DIRECTORY|O_RDONLY);
448         if (fd < 0) {
449                 if (errno == ENOTDIR)
450                         return DT_REG; /* kind of a lie */
451                 return DT_UNKNOWN;
452         }
453         close(fd);
454         return DT_DIR;
455 }
456
457 static int process_dir(DIR *dir, char *dname, struct find_param *param)
458 {
459         struct dirent64 *dirp;
460         DIR *subdir;
461         char path[1024];
462         int rc;
463
464         if (!param->got_uuids) {
465                 rc = setup_obd_uuids(dir, dname, param);
466                 if (rc)
467                         return rc;
468         }
469
470         /* retrieve dir's stripe info */
471         strncpy((char *)param->lum, dname, param->lumlen);
472         rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->lum);
473         if (rc) {
474                 if (errno == ENODATA) {
475                         if (!param->obduuid && param->verbose)
476                                 printf("%s/%s has no stripe info\n", dname, "");
477                         rc = 0;
478                 } else {
479                         err_msg("IOC_MDC_GETSTRIPE ioctl failed");
480                         return errno;
481                 }
482         } else {
483                llapi_lov_dump_user_lmm(param, dname, "");
484         }
485
486         /* Handle the contents of the directory */
487         while ((dirp = readdir64(dir)) != NULL) {
488                 if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
489                         continue;
490
491                 if (dirp->d_type == DT_UNKNOWN)
492                         dirp->d_type = handle_dt_unknown(dname, dirp->d_name);
493
494                 switch (dirp->d_type) {
495                 case DT_UNKNOWN:
496                         err_msg("\"%s\" is UNKNOWN type %d", dirp->d_name,
497                                 dirp->d_type);
498                         /* If we cared we could stat the file to determine
499                          * type and continue on here, but we don't since we
500                          * know d_type should be valid for lustre and this
501                          * tool only makes sense for lustre filesystems. */
502                         return EINVAL;
503                         break;
504                 case DT_DIR:
505                         if (!param->recursive)
506                                 break;
507                         strcpy(path, dname);
508                         strcat(path, "/");
509                         strcat(path, dirp->d_name);
510                         subdir = opendir(path);
511                         if (subdir == NULL) {
512                                 err_msg("\"%.40s\" opendir failed", path);
513                                 return errno;
514                         }
515                         rc = process_dir(subdir, path, param);
516                         closedir(subdir);
517                         if (rc)
518                                 return rc;
519                         break;
520                 case DT_REG:
521                         rc = process_file(dir, dname, dirp->d_name, param);
522                         if (rc)
523                                 return rc;
524                         break;
525                 default:
526                         break;
527                 }
528         }
529
530         return 0;
531 }
532
533 static int process_path(char *path, struct find_param *param)
534 {
535         char *fname, *dname;
536         DIR *dir;
537         int rc = 0;
538
539         fname = strrchr(path, '/');
540         if (fname != NULL && fname[1] == '\0') {
541                 /* Trailing '/', it must be a dir */
542                 *fname = '\0';
543                 dir = opendir(path);
544                 if (dir == NULL) {
545                         err_msg("\"%.40s\" opendir failed", path);
546                         rc = errno;
547                 } else {
548                         rc = process_dir(dir, path, param);
549                         closedir(dir);
550                 }
551         } else if ((dir = opendir(path)) != NULL) {
552                 /* No trailing '/', but it is still a dir */
553                 rc = process_dir(dir, path, param);
554                 closedir(dir);
555         } else {
556                 /* It must be a file (or other non-directory) */
557                 if (fname == NULL) {
558                         dname = ".";
559                         fname = path;
560                 } else {
561                         *fname = '\0';
562                         fname++;
563                         dname = path;
564                 }
565                 dir = opendir(dname);
566                 if (dir == NULL) {
567                         err_msg("\"%.40s\" opendir failed", dname);
568                         rc = errno;
569                 } else {
570                         if (!param->got_uuids)
571                                 rc = setup_obd_uuids(dir, dname, param);
572                         if (rc == 0)
573                                 rc = process_file(dir, dname, fname, param);
574                         closedir(dir);
575                 }
576         }
577
578         return rc;
579 }
580
581 int llapi_find(char *path, struct obd_uuid *obduuid, int recursive,
582                int verbose, int quiet)
583 {
584         struct find_param param;
585         int ret = 0;
586
587         memset(&param, 0, sizeof(param));
588         param.recursive = recursive;
589         param.verbose = verbose;
590         param.quiet = quiet;
591         if (obduuid) {
592                 param.obduuid = malloc(sizeof(*obduuid));
593                 if (param.obduuid == NULL) {
594                         ret = ENOMEM;
595                         goto out;
596                 }
597                 memcpy(param.obduuid, obduuid, sizeof(*obduuid));
598         }
599
600         ret = prepare_find(&param);
601         if (ret)
602                 goto out;
603
604         process_path(path, &param);
605 out:
606         cleanup_find(&param);
607         return ret;
608 }
609
610 #define MAX_STRING_SIZE 128
611 #define DEVICES_LIST "/proc/fs/lustre/devices"
612
613 int llapi_target_check(int type_num, char **obd_type, char *dir)
614 {
615         char buf[MAX_STRING_SIZE];
616         FILE *fp = fopen(DEVICES_LIST, "r");
617         int rc = 0;
618         int i;
619
620         if (fp == NULL) {
621                 fprintf(stderr, "error: %s opening "DEVICES_LIST"\n",
622                         strerror(rc =  errno));
623                 return rc;
624         }
625
626         while (fgets(buf, sizeof(buf), fp) != NULL) {
627                 char *obd_type_name = NULL;
628                 char *obd_name = NULL;
629                 char rawbuf[OBD_MAX_IOCTL_BUFFER];
630                 char *bufl = rawbuf;
631                 char *bufp = buf;
632                 int max = sizeof(rawbuf);
633                 struct obd_ioctl_data datal;
634                 struct obd_statfs osfs_buffer;
635
636                 while(bufp[0] == ' ')
637                         ++bufp;
638
639                 for(i = 0; i < 3; i++) {
640                         obd_type_name = strsep(&bufp, " ");
641                 }
642                 obd_name = strsep(&bufp, " ");
643
644                 memset(&osfs_buffer, 0, sizeof (osfs_buffer));
645
646                 memset(bufl, 0, sizeof(rawbuf));
647                 datal.ioc_pbuf1 = (char *)&osfs_buffer;
648                 datal.ioc_plen1 = sizeof(osfs_buffer);
649
650                 for (i = 0; i < type_num; i++)
651                         if (strcmp(obd_type_name, obd_type[i]) == 0) {
652                                 datal.ioc_inlbuf1 = obd_name;
653                                 datal.ioc_inllen1 = strlen(obd_name) + 1;
654
655                                 obd_ioctl_pack(&datal,&bufl,max);
656
657                                 rc = ioctl(dirfd(opendir(dir)), OBD_IOC_PING,
658                                            bufl);
659
660                                 if (rc) {
661                                         fprintf(stderr, "error: check %s: %s\n",
662                                                 obd_name, strerror(rc = errno));
663                                 } else {
664                                         printf("%s active.\n",obd_name);
665                                 }
666                         }
667
668         }
669         fclose(fp);
670         return rc;
671 }
672
673 #undef MAX_STRING_SIZE
674
675 int llapi_catinfo(char *dir, char *keyword, char *node_name)
676 {
677         char raw[OBD_MAX_IOCTL_BUFFER];
678         char out[LLOG_CHUNK_SIZE];
679         char *buf = raw;
680         struct obd_ioctl_data data;
681         char key[30];
682         DIR *root;
683         int rc;
684
685         sprintf(key, "%s", keyword);
686         memset(raw, 0, sizeof(buf));
687         memset(out, 0, sizeof(out));
688         data.ioc_inlbuf1 = key;
689         data.ioc_inllen1 = strlen(key) + 1;
690         if (node_name) {
691                 data.ioc_inlbuf2 = node_name;
692                 data.ioc_inllen2 = strlen(node_name) + 1;
693         }
694         data.ioc_pbuf1 = out;
695         data.ioc_plen1 = sizeof(out);
696         rc = obd_ioctl_pack(&data, &buf, sizeof(raw));
697         if (rc)
698                 return rc;
699
700         root = opendir(dir);
701         if (root == NULL) {
702                 err_msg("open %s failed", dir);
703                 return errno;
704         }
705
706         rc = ioctl(dirfd(root), OBD_IOC_LLOG_CATINFO, buf);
707         if (rc)
708                 err_msg("ioctl OBD_IOC_CATINFO failed");
709         else
710                 fprintf(stdout, "%s", data.ioc_pbuf1);
711
712         closedir(root);
713         return rc;
714 }
715
716 int llapi_is_lustre_mnttype(char *type)
717 {
718         return (strcmp(type,"lustre") == 0 || strcmp(type,"lustre_lite") == 0);
719 }