Whamcloud - gitweb
merge b_devel into HEAD. Includes:
[fs/lustre-release.git] / lustre / utils / obd.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: Andreas Dilger <adilger@clusterfs.com>
8  *   Author: Robert Read <rread@clusterfs.com>
9  *
10  *   This file is part of Lustre, http://www.lustre.org.
11  *
12  *   Lustre is free software; you can redistribute it and/or
13  *   modify it under the terms of version 2 of the GNU General Public
14  *   License as published by the Free Software Foundation.
15  *
16  *   Lustre is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Lustre; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  */
26
27
28 #include <stdlib.h>
29 #include <sys/ioctl.h>
30 #include <fcntl.h>
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <sys/stat.h>
35 #include <stdio.h>
36 #include <stdarg.h>
37 #include <signal.h>
38
39 #ifndef __KERNEL__
40 #include <liblustre.h>
41 #endif
42 #include <linux/lustre_lib.h>
43 #include <linux/lustre_idl.h>
44 #include <linux/lustre_dlm.h>
45 #include <linux/obd.h>          /* for struct lov_stripe_md */
46 #include <linux/obd_lov.h>      /* for IOC_LOV_SET_OSC_ACTIVE */
47 #include <linux/lustre_build_version.h>
48
49 #include <unistd.h>
50 #include <sys/un.h>
51 #include <time.h>
52 #include <sys/time.h>
53 #include <netinet/in.h>
54 #include <errno.h>
55 #include <string.h>
56
57 #include <asm/page.h>           /* needed for PAGE_SIZE - rread */
58
59 #define __KERNEL__
60 #include <linux/list.h>
61 #undef __KERNEL__
62
63 #include "obdctl.h"
64 #include <portals/ptlctl.h>
65 #include "parser.h"
66 #include <stdio.h>
67
68 #define SHMEM_STATS 1
69 #if SHMEM_STATS
70 # include <sys/ipc.h>
71 # include <sys/shm.h>
72
73 # define MAX_SHMEM_COUNT 1024
74 static long long *shared_counters;
75 static long long counter_snapshot[2][MAX_SHMEM_COUNT];
76 struct timeval prev_time;
77 #endif
78
79 uint64_t conn_addr = -1;
80 uint64_t conn_cookie;
81 char rawbuf[8192];
82 char *buf = rawbuf;
83 int max = sizeof(rawbuf);
84
85 static int thread;
86
87 union lsm_buffer {
88         char                 space [4096];
89         struct lov_stripe_md lsm;
90 } lsm_buffer;
91
92 static char *cmdname(char *func);
93
94 #define IOC_INIT(data)                                                  \
95 do {                                                                    \
96         memset(&data, 0, sizeof(data));                                 \
97         data.ioc_addr = conn_addr;                                      \
98         data.ioc_cookie = conn_cookie;                                  \
99 } while (0)
100
101 #define IOC_PACK(func, data)                                            \
102 do {                                                                    \
103         memset(buf, 0, sizeof(rawbuf));                                 \
104         if (obd_ioctl_pack(&data, &buf, max)) {                         \
105                 fprintf(stderr, "error: %s: invalid ioctl\n",           \
106                         cmdname(func));                                 \
107                 return -2;                                              \
108         }                                                               \
109 } while (0)
110
111 #define IOC_UNPACK(func, data)                                          \
112 do {                                                                    \
113         if (obd_ioctl_unpack(&data, buf, max)) {                        \
114                 fprintf(stderr, "error: %s: invalid reply\n",           \
115                         cmdname(func));                                 \
116                 return -2;                                              \
117         }                                                               \
118 } while (0)
119
120 char *obdo_print(struct obdo *obd)
121 {
122         char buf[1024];
123
124         sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64
125                 "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64
126                 "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n"
127                 "obdflags: %x\nnlink: %d,\nvalid %x\n",
128                 obd->o_id, obd->o_gr, obd->o_atime, obd->o_mtime, obd->o_ctime,
129                 obd->o_size, obd->o_blocks, obd->o_blksize, obd->o_mode,
130                 obd->o_uid, obd->o_gid, obd->o_flags, obd->o_obdflags,
131                 obd->o_nlink, obd->o_valid);
132         return strdup(buf);
133 }
134
135
136 #define BAD_VERBOSE (-999999999)
137
138 #define N2D_OFF 0x100      /* So we can tell between error codes and devices */
139
140 static int do_name2dev(char *func, char *name)
141 {
142         struct obd_ioctl_data data;
143         int rc;
144
145         IOC_INIT(data);
146
147         data.ioc_inllen1 = strlen(name) + 1;
148         data.ioc_inlbuf1 = name;
149
150         IOC_PACK(func, data);
151         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf);
152         if (rc < 0) {
153                 fprintf(stderr, "error: %s: %s - %s\n", cmdname(func),
154                         name, strerror(rc = errno));
155                 return rc;
156         }
157         IOC_UNPACK(func, data);
158
159         return data.ioc_dev + N2D_OFF;
160 }
161
162 /*
163  * resolve a device name to a device number.
164  * supports a number or name.
165  * FIXME: support UUID
166  */
167 static int parse_devname(char *func, char *name)
168 {
169         int rc;
170         int ret = -1;
171
172         if (!name)
173                 return ret;
174         if (name[0] == '$') {
175                 rc = do_name2dev(func, name + 1);
176                 if (rc >= N2D_OFF) {
177                         ret = rc - N2D_OFF;
178                         printf("%s is device %d\n", name, ret);
179                 } else {
180                         fprintf(stderr, "error: %s: %s: %s\n", cmdname(func),
181                                 name, "device not found");
182                 }
183         } else
184                 ret = strtoul(name, NULL, 0);
185
186         return ret;
187 }
188
189 static char *
190 lsm_string (struct lov_stripe_md *lsm)
191 {
192         static char buffer[4096];
193         char       *p = buffer;
194         int         space = sizeof (buffer);
195         int         i;
196         int         nob;
197
198         *p = 0;
199         space--;
200
201         nob = snprintf(p, space, LPX64, lsm->lsm_object_id);
202         p += nob;
203         space -= nob;
204
205         if (lsm->lsm_stripe_count != 0) {
206                 nob = snprintf (p, space, "=%u#%u@%d",
207                                 lsm->lsm_stripe_size,
208                                 lsm->lsm_stripe_count,
209                                 lsm->lsm_stripe_offset);
210                 p += nob;
211                 space -= nob;
212
213                 for (i = 0; i < lsm->lsm_stripe_count; i++) {
214                         nob = snprintf (p, space, ":"LPX64,
215                                         lsm->lsm_oinfo[i].loi_id);
216                         p += nob;
217                         space -= nob;
218                 }
219         }
220
221         if (space == 0) {                       /* probable overflow */
222                 fprintf (stderr, "lsm_string() overflowed buffer\n");
223                 abort ();
224         }
225
226         return (buffer);
227 }
228
229 static void
230 reset_lsmb (union lsm_buffer *lsmb)
231 {
232         memset (lsmb->space, 0, sizeof (lsmb->space));
233         lsmb->lsm.lsm_magic = LOV_MAGIC;
234 }
235
236 static int
237 parse_lsm (union lsm_buffer *lsmb, char *string)
238 {
239         struct lov_stripe_md *lsm = &lsmb->lsm;
240         char                 *end;
241         int                   i;
242
243         /*
244          * object_id[=size#count[@offset][:id]*]
245          */
246
247         reset_lsmb (lsmb);
248
249         lsm->lsm_object_id = strtoull (string, &end, 0);
250         if (end == string)
251                 return (-1);
252         string = end;
253
254         if (*string == 0)
255                 return (0);
256
257         if (*string != '=')
258                 return (-1);
259         string++;
260
261         lsm->lsm_stripe_size = strtoul (string, &end, 0);
262         if (end == string)
263                 return (-1);
264         string = end;
265
266         if (*string != '#')
267                 return (-1);
268         string++;
269
270         lsm->lsm_stripe_count = strtoul (string, &end, 0);
271         if (end == string)
272                 return (-1);
273         string = end;
274
275         if (*string == '@') {
276                 string++;
277                 lsm->lsm_stripe_offset = strtol (string, &end, 0);
278                 if (end == string)
279                         return (-1);
280                 string = end;
281         }
282
283         if (*string == 0)               /* don't have to specify obj ids */
284                 return (0);
285
286         for (i = 0; i < lsm->lsm_stripe_count; i++) {
287                 if (*string != ':')
288                         return (-1);
289                 string++;
290                 lsm->lsm_oinfo[i].loi_id = strtoull (string, &end, 0);
291                 string = end;
292         }
293
294         if (*string != 0)
295                 return (-1);
296
297         return (0);
298 }
299
300 static char *cmdname(char *func)
301 {
302         static char buf[512];
303
304         if (thread) {
305                 sprintf(buf, "%s-%d", func, thread);
306                 return buf;
307         }
308
309         return func;
310 }
311
312 #define difftime(a, b)                                          \
313         ((double)(a)->tv_sec - (b)->tv_sec +                    \
314          ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
315
316 static int be_verbose(int verbose, struct timeval *next_time,
317                       __u64 num, __u64 *next_num, int num_total)
318 {
319         struct timeval now;
320
321         if (!verbose)
322                 return 0;
323
324         if (next_time != NULL)
325                 gettimeofday(&now, NULL);
326
327         /* A positive verbosity means to print every X iterations */
328         if (verbose > 0 &&
329             (next_num == NULL || num >= *next_num || num >= num_total)) {
330                 *next_num += verbose;
331                 if (next_time) {
332                         next_time->tv_sec = now.tv_sec - verbose;
333                         next_time->tv_usec = now.tv_usec;
334                 }
335                 return 1;
336         }
337
338         /* A negative verbosity means to print at most each X seconds */
339         if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){
340                 next_time->tv_sec = now.tv_sec - verbose;
341                 next_time->tv_usec = now.tv_usec;
342                 if (next_num)
343                         *next_num = num;
344                 return 1;
345         }
346
347         return 0;
348 }
349
350 static int get_verbose(char *func, const char *arg)
351 {
352         int verbose;
353         char *end;
354
355         if (!arg || arg[0] == 'v')
356                 verbose = 1;
357         else if (arg[0] == 's' || arg[0] == 'q')
358                 verbose = 0;
359         else {
360                 verbose = (int)strtoul(arg, &end, 0);
361                 if (*end) {
362                         fprintf(stderr, "error: %s: bad verbose option '%s'\n",
363                                 cmdname(func), arg);
364                         return BAD_VERBOSE;
365                 }
366         }
367
368         if (verbose < 0)
369                 printf("Print status every %d seconds\n", -verbose);
370         else if (verbose == 1)
371                 printf("Print status every operation\n");
372         else if (verbose > 1)
373                 printf("Print status every %d operations\n", verbose);
374
375         return verbose;
376 }
377
378 int do_disconnect(char *func, int verbose)
379 {
380         int rc;
381         struct obd_ioctl_data data;
382
383         if (conn_addr == -1)
384                 return 0;
385
386         IOC_INIT(data);
387
388         IOC_PACK(func, data);
389         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DISCONNECT, buf);
390         if (rc < 0) {
391                 fprintf(stderr, "error: %s: OPD_IOC_DISCONNECT %s\n",
392                         cmdname(func),strerror(errno));
393         } else {
394                 if (verbose)
395                         printf("%s: disconnected conn "LPX64"\n", cmdname(func),
396                                conn_addr);
397                 conn_addr = -1;
398         }
399
400         return rc;
401 }
402
403 #if SHMEM_STATS
404 static void shmem_setup(void)
405 {
406         /* Create new segment */
407         int shmid = shmget(IPC_PRIVATE, sizeof(counter_snapshot[0]), 0600);
408
409         if (shmid == -1) {
410                 fprintf(stderr, "Can't create shared memory counters: %s\n",
411                         strerror(errno));
412                 return;
413         }
414
415         /* Attatch to new segment */
416         shared_counters = (long long *)shmat(shmid, NULL, 0);
417
418         if (shared_counters == (long long *)(-1)) {
419                 fprintf(stderr, "Can't attach shared memory counters: %s\n",
420                         strerror(errno));
421                 shared_counters = NULL;
422                 return;
423         }
424
425         /* Mark segment as destroyed, so it will disappear when we exit.
426          * Forks will inherit attached segments, so we should be OK.
427          */
428         if (shmctl(shmid, IPC_RMID, NULL) == -1) {
429                 fprintf(stderr, "Can't destroy shared memory counters: %s\n",
430                         strerror(errno));
431         }
432 }
433
434 static inline void shmem_reset(void)
435 {
436         if (shared_counters == NULL)
437                 return;
438
439         memset(shared_counters, 0, sizeof(counter_snapshot[0]));
440         memset(counter_snapshot, 0, sizeof(counter_snapshot));
441         gettimeofday(&prev_time, NULL);
442 }
443
444 static inline void shmem_bump(void)
445 {
446         if (shared_counters == NULL || thread <= 0 || thread > MAX_SHMEM_COUNT)
447                 return;
448
449         shared_counters[thread - 1]++;
450 }
451
452 static void shmem_snap(int n)
453 {
454         struct timeval this_time;
455         int non_zero = 0;
456         long long total = 0;
457         double secs;
458         int i;
459
460         if (shared_counters == NULL || n > MAX_SHMEM_COUNT)
461                 return;
462
463         memcpy(counter_snapshot[1], counter_snapshot[0],
464                n * sizeof(counter_snapshot[0][0]));
465         memcpy(counter_snapshot[0], shared_counters,
466                n * sizeof(counter_snapshot[0][0]));
467         gettimeofday(&this_time, NULL);
468
469         for (i = 0; i < n; i++) {
470                 long long this_count =
471                         counter_snapshot[0][i] - counter_snapshot[1][i];
472
473                 if (this_count != 0) {
474                         non_zero++;
475                         total += this_count;
476                 }
477         }
478
479         secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) -
480                 (prev_time.tv_sec + prev_time.tv_usec / 1000000.0);
481
482         printf("%d/%d Total: %f/second\n", non_zero, n, total / secs);
483
484         prev_time = this_time;
485 }
486
487 #define SHMEM_SETUP()   shmem_setup()
488 #define SHMEM_RESET()   shmem_reset()
489 #define SHMEM_BUMP()    shmem_bump()
490 #define SHMEM_SNAP(n)   shmem_snap(n)
491 #else
492 #define SHMEM_SETUP()
493 #define SHMEM_RESET()
494 #define SHMEM_BUMP()
495 #define SHMEM_SNAP(n)
496 #endif
497
498 extern command_t cmdlist[];
499
500 static int do_device(char *func, int dev)
501 {
502         struct obd_ioctl_data data;
503
504         memset(&data, 0, sizeof(data));
505
506         data.ioc_dev = dev;
507
508         IOC_PACK(func, data);
509         return l_ioctl(OBD_DEV_ID, OBD_IOC_DEVICE, buf);
510 }
511
512 int jt_obd_device(int argc, char **argv)
513 {
514         int rc, dev;
515         do_disconnect(argv[0], 1);
516
517         if (argc != 2)
518                 return CMD_HELP;
519
520         dev = parse_devname(argv[0], argv[1]);
521         if (dev < 0)
522                 return -1;
523
524         rc = do_device(argv[0], dev);
525         if (rc < 0)
526                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
527                         strerror(rc = errno));
528
529         return rc;
530 }
531
532 int jt_obd_connect(int argc, char **argv)
533 {
534         struct obd_ioctl_data data;
535         int rc;
536
537         IOC_INIT(data);
538
539         do_disconnect(argv[0], 1);
540
541         /* XXX TODO: implement timeout per lctl usage for probe */
542         if (argc != 1)
543                 return CMD_HELP;
544
545         IOC_PACK(argv[0], data);
546         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CONNECT, buf);
547         IOC_UNPACK(argv[0], data);
548         if (rc < 0)
549                 fprintf(stderr, "error: %s: OBD_IOC_CONNECT %s\n",
550                         cmdname(argv[0]), strerror(rc = errno));
551         else {
552                 conn_addr = data.ioc_addr;
553                 conn_cookie = data.ioc_cookie;
554         }
555         return rc;
556 }
557
558 int jt_obd_disconnect(int argc, char **argv)
559 {
560         if (argc != 1)
561                 return CMD_HELP;
562
563         if (conn_addr == -1)
564                 return 0;
565
566         return do_disconnect(argv[0], 0);
567 }
568
569 int jt_opt_device(int argc, char **argv)
570 {
571         char *arg2[3];
572         int ret;
573         int rc;
574
575         if (argc < 3)
576                 return CMD_HELP;
577
578         rc = do_device("device", parse_devname(argv[0], argv[1]));
579
580         if (!rc) {
581                 arg2[0] = "connect";
582                 arg2[1] = NULL;
583                 rc = jt_obd_connect(1, arg2);
584         }
585
586         if (!rc)
587                 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
588
589         ret = do_disconnect(argv[0], 0);
590         if (!rc)
591                 rc = ret;
592
593         return rc;
594 }
595
596 int jt_opt_threads(int argc, char **argv)
597 {
598         __u64 threads, next_thread;
599         int verbose;
600         int rc = 0;
601         char *end;
602         int i;
603
604         if (argc < 5)
605                 return CMD_HELP;
606
607         threads = strtoull(argv[1], &end, 0);
608         if (*end) {
609                 fprintf(stderr, "error: %s: invalid page count '%s'\n",
610                         cmdname(argv[0]), argv[1]);
611                 return CMD_HELP;
612         }
613
614         verbose = get_verbose(argv[0], argv[2]);
615         if (verbose == BAD_VERBOSE)
616                 return CMD_HELP;
617
618         if (verbose != 0)
619                 printf("%s: starting "LPD64" threads on device %s running %s\n",
620                        argv[0], threads, argv[3], argv[4]);
621
622         SHMEM_RESET();
623
624         for (i = 1, next_thread = verbose; i <= threads; i++) {
625                 rc = fork();
626                 if (rc < 0) {
627                         fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
628                                 strerror(rc = errno));
629                         break;
630                 } else if (rc == 0) {
631                         thread = i;
632                         argv[2] = "--device";
633                         return jt_opt_device(argc - 2, argv + 2);
634                 } else if (be_verbose(verbose, NULL, i, &next_thread, threads))
635                         printf("%s: thread #%d (PID %d) started\n",
636                                argv[0], i, rc);
637                 rc = 0;
638         }
639
640         if (!thread) {          /* parent process */
641                 int live_threads = threads;
642
643                 while (live_threads > 0) {
644                         int status;
645                         pid_t ret;
646
647                         ret = waitpid(0, &status, verbose < 0 ? WNOHANG : 0);
648                         if (ret == 0) {
649                                 if (verbose >= 0)
650                                         abort();
651
652                                 sleep(-verbose);
653                                 SHMEM_SNAP(threads);
654                                 continue;
655                         }
656
657                         if (ret < 0) {
658                                 fprintf(stderr, "error: %s: wait - %s\n",
659                                         argv[0], strerror(errno));
660                                 if (!rc)
661                                         rc = errno;
662                         } else {
663                                 /*
664                                  * This is a hack.  We _should_ be able to use
665                                  * WIFEXITED(status) to see if there was an
666                                  * error, but it appears to be broken and it
667                                  * always returns 1 (OK).  See wait(2).
668                                  */
669                                 int err = WEXITSTATUS(status);
670                                 if (err || WIFSIGNALED(status))
671                                         fprintf(stderr,
672                                                 "%s: PID %d had rc=%d\n",
673                                                 argv[0], ret, err);
674                                 if (!rc)
675                                         rc = err;
676
677                                 live_threads--;
678                         }
679                 }
680         }
681
682         return rc;
683 }
684
685 int jt_obd_detach(int argc, char **argv)
686 {
687         struct obd_ioctl_data data;
688         int rc;
689
690         IOC_INIT(data);
691
692         if (argc != 1)
693                 return CMD_HELP;
694
695         IOC_PACK(argv[0], data);
696         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DETACH, buf);
697         if (rc < 0)
698                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
699                         strerror(rc = errno));
700
701         return rc;
702 }
703
704 int jt_obd_cleanup(int argc, char **argv)
705 {
706         struct obd_ioctl_data data;
707         char force = 'F';
708         int rc;
709
710         IOC_INIT(data);
711
712         if (argc != 1 && argc != 2)
713                 return CMD_HELP;
714
715         if (argc == 2) {
716                 if (strcmp(argv[1], "force"))
717                         return CMD_HELP;
718                 data.ioc_inllen1 = 1;
719                 data.ioc_inlbuf1 = &force;
720         }
721
722         IOC_PACK(argv[0], data);
723         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEANUP, buf);
724         if (rc < 0)
725                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
726                         strerror(rc = errno));
727
728         return rc;
729 }
730
731 int jt_obd_no_transno(int argc, char **argv)
732 {
733         struct obd_ioctl_data data;
734         int rc;
735
736         IOC_INIT(data);
737
738         if (argc != 1)
739                 return CMD_HELP;
740
741         IOC_PACK(argv[0], data);
742         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf);
743         if (rc < 0)
744                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
745                         strerror(rc = errno));
746
747         return rc;
748 }
749
750 int jt_obd_set_readonly(int argc, char **argv)
751 {
752         struct obd_ioctl_data data;
753         int rc;
754
755         IOC_INIT(data);
756
757         if (argc != 1)
758                 return CMD_HELP;
759
760         IOC_PACK(argv[0], data);
761         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf);
762         if (rc < 0)
763                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
764                         strerror(rc = errno));
765
766         return rc;
767 }
768
769 int jt_obd_newdev(int argc, char **argv)
770 {
771         int rc;
772         struct obd_ioctl_data data;
773
774         IOC_INIT(data);
775
776         if (argc != 1)
777                 return CMD_HELP;
778
779         IOC_PACK(argv[0], data);
780         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NEWDEV, buf);
781         if (rc < 0)
782                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
783                         strerror(rc = errno));
784         else {
785                 IOC_UNPACK(argv[0], data);
786                 printf("Current device set to %d\n", data.ioc_dev);
787         }
788
789         return rc;
790 }
791
792 int jt_get_version(int argc, char **argv)
793 {
794         int rc;
795         char buf[8192];
796         struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
797
798         if (argc != 1)
799                 return CMD_HELP;
800
801         memset(buf, 0, sizeof(buf));
802         data->ioc_version = OBD_IOCTL_VERSION;
803         data->ioc_addr = conn_addr;
804         data->ioc_cookie = conn_addr;
805         data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
806         data->ioc_len = obd_ioctl_packlen(data);
807
808         rc = l_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf);
809         if (rc < 0)
810                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
811                         strerror(rc = errno));
812         else {
813                 printf("Lustre version: %s\n", data->ioc_bulk);
814         }
815
816         printf("lctl   version: %s\n", BUILD_VERSION);
817         return rc;
818 }
819
820 int jt_obd_list(int argc, char **argv)
821 {
822         int rc;
823         char buf[8192];
824         struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
825
826         if (argc != 1)
827                 return CMD_HELP;
828
829         memset(buf, 0, sizeof(buf));
830         data->ioc_version = OBD_IOCTL_VERSION;
831         data->ioc_addr = conn_addr;
832         data->ioc_cookie = conn_addr;
833         data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
834         data->ioc_len = obd_ioctl_packlen(data);
835
836         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
837         if (rc < 0)
838                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
839                         strerror(rc = errno));
840         else {
841                 printf("%s", data->ioc_bulk);
842         }
843
844         return rc;
845 }
846
847 int jt_obd_attach(int argc, char **argv)
848 {
849         struct obd_ioctl_data data;
850         int rc;
851
852         IOC_INIT(data);
853
854         if (argc != 2 && argc != 3 && argc != 4)
855                 return CMD_HELP;
856
857         data.ioc_inllen1 = strlen(argv[1]) + 1;
858         data.ioc_inlbuf1 = argv[1];
859         if (argc >= 3) {
860                 data.ioc_inllen2 = strlen(argv[2]) + 1;
861                 data.ioc_inlbuf2 = argv[2];
862         }
863
864         if (argc == 4) {
865                 data.ioc_inllen3 = strlen(argv[3]) + 1;
866                 data.ioc_inlbuf3 = argv[3];
867         }
868
869         IOC_PACK(argv[0], data);
870         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ATTACH, buf);
871         if (rc < 0)
872                 fprintf(stderr, "error: %s: OBD_IOC_ATTACH %s\n",
873                         cmdname(argv[0]), strerror(rc = errno));
874         else if (argc == 3) {
875                 char name[1024];
876                 if (strlen(argv[2]) > 128) {
877                         printf("Name too long to set environment\n");
878                         return -EINVAL;
879                 }
880                 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
881                 rc = setenv(name, argv[1], 1);
882                 if (rc) {
883                         printf("error setting env variable %s\n", name);
884                 }
885         }
886
887         return rc;
888 }
889
890 int jt_obd_name2dev(int argc, char **argv)
891 {
892         int rc;
893
894         if (argc != 2)
895                 return CMD_HELP;
896
897         rc = do_name2dev(argv[0], argv[1]);
898         if (rc >= N2D_OFF) {
899                 int dev = rc - N2D_OFF;
900                 rc = do_device(argv[0], dev);
901                 if (rc == 0)
902                         printf("%d\n", dev);
903         }
904         return rc;
905 }
906
907 int jt_obd_setup(int argc, char **argv)
908 {
909         struct obd_ioctl_data data;
910         int rc;
911
912         IOC_INIT(data);
913
914         if (argc > 4)
915                 return CMD_HELP;
916
917         data.ioc_dev = -1;
918         if (argc > 1) {
919                 data.ioc_dev = parse_devname(argv[0], argv[1]);
920                 if (data.ioc_dev < 0)
921                         return -1;
922                 data.ioc_inllen1 = strlen(argv[1]) + 1;
923                 data.ioc_inlbuf1 = argv[1];
924         }
925         if (argc > 2) {
926                 data.ioc_inllen2 = strlen(argv[2]) + 1;
927                 data.ioc_inlbuf2 = argv[2];
928         }
929         if (argc > 3) {
930                 data.ioc_inllen3 = strlen(argv[3]) + 1;
931                 data.ioc_inlbuf3 = argv[3];
932         }
933
934         IOC_PACK(argv[0], data);
935         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETUP, buf);
936         if (rc < 0)
937                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
938                         strerror(rc = errno));
939
940         return rc;
941 }
942
943 /* Get echo client's stripe meta-data for the given object
944  */
945 int jt_obd_get_stripe (int argc, char **argv)
946 {
947         struct obd_ioctl_data data;
948         __u64 id;
949         int   rc;
950         char *end;
951
952         if (argc != 2)
953                 return (CMD_HELP);
954
955         id = strtoull (argv[1], &end, 0);
956         if (*end) {
957                 fprintf (stderr, "Error: %s: invalid object id '%s'\n",
958                          cmdname (argv[0]), argv[1]);
959                 return (CMD_HELP);
960         }
961
962         memset (&lsm_buffer, 0, sizeof (lsm_buffer));
963
964         IOC_INIT (data);
965         data.ioc_obdo1.o_id = id;
966         data.ioc_obdo1.o_mode = S_IFREG | 0644;
967         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
968         data.ioc_pbuf1 = (char *)&lsm_buffer;
969         data.ioc_plen1 = sizeof (lsm_buffer);
970
971         IOC_PACK(argv[0], data);
972         rc = l_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf);
973         IOC_UNPACK(argv[0], data);
974
975         if (rc != 0) {
976                 fprintf (stderr, "Error: %s: rc %d(%s)\n",
977                          cmdname (argv[0]), rc, strerror (errno));
978                 return (rc);
979         }
980
981         printf ("%s\n", lsm_string (&lsm_buffer.lsm));
982
983         return (rc);
984 }
985
986 /* Set stripe meta-data for 1 or more objects.  Object must be new to
987  * this echo client instance.
988  */
989 int jt_obd_set_stripe (int argc, char **argv)
990 {
991         struct obd_ioctl_data data;
992         char *end;
993         int count = 1;
994         int i;
995         int rc;
996
997         if (argc < 2 || argc > 3)
998                 return CMD_HELP;
999
1000         rc = parse_lsm (&lsm_buffer, argv[1]);
1001         if (rc != 0) {
1002                 fprintf (stderr, "error: %s: invalid object '%s'\n",
1003                          cmdname (argv[0]), argv[1]);
1004                 return CMD_HELP;
1005         }
1006
1007         if (argc > 2) {
1008                 count = strtol (argv[2], &end, 0);
1009                 if (*end != 0) {
1010                         fprintf (stderr, "error: %s: invalid count '%s'\n",
1011                                  cmdname (argv[0]), argv[1]);
1012                         return CMD_HELP;
1013                 }
1014         }
1015
1016         for (i = 0; i < count; i++) {
1017                 IOC_INIT (data);
1018                 data.ioc_obdo1.o_id = lsm_buffer.lsm.lsm_object_id + i;
1019                 data.ioc_obdo1.o_mode = S_IFREG | 0644;
1020                 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
1021                 data.ioc_pbuf1 = (char *)&lsm_buffer;
1022                 data.ioc_plen1 = sizeof (lsm_buffer);
1023
1024                 IOC_PACK (argv[0], data);
1025                 rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
1026                 IOC_UNPACK (argv[0], data);
1027
1028                 if (rc != 0) {
1029                         fprintf (stderr, "Error: %s: rc %d(%s)\n",
1030                                  cmdname (argv[0]), rc, strerror (errno));
1031                         return (rc);
1032                 }
1033         }
1034
1035         return (0);
1036 }
1037
1038 /* Clear stripe meta-data info for an object on this echo-client instance
1039  */
1040 int jt_obd_unset_stripe (int argc, char **argv)
1041 {
1042         struct obd_ioctl_data data;
1043         char *end;
1044         obd_id id;
1045         int rc;
1046
1047         if (argc != 2)
1048                 return CMD_HELP;
1049
1050         id = strtoll (argv[1], &end, 0);
1051         if (*end == 0) {
1052                 fprintf (stderr, "error: %s: invalid object id '%s'\n",
1053                          cmdname (argv[0]), argv[1]);
1054                 return CMD_HELP;
1055         }
1056
1057         IOC_INIT (data);
1058         data.ioc_obdo1.o_id = lsm_buffer.lsm.lsm_object_id;
1059         data.ioc_obdo1.o_mode = S_IFREG | 0644;
1060         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
1061
1062         IOC_PACK (argv[0], data);
1063         rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
1064         IOC_UNPACK (argv[0], data);
1065
1066         if (rc != 0)
1067                 fprintf (stderr, "Error: %s: rc %d(%s)\n",
1068                          cmdname (argv[0]), rc, strerror (errno));
1069
1070         return (0);
1071 }
1072
1073 /* Create one or more objects, arg[1] may describe stripe meta-data.  If
1074  * not, defaults assumed.  This echo-client instances stashes the stripe
1075  * object ids.  Use get_stripe on this node to print full lsm and
1076  * set_stripe on another node to cut/paste between nodes.
1077  */
1078 int jt_obd_create(int argc, char **argv)
1079 {
1080         static __u64 base_id = 1;
1081
1082         struct obd_ioctl_data data;
1083         struct timeval next_time;
1084         __u64 count = 1, next_count;
1085         int verbose = 1, mode = 0100644, rc = 0, i;
1086         char *end;
1087
1088         IOC_INIT(data);
1089         if (argc < 2 || argc > 5)
1090                 return CMD_HELP;
1091
1092         count = strtoull(argv[1], &end, 0);
1093         if (*end) {
1094                 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1095                         cmdname(argv[0]), argv[1]);
1096                 return CMD_HELP;
1097         }
1098
1099         if (argc > 2) {
1100                 mode = strtoul(argv[2], &end, 0);
1101                 if (*end) {
1102                         fprintf(stderr, "error: %s: invalid mode '%s'\n",
1103                                 cmdname(argv[0]), argv[2]);
1104                         return CMD_HELP;
1105                 }
1106                 if (!(mode & S_IFMT))
1107                         mode |= S_IFREG;
1108         }
1109
1110         if (argc > 3) {
1111                 verbose = get_verbose(argv[0], argv[3]);
1112                 if (verbose == BAD_VERBOSE)
1113                         return CMD_HELP;
1114         }
1115
1116         if (argc < 5)
1117                 reset_lsmb (&lsm_buffer);       /* will set default */
1118         else {
1119                 rc = parse_lsm (&lsm_buffer, argv[4]);
1120                 if (rc != 0) {
1121                         fprintf(stderr, "error: %s: invalid lsm '%s'\n",
1122                                 cmdname(argv[0]), argv[4]);
1123                         return CMD_HELP;
1124                 }
1125                 base_id = lsm_buffer.lsm.lsm_object_id;
1126         }
1127
1128         printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
1129         gettimeofday(&next_time, NULL);
1130         next_time.tv_sec -= verbose;
1131
1132         for (i = 1, next_count = verbose; i <= count; i++) {
1133                 data.ioc_obdo1.o_mode = mode;
1134                 data.ioc_obdo1.o_id = base_id++;
1135                 data.ioc_obdo1.o_uid = 0;
1136                 data.ioc_obdo1.o_gid = 0;
1137                 data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE |
1138                                          OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;
1139
1140                 data.ioc_plen1 = sizeof (lsm_buffer);
1141                 data.ioc_pbuf1 = (char *)&lsm_buffer;
1142
1143                 IOC_PACK(argv[0], data);
1144                 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf);
1145                 IOC_UNPACK(argv[0], data);
1146                 SHMEM_BUMP();
1147                 if (rc < 0) {
1148                         fprintf(stderr, "error: %s: #%d - %s\n",
1149                                 cmdname(argv[0]), i, strerror(rc = errno));
1150                         break;
1151                 }
1152                 if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) {
1153                         fprintf(stderr, "error: %s: objid not valid #%d:%08x\n",
1154                                 cmdname(argv[0]), i, data.ioc_obdo1.o_valid);
1155                         rc = EINVAL;
1156                         break;
1157                 }
1158
1159                 if (be_verbose(verbose, &next_time, i, &next_count, count))
1160                         printf("%s: #%d is object id "LPX64"\n",
1161                                 cmdname(argv[0]), i, data.ioc_obdo1.o_id);
1162         }
1163         return rc;
1164 }
1165
1166 int jt_obd_setattr(int argc, char **argv)
1167 {
1168         struct obd_ioctl_data data;
1169         char *end;
1170         int rc;
1171
1172         IOC_INIT(data);
1173         if (argc != 2)
1174                 return CMD_HELP;
1175
1176         data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1177         if (*end) {
1178                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1179                         cmdname(argv[0]), argv[1]);
1180                 return CMD_HELP;
1181         }
1182         data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0);
1183         if (*end) {
1184                 fprintf(stderr, "error: %s: invalid mode '%s'\n",
1185                         cmdname(argv[0]), argv[2]);
1186                 return CMD_HELP;
1187         }
1188         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
1189
1190         IOC_PACK(argv[0], data);
1191         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf);
1192         if (rc < 0)
1193                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1194                         strerror(rc = errno));
1195
1196         return rc;
1197 }
1198
1199 int jt_obd_destroy(int argc, char **argv)
1200 {
1201         struct obd_ioctl_data data;
1202         struct timeval next_time;
1203         __u64 count = 1, next_count;
1204         int verbose = 1;
1205         __u64 id;
1206         char *end;
1207         int rc = 0, i;
1208
1209         IOC_INIT(data);
1210         if (argc < 2 || argc > 4)
1211                 return CMD_HELP;
1212
1213         id = strtoull(argv[1], &end, 0);
1214         if (*end) {
1215                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1216                         cmdname(argv[0]), argv[1]);
1217                 return CMD_HELP;
1218         }
1219         if (argc > 2) {
1220                 count = strtoull(argv[2], &end, 0);
1221                 if (*end) {
1222                         fprintf(stderr,
1223                                 "error: %s: invalid iteration count '%s'\n",
1224                                 cmdname(argv[0]), argv[2]);
1225                         return CMD_HELP;
1226                 }
1227         }
1228
1229         if (argc > 3) {
1230                 verbose = get_verbose(argv[0], argv[3]);
1231                 if (verbose == BAD_VERBOSE)
1232                         return CMD_HELP;
1233         }
1234
1235         printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
1236         gettimeofday(&next_time, NULL);
1237         next_time.tv_sec -= verbose;
1238
1239         for (i = 1, next_count = verbose; i <= count; i++, id++) {
1240                 data.ioc_obdo1.o_id = id;
1241                 data.ioc_obdo1.o_mode = S_IFREG | 0644;
1242                 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
1243
1244                 IOC_PACK(argv[0], data);
1245                 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf);
1246                 IOC_UNPACK(argv[0], data);
1247                 SHMEM_BUMP();
1248                 if (rc < 0) {
1249                         fprintf(stderr, "error: %s: objid "LPX64": %s\n",
1250                                 cmdname(argv[0]), id, strerror(rc = errno));
1251                         break;
1252                 }
1253
1254                 if (be_verbose(verbose, &next_time, i, &next_count, count))
1255                         printf("%s: #%d is object id "LPX64"\n",
1256                                cmdname(argv[0]), i, id);
1257         }
1258
1259         return rc;
1260 }
1261
1262 int jt_obd_getattr(int argc, char **argv)
1263 {
1264         struct obd_ioctl_data data;
1265         char *end;
1266         int rc;
1267
1268         if (argc != 2)
1269                 return CMD_HELP;
1270
1271         IOC_INIT(data);
1272         data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1273         if (*end) {
1274                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1275                         cmdname(argv[0]), argv[1]);
1276                 return CMD_HELP;
1277         }
1278         /* to help obd filter */
1279         data.ioc_obdo1.o_mode = 0100644;
1280         data.ioc_obdo1.o_valid = 0xffffffff;
1281         printf("%s: object id "LPX64"\n", cmdname(argv[0]),data.ioc_obdo1.o_id);
1282
1283         IOC_PACK(argv[0], data);
1284         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf);
1285         IOC_UNPACK(argv[0], data);
1286         if (rc) {
1287                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1288                         strerror(rc = errno));
1289         } else {
1290                 printf("%s: object id "LPX64", mode %o\n", cmdname(argv[0]),
1291                        data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
1292         }
1293         return rc;
1294 }
1295
1296 int jt_obd_test_getattr(int argc, char **argv)
1297 {
1298         struct obd_ioctl_data data;
1299         struct timeval start, next_time;
1300         __u64 i, count, next_count;
1301         int verbose = 1;
1302         obd_id objid = 3;
1303         char *end;
1304         int rc = 0;
1305
1306         if (argc < 2 && argc > 4)
1307                 return CMD_HELP;
1308
1309         IOC_INIT(data);
1310         count = strtoull(argv[1], &end, 0);
1311         if (*end) {
1312                 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1313                         cmdname(argv[0]), argv[1]);
1314                 return CMD_HELP;
1315         }
1316
1317         if (argc >= 3) {
1318                 verbose = get_verbose(argv[0], argv[2]);
1319                 if (verbose == BAD_VERBOSE)
1320                         return CMD_HELP;
1321         }
1322
1323         if (argc >= 4) {
1324                 if (argv[3][0] == 't') {
1325                         objid = strtoull(argv[3] + 1, &end, 0);
1326                         if (thread)
1327                                 objid += thread - 1;
1328                 } else
1329                         objid = strtoull(argv[3], &end, 0);
1330                 if (*end) {
1331                         fprintf(stderr, "error: %s: invalid objid '%s'\n",
1332                                 cmdname(argv[0]), argv[3]);
1333                         return CMD_HELP;
1334                 }
1335         }
1336
1337         gettimeofday(&start, NULL);
1338         next_time.tv_sec = start.tv_sec - verbose;
1339         next_time.tv_usec = start.tv_usec;
1340         if (verbose != 0)
1341                 printf("%s: getting "LPD64" attrs (objid "LPX64"): %s",
1342                        cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
1343
1344         for (i = 1, next_count = verbose; i <= count; i++) {
1345                 data.ioc_obdo1.o_id = objid;
1346                 data.ioc_obdo1.o_mode = S_IFREG;
1347                 data.ioc_obdo1.o_valid = 0xffffffff;
1348                 IOC_PACK(argv[0], data);
1349                 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data);
1350                 SHMEM_BUMP();
1351                 if (rc < 0) {
1352                         fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n",
1353                                 cmdname(argv[0]), i, errno, strerror(rc = errno));
1354                         break;
1355                 } else {
1356                         if (be_verbose
1357                             (verbose, &next_time, i, &next_count, count))
1358                                 printf("%s: got attr #"LPD64"\n",
1359                                        cmdname(argv[0]), i);
1360                 }
1361         }
1362
1363         if (!rc) {
1364                 struct timeval end;
1365                 double diff;
1366
1367                 gettimeofday(&end, NULL);
1368
1369                 diff = difftime(&end, &start);
1370
1371                 --i;
1372                 if (verbose != 0)
1373                         printf("%s: "LPD64" attrs in %.4gs (%.4g attr/s): %s",
1374                                cmdname(argv[0]), i, diff, (double)i / diff,
1375                                ctime(&end.tv_sec));
1376         }
1377         return rc;
1378 }
1379
1380 int jt_obd_test_brw(int argc, char **argv)
1381 {
1382         struct obd_ioctl_data data;
1383         struct timeval start, next_time;
1384         int pages = 1;
1385         __u64 count, next_count;
1386         __u64 objid = 3;
1387         int verbose = 1, write = 0, rw;
1388         char *end;
1389         int thr_offset = 0;
1390         int i;
1391         int len;
1392         int rc = 0;
1393
1394         if (argc < 2 || argc > 6) {
1395                 fprintf(stderr, "error: %s: bad number of arguments: %d\n",
1396                         cmdname(argv[0]), argc);
1397                 return CMD_HELP;
1398         }
1399
1400         /* make each thread write to a different offset */
1401         if (argv[1][0] == 't') {
1402                 count = strtoull(argv[1] + 1, &end, 0);
1403                 if (thread)
1404                         thr_offset = thread - 1;
1405         } else
1406                 count = strtoull(argv[1], &end, 0);
1407
1408         if (*end) {
1409                 fprintf(stderr, "error: %s: bad iteration count '%s'\n",
1410                         cmdname(argv[0]), argv[1]);
1411                 return CMD_HELP;
1412         }
1413
1414         if (argc >= 3) {
1415                 if (argv[2][0] == 'w' || argv[2][0] == '1')
1416                         write = 1;
1417                 else if (argv[2][0] == 'r' || argv[2][0] == '0')
1418                         write = 0;
1419         }
1420
1421         if (argc >= 4) {
1422                 verbose = get_verbose(argv[0], argv[3]);
1423                 if (verbose == BAD_VERBOSE)
1424                         return CMD_HELP;
1425         }
1426
1427         if (argc >= 5) {
1428                 pages = strtoul(argv[4], &end, 0);
1429                 if (*end) {
1430                         fprintf(stderr, "error: %s: bad page count '%s'\n",
1431                                 cmdname(argv[0]), argv[4]);
1432                         return CMD_HELP;
1433                 }
1434         }
1435         if (argc >= 6) {
1436                 if (argv[5][0] == 't') {
1437                         objid = strtoull(argv[5] + 1, &end, 0);
1438                         if (thread)
1439                                 objid += thread - 1;
1440                 } else
1441                         objid = strtoull(argv[5], &end, 0);
1442                 if (*end) {
1443                         fprintf(stderr, "error: %s: bad objid '%s'\n",
1444                                 cmdname(argv[0]), argv[5]);
1445                         return CMD_HELP;
1446                 }
1447         }
1448
1449         len = pages * PAGE_SIZE;
1450
1451         IOC_INIT(data);
1452         data.ioc_obdo1.o_id = objid;
1453         data.ioc_obdo1.o_mode = S_IFREG;
1454         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
1455         data.ioc_count = len;
1456         data.ioc_offset = thr_offset * len * count;
1457
1458         gettimeofday(&start, NULL);
1459         next_time.tv_sec = start.tv_sec - verbose;
1460         next_time.tv_usec = start.tv_usec;
1461
1462         if (verbose != 0)
1463                 printf("%s: %s "LPU64"x%d pages (obj "LPX64", off "LPU64"): %s",
1464                        cmdname(argv[0]), write ? "writing" : "reading", count,
1465                        pages, objid, data.ioc_offset, ctime(&start.tv_sec));
1466
1467         IOC_PACK(argv[0], data);
1468         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_OPEN, buf);
1469         IOC_UNPACK(argv[0], data);
1470         if (rc) {
1471                 fprintf(stderr, "error: brw_open: %s\n", strerror(rc = errno));
1472                 return rc;
1473         }
1474
1475         rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
1476         for (i = 1, next_count = verbose; i <= count; i++) {
1477                 rc = l_ioctl(OBD_DEV_ID, rw, buf);
1478                 SHMEM_BUMP();
1479                 if (rc) {
1480                         fprintf(stderr, "error: %s: #%d - %s on %s\n",
1481                                 cmdname(argv[0]), i, strerror(rc = errno),
1482                                 write ? "write" : "read");
1483                         break;
1484                 } else if (be_verbose(verbose, &next_time,i, &next_count,count))
1485                         printf("%s: %s number %dx%d\n", cmdname(argv[0]),
1486                                write ? "write" : "read", i, pages);
1487
1488                 data.ioc_offset += len;
1489         }
1490
1491         if (!rc) {
1492                 struct timeval end;
1493                 double diff;
1494
1495                 gettimeofday(&end, NULL);
1496
1497                 diff = difftime(&end, &start);
1498
1499                 --i;
1500                 if (verbose != 0)
1501                         printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s",
1502                                cmdname(argv[0]), write ? "wrote" : "read",
1503                                i, pages, diff, (double)i * pages / diff,
1504                                ctime(&end.tv_sec));
1505         }
1506         rw = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE, buf);
1507         if (rw) {
1508                 fprintf(stderr, "error: brw_close: %s\n", strerror(rw = errno));
1509                 if (!rc)
1510                         rc = rw;
1511         }
1512
1513         return rc;
1514 }
1515
1516 int jt_obd_lov_setconfig(int argc, char **argv)
1517 {
1518         struct obd_ioctl_data data;
1519         struct lov_desc desc;
1520         struct obd_uuid *uuidarray, *ptr;
1521         int rc, i;
1522         char *end;
1523
1524         IOC_INIT(data);
1525
1526         if (argc <= 6)
1527                 return CMD_HELP;
1528
1529         if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
1530                 fprintf(stderr,
1531                         "error: %s: LOV uuid '%s' longer than "LPSZ" chars\n",
1532                         cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
1533                 return -EINVAL;
1534         }
1535
1536         memset(&desc, 0, sizeof(desc));
1537         obd_str2uuid(&desc.ld_uuid, argv[1]);
1538         desc.ld_tgt_count = argc - 6;
1539         desc.ld_default_stripe_count = strtoul(argv[2], &end, 0);
1540         if (*end) {
1541                 fprintf(stderr, "error: %s: bad default stripe count '%s'\n",
1542                         cmdname(argv[0]), argv[2]);
1543                 return CMD_HELP;
1544         }
1545         if (desc.ld_default_stripe_count > desc.ld_tgt_count) {
1546                 fprintf(stderr,
1547                         "error: %s: default stripe count %u > OST count %u\n",
1548                         cmdname(argv[0]), desc.ld_default_stripe_count,
1549                         desc.ld_tgt_count);
1550                 return -EINVAL;
1551         }
1552
1553         desc.ld_default_stripe_size = strtoull(argv[3], &end, 0);
1554         if (*end) {
1555                 fprintf(stderr, "error: %s: bad default stripe size '%s'\n",
1556                         cmdname(argv[0]), argv[3]);
1557                 return CMD_HELP;
1558         }
1559         if (desc.ld_default_stripe_size < 4096) {
1560                 fprintf(stderr,
1561                         "error: %s: default stripe size "LPU64" too small\n",
1562                         cmdname(argv[0]), desc.ld_default_stripe_size);
1563                 return -EINVAL;
1564         } else if ((long)desc.ld_default_stripe_size <
1565                    desc.ld_default_stripe_size) {
1566                 fprintf(stderr,
1567                         "error: %s: default stripe size "LPU64" too large\n",
1568                         cmdname(argv[0]), desc.ld_default_stripe_size);
1569                 return -EINVAL;
1570         }
1571         desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0);
1572         if (*end) {
1573                 fprintf(stderr, "error: %s: bad default stripe offset '%s'\n",
1574                         cmdname(argv[0]), argv[4]);
1575                 return CMD_HELP;
1576         }
1577         desc.ld_pattern = strtoul(argv[5], &end, 0);
1578         if (*end) {
1579                 fprintf(stderr, "error: %s: bad stripe pattern '%s'\n",
1580                         cmdname(argv[0]), argv[5]);
1581                 return CMD_HELP;
1582         }
1583
1584         /* NOTE: it is possible to overwrite the default striping parameters,
1585          *       but EXTREME care must be taken when saving the OST UUID list.
1586          *       It must be EXACTLY the same, or have only additions at the
1587          *       end of the list, or only overwrite individual OST entries
1588          *       that are restored from backups of the previous OST.
1589          */
1590         uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
1591         if (!uuidarray) {
1592                 fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
1593                         cmdname(argv[0]), desc.ld_tgt_count);
1594                 rc = -ENOMEM;
1595                 goto out;
1596         }
1597         for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) {
1598                 if (strlen(argv[i]) >= sizeof(*ptr)) {
1599                         fprintf(stderr, "error: %s: arg %d (%s) too long\n",
1600                                 cmdname(argv[0]), i, argv[i]);
1601                         rc = -EINVAL;
1602                         goto out;
1603                 }
1604                 strcpy((char *)ptr, argv[i]);
1605         }
1606
1607         data.ioc_inllen1 = sizeof(desc);
1608         data.ioc_inlbuf1 = (char *)&desc;
1609         data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
1610         data.ioc_inlbuf2 = (char *)uuidarray;
1611
1612         if (obd_ioctl_pack(&data, &buf, max)) {
1613                 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1614                 rc = -EINVAL;
1615                 goto out;
1616         }
1617         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LOV_SET_CONFIG, buf);
1618         if (rc)
1619                 fprintf(stderr, "error: %s: ioctl error: %s\n",
1620                         cmdname(argv[0]), strerror(rc = errno));
1621 out:
1622         free(uuidarray);
1623         return rc;
1624 }
1625
1626 #define DEF_UUID_ARRAY_LEN (8192 / 40)
1627
1628 int jt_obd_lov_getconfig(int argc, char **argv)
1629 {
1630         struct obd_ioctl_data data;
1631         struct lov_desc desc;
1632         struct obd_uuid *uuidarray;
1633         char *path;
1634         int rc, fd;
1635
1636         IOC_INIT(data);
1637
1638         if (argc != 2)
1639                 return CMD_HELP;
1640
1641         path = argv[1];
1642         fd = open(path, O_RDONLY);
1643         if (fd < 0) {
1644                 fprintf(stderr, "open \"%s\" failed: %s\n", path,
1645                         strerror(errno));
1646                 return -1;
1647         }
1648
1649         memset(&desc, 0, sizeof(desc));
1650         obd_str2uuid(&desc.ld_uuid, argv[1]);
1651         desc.ld_tgt_count = DEF_UUID_ARRAY_LEN;
1652 repeat:
1653         uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
1654         if (!uuidarray) {
1655                 fprintf(stderr, "error: %s: no memory for %d uuid's\n",
1656                         cmdname(argv[0]), desc.ld_tgt_count);
1657                 rc = -ENOMEM;
1658                 goto out;
1659         }
1660
1661         data.ioc_inllen1 = sizeof(desc);
1662         data.ioc_inlbuf1 = (char *)&desc;
1663         data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
1664         data.ioc_inlbuf2 = (char *)uuidarray;
1665
1666         if (obd_ioctl_pack(&data, &buf, max)) {
1667                 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1668                 rc = -EINVAL;
1669                 goto out;
1670         }
1671         rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
1672         if (rc == -ENOSPC) {
1673                 free(uuidarray);
1674                 goto repeat;
1675         } else if (rc) {
1676                 fprintf(stderr, "error: %s: ioctl error: %s\n",
1677                         cmdname(argv[0]), strerror(rc = errno));
1678         } else {
1679                 struct obd_uuid *ptr;
1680                 int i;
1681
1682                 if (obd_ioctl_unpack(&data, buf, max)) {
1683                         fprintf(stderr, "error: %s: invalid reply\n",
1684                                 cmdname(argv[0]));
1685                         rc = -EINVAL;
1686                         goto out;
1687                 }
1688                 printf("default_stripe_count: %u\n",
1689                        desc.ld_default_stripe_count);
1690                 printf("default_stripe_size: "LPU64"\n",
1691                        desc.ld_default_stripe_size);
1692                 printf("default_stripe_offset: "LPU64"\n",
1693                        desc.ld_default_stripe_offset);
1694                 printf("default_stripe_pattern: %u\n", desc.ld_pattern);
1695                 printf("obd_count: %u\n", desc.ld_tgt_count);
1696                 for (i = 0, ptr = uuidarray; i < desc.ld_tgt_count; i++, ptr++)
1697                         printf("%u: %s\n", i, (char *)ptr);
1698         }
1699 out:
1700         free(uuidarray);
1701         close(fd);
1702         return rc;
1703 }
1704
1705 int jt_obd_test_ldlm(int argc, char **argv)
1706 {
1707         struct obd_ioctl_data data;
1708         int rc;
1709
1710         IOC_INIT(data);
1711         if (argc != 1)
1712                 return CMD_HELP;
1713
1714         IOC_PACK(argv[0], data);
1715         rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf);
1716         if (rc)
1717                 fprintf(stderr, "error: %s: test failed: %s\n",
1718                         cmdname(argv[0]), strerror(rc = errno));
1719         return rc;
1720 }
1721
1722 int jt_obd_dump_ldlm(int argc, char **argv)
1723 {
1724         struct obd_ioctl_data data;
1725         int rc;
1726
1727         IOC_INIT(data);
1728         if (argc != 1)
1729                 return CMD_HELP;
1730
1731         IOC_PACK(argv[0], data);
1732         rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf);
1733         if (rc)
1734                 fprintf(stderr, "error: %s failed: %s\n",
1735                         cmdname(argv[0]), strerror(rc = errno));
1736         return rc;
1737 }
1738
1739 int jt_obd_ldlm_regress_start(int argc, char **argv)
1740 {
1741         int rc;
1742         struct obd_ioctl_data data;
1743         char argstring[200];
1744         int i, count = sizeof(argstring) - 1;
1745
1746         IOC_INIT(data);
1747         if (argc > 5)
1748                 return CMD_HELP;
1749
1750         argstring[0] = '\0';
1751         for (i = 1; i < argc; i++) {
1752                 strncat(argstring, " ", count);
1753                 count--;
1754                 strncat(argstring, argv[i], count);
1755                 count -= strlen(argv[i]);
1756         }
1757
1758         if (strlen(argstring)) {
1759                 data.ioc_inlbuf1 = argstring;
1760                 data.ioc_inllen1 = strlen(argstring) + 1;
1761         }
1762
1763         IOC_PACK(argv[0], data);
1764         rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
1765         if (rc)
1766                 fprintf(stderr, "error: %s: test failed: %s\n",
1767                         cmdname(argv[0]), strerror(rc = errno));
1768
1769         return rc;
1770 }
1771
1772 int jt_obd_ldlm_regress_stop(int argc, char **argv)
1773 {
1774         int rc;
1775         struct obd_ioctl_data data;
1776         IOC_INIT(data);
1777
1778         if (argc != 1)
1779                 return CMD_HELP;
1780
1781         IOC_PACK(argv[0], data);
1782         rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
1783
1784         if (rc)
1785                 fprintf(stderr, "error: %s: test failed: %s\n",
1786                         cmdname(argv[0]), strerror(rc = errno));
1787         return rc;
1788 }
1789
1790 int jt_obd_lov_set_osc_active(int argc, char **argv)
1791 {
1792         struct obd_ioctl_data data;
1793         int rc;
1794
1795         IOC_INIT(data);
1796         if (argc != 3)
1797                 return CMD_HELP;
1798
1799         data.ioc_inlbuf1 = argv[1];
1800         data.ioc_inllen1 = strlen(argv[1]) + 1;
1801
1802         /* reuse offset for 'active' */
1803         data.ioc_offset = atoi(argv[2]);
1804
1805         IOC_PACK(argv[0], data);
1806         rc = l_ioctl(OBD_DEV_ID, IOC_LOV_SET_OSC_ACTIVE, buf);
1807         if (rc)
1808                 fprintf(stderr, "error: %s: failed: %s\n",
1809                         cmdname(argv[0]), strerror(rc = errno));
1810
1811         return rc;
1812 }
1813
1814 int jt_obd_newconn(int argc, char **argv)
1815 {
1816         int rc;
1817         struct obd_ioctl_data data;
1818
1819         IOC_INIT(data);
1820         if (argc < 2 || argc > 3)
1821                 return CMD_HELP;
1822
1823         data.ioc_inllen1 = strlen(argv[1]) + 1;
1824         data.ioc_inlbuf1 = argv[1];
1825
1826         if (argc == 3) {
1827                 data.ioc_inllen2 = strlen(argv[2]) + 1;
1828                 data.ioc_inlbuf2 = argv[2];
1829         }
1830
1831         IOC_PACK(argv[0], data);
1832         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECOVD_NEWCONN, buf);
1833         if (rc < 0)
1834                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1835                         strerror(rc = errno));
1836
1837         return rc;
1838 }
1839
1840 int jt_obd_failconn(int argc, char **argv)
1841 {
1842         int rc;
1843         struct obd_ioctl_data data;
1844
1845         IOC_INIT(data);
1846         if (argc < 2)
1847                 return CMD_HELP;
1848
1849         data.ioc_inllen1 = strlen(argv[1]) + 1;
1850         data.ioc_inlbuf1 = argv[1];
1851
1852         IOC_PACK(argv[0], data);
1853         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECOVD_FAILCONN, buf);
1854         if (rc < 0)
1855                 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1856                         strerror(rc = errno));
1857
1858         return rc;
1859 }
1860
1861 int jt_obd_mdc_lookup(int argc, char **argv)
1862 {
1863         struct obd_ioctl_data data;
1864         char *parent, *child;
1865         int rc, fd, verbose = 1;
1866
1867         if (argc < 3 || argc > 4)
1868                 return CMD_HELP;
1869
1870         parent = argv[1];
1871         child = argv[2];
1872         if (argc == 4)
1873                 verbose = get_verbose(argv[0], argv[3]);
1874
1875         IOC_INIT(data);
1876
1877         data.ioc_inllen1 = strlen(child) + 1;
1878         data.ioc_inlbuf1 = child;
1879
1880         IOC_PACK(argv[0], data);
1881
1882         fd = open(parent, O_RDONLY);
1883         if (fd < 0) {
1884                 fprintf(stderr, "open \"%s\" failed: %s\n", parent,
1885                         strerror(errno));
1886                 return -1;
1887         }
1888
1889         rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
1890         if (rc < 0) {
1891                 fprintf(stderr, "error: %s: ioctl error: %s\n",
1892                         cmdname(argv[0]), strerror(rc = errno));
1893         }
1894         close(fd);
1895
1896         if (verbose) {
1897                 IOC_UNPACK(argv[0], data);
1898                 printf("%s: mode %o uid %d gid %d\n", child,
1899                        data.ioc_obdo1.o_mode, data.ioc_obdo1.o_uid,
1900                        data.ioc_obdo1.o_gid);
1901         }
1902
1903         return rc;
1904 }
1905
1906 static 
1907 int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal) 
1908 {
1909         char tmp[64];
1910         int rc;
1911         struct obd_ioctl_data data;
1912
1913         IOC_INIT(data);
1914         data.ioc_nid = nid;
1915         data.ioc_inllen1 = strlen(uuid) + 1;
1916         data.ioc_inlbuf1 = uuid;
1917         data.ioc_nal = nal;
1918
1919         IOC_PACK(func, data);
1920         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ADD_UUID, buf);
1921         if (rc) {
1922                 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
1923                         strerror(errno));
1924                 return -1;
1925         }
1926
1927         printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid));
1928         return 0;
1929 }
1930
1931 int jt_obd_add_uuid(int argc, char **argv)
1932 {
1933         ptl_nid_t nid = 0;
1934         int nal;
1935         
1936         if (argc != 4) {                
1937                 return CMD_HELP;
1938         }
1939
1940         if (ptl_parse_nid (&nid, argv[2]) != 0) {
1941                 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
1942                         return (-1);
1943         }
1944
1945         nal = ptl_name2nal(argv[3]);
1946
1947         if (nal == 0) {
1948                 fprintf (stderr, "Can't parse NAL %s\n", argv[3]);
1949                 return -1;
1950         }
1951
1952         return do_add_uuid(argv[0], argv[1], nid, nal);
1953 }
1954
1955 int jt_obd_close_uuid(int argc, char **argv)
1956 {
1957         int rc, nal;
1958         struct obd_ioctl_data data;
1959
1960         if (argc != 3) {
1961                 fprintf(stderr, "usage: %s <uuid> <net-type>\n", argv[0]);
1962                 return 0;
1963         }
1964
1965         nal = ptl_name2nal(argv[2]);
1966
1967         if (nal == 0) {
1968                 fprintf (stderr, "Can't parse NAL %s\n", argv[2]);
1969                 return -1;
1970         }
1971
1972         IOC_INIT(data);
1973         data.ioc_inllen1 = strlen(argv[1]) + 1;
1974         data.ioc_inlbuf1 = argv[1];
1975         data.ioc_nal = nal;
1976
1977         IOC_PACK(argv[0], data);
1978         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf);
1979         if (rc) {
1980                 fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n",
1981                         strerror(errno));
1982                 return -1;
1983         }
1984         return 0;
1985 }
1986
1987
1988 int jt_obd_del_uuid(int argc, char **argv)
1989 {
1990         int rc;
1991         struct obd_ioctl_data data;
1992
1993         if (argc != 2) {
1994                 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
1995                 return 0;
1996         }
1997
1998         IOC_INIT(data);
1999
2000         if (strcmp (argv[1], "_all_"))
2001         {
2002                 data.ioc_inllen1 = strlen(argv[1]) + 1;
2003                 data.ioc_inlbuf1 = argv[1];
2004         }
2005         
2006         IOC_PACK(argv[0], data);
2007         rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DEL_UUID, buf);
2008         if (rc) {
2009                 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
2010                         strerror(errno));
2011                 return -1;
2012         }
2013         return 0;
2014 }
2015
2016 static void signal_server(int sig)
2017 {
2018         if (sig == SIGINT) {
2019                 do_disconnect("sigint", 1);
2020                 exit(1);
2021         } else
2022                 fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig);
2023 }
2024
2025 int obd_initialize(int argc, char **argv)
2026 {
2027         SHMEM_SETUP();
2028         register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH);
2029
2030         return 0;
2031 }
2032
2033
2034 void obd_cleanup(int argc, char **argv)
2035 {
2036         struct sigaction sigact;
2037
2038         sigact.sa_handler = signal_server;
2039         sigfillset(&sigact.sa_mask);
2040         sigact.sa_flags = SA_RESTART;
2041         sigaction(SIGINT, &sigact, NULL);
2042
2043         do_disconnect(argv[0], 1);
2044 }