4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Whamcloud, Inc.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
38 * Author: Peter J. Braam <braam@clusterfs.com>
39 * Author: Phil Schwan <phil@clusterfs.com>
40 * Author: Andreas Dilger <adilger@clusterfs.com>
41 * Author: Robert Read <rread@clusterfs.com>
44 #include <sys/ioctl.h>
45 #include <sys/socket.h>
48 #include <sys/types.h>
67 #include <obd.h> /* for struct lov_stripe_md */
68 #include <lustre/lustre_build_version.h>
70 #include <obd_class.h>
71 #include <lnet/lnetctl.h>
72 #include <libcfs/libcfsutil.h>
73 #include <lustre/liblustreapi.h>
75 #define MAX_STRING_SIZE 128
76 #define DEVICES_LIST "/proc/fs/lustre/devices"
83 #define MAX_THREADS 4096
84 #define MAX_BASE_ID 0xffffffff
90 __u64 counters[MAX_THREADS];
91 __u64 offsets[MAX_THREADS];
95 struct timeval start_time;
96 struct timeval end_time;
100 static struct shared_data *shared_data;
101 static __u64 counter_snapshot[2][MAX_THREADS];
102 static int prev_valid;
103 static struct timeval prev_time;
107 const int thread = 0;
108 const int nthreads = 1;
111 static int cur_device = -1;
113 struct lov_oinfo lov_oinfos[LOV_MAX_STRIPE_COUNT];
116 struct lov_stripe_md lsm;
117 struct lov_oinfo *ptrs[LOV_MAX_STRIPE_COUNT];
120 static int l2_ioctl(int dev_id, int opc, void *buf)
122 return l_ioctl(dev_id, opc, buf);
125 int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg)
127 struct obd_ioctl_data data;
128 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
131 memset(&data, 0, sizeof(data));
132 data.ioc_dev = cur_device;
133 data.ioc_type = LUSTRE_CFG_TYPE;
134 data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount,
136 data.ioc_pbuf1 = (void *)lcfg;
137 memset(buf, 0, sizeof(rawbuf));
138 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
140 fprintf(stderr, "error: %s: invalid ioctl\n",
145 rc = l_ioctl(dev_id, OBD_IOC_PROCESS_CFG, buf);
150 static int do_device(char *func, char *devname);
152 static int get_mgs_device()
155 static int mgs_device = -1;
157 if (mgs_device == -1) {
159 do_disconnect(NULL, 1);
160 rc = do_device("mgsioc", mgs);
163 "This command must be run on the MGS.\n");
167 mgs_device = cur_device;
172 /* Returns -1 on error with errno set */
173 int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg)
175 struct obd_ioctl_data data;
176 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
179 memset(&data, 0, sizeof(data));
180 rc = data.ioc_dev = get_mgs_device();
183 data.ioc_type = LUSTRE_CFG_TYPE;
184 data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount,
186 data.ioc_pbuf1 = (void *)lcfg;
187 memset(buf, 0, sizeof(rawbuf));
188 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
190 fprintf(stderr, "error: %s: invalid ioctl\n",
195 rc = l_ioctl(dev_id, OBD_IOC_PARAM, buf);
199 fprintf(stderr, "Make sure cfg_device is set first.\n");
204 char *obdo_print(struct obdo *obd)
208 sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64
209 "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64
210 "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n"
211 "misc: %x\nnlink: %d,\nvalid "LPX64"\n",
212 obd->o_id, obd->o_seq, obd->o_atime, obd->o_mtime, obd->o_ctime,
213 obd->o_size, obd->o_blocks, obd->o_blksize, obd->o_mode,
214 obd->o_uid, obd->o_gid, obd->o_flags, obd->o_misc,
215 obd->o_nlink, obd->o_valid);
220 #define BAD_VERBOSE (-999999999)
222 #define N2D_OFF 0x100 /* So we can tell between error codes and devices */
224 static int do_name2dev(char *func, char *name)
226 struct obd_ioctl_data data;
227 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
230 memset(&data, 0, sizeof(data));
231 data.ioc_dev = cur_device;
232 data.ioc_inllen1 = strlen(name) + 1;
233 data.ioc_inlbuf1 = name;
235 memset(buf, 0, sizeof(rawbuf));
236 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
238 fprintf(stderr, "error: %s: invalid ioctl\n",
242 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf);
245 rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
247 fprintf(stderr, "error: %s: invalid reply\n",
252 return data.ioc_dev + N2D_OFF;
256 * resolve a device name to a device number.
257 * supports a number, $name or %uuid.
259 int parse_devname(char *func, char *name)
266 if (isdigit(name[0])) {
267 ret = strtoul(name, NULL, 0);
269 if (name[0] == '$' || name[0] == '%')
271 rc = do_name2dev(func, name);
274 // printf("Name %s is device %d\n", name, ret);
276 fprintf(stderr, "No device found for name %s: %s\n",
284 reset_lsmb (struct lsm_buffer *lsmb)
286 memset (&lsmb->lsm, 0, sizeof (lsmb->lsm));
287 memset(lov_oinfos, 0, sizeof(lov_oinfos));
288 lsmb->lsm.lsm_magic = LOV_MAGIC;
292 parse_lsm (struct lsm_buffer *lsmb, char *string)
294 struct lov_stripe_md *lsm = &lsmb->lsm;
299 * object_id[=size#count[@offset:id]*]
304 lsm->lsm_object_id = strtoull (string, &end, 0);
316 lsm->lsm_stripe_size = strtoul (string, &end, 0);
325 lsm->lsm_stripe_count = strtoul (string, &end, 0);
330 if (*string == 0) /* don't have to specify obj ids */
333 for (i = 0; i < lsm->lsm_stripe_count; i++) {
337 lsm->lsm_oinfo[i]->loi_ost_idx = strtoul(string, &end, 0);
341 lsm->lsm_oinfo[i]->loi_id = strtoull(string, &end, 0);
351 char *jt_cmdname(char *func)
353 static char buf[512];
356 sprintf(buf, "%s-%d", func, thread);
363 #define difftime(a, b) \
364 ((a)->tv_sec - (b)->tv_sec + \
365 ((a)->tv_usec - (b)->tv_usec) / 1000000.0)
367 static int be_verbose(int verbose, struct timeval *next_time,
368 __u64 num, __u64 *next_num, int num_total)
375 if (next_time != NULL)
376 gettimeofday(&now, NULL);
378 /* A positive verbosity means to print every X iterations */
379 if (verbose > 0 && (num >= *next_num || num >= num_total)) {
380 *next_num += verbose;
382 next_time->tv_sec = now.tv_sec - verbose;
383 next_time->tv_usec = now.tv_usec;
388 /* A negative verbosity means to print at most each X seconds */
389 if (verbose < 0 && next_time != NULL &&
390 difftime(&now, next_time) >= 0.0){
391 next_time->tv_sec = now.tv_sec - verbose;
392 next_time->tv_usec = now.tv_usec;
400 static int get_verbose(char *func, const char *arg)
405 if (!arg || arg[0] == 'v')
407 else if (arg[0] == 's' || arg[0] == 'q')
410 verbose = (int)strtoul(arg, &end, 0);
412 fprintf(stderr, "error: %s: bad verbose option '%s'\n",
413 jt_cmdname(func), arg);
419 printf("Print status every %d seconds\n", -verbose);
420 else if (verbose == 1)
421 printf("Print status every operation\n");
422 else if (verbose > 1)
423 printf("Print status every %d operations\n", verbose);
428 int do_disconnect(char *func, int verbose)
430 lcfg_set_devname(NULL);
436 static int shmem_setup(void)
438 pthread_mutexattr_t mattr;
439 pthread_condattr_t cattr;
443 /* Create new segment */
444 shmid = shmget(IPC_PRIVATE, sizeof(*shared_data), 0600);
446 fprintf(stderr, "Can't create shared data: %s\n",
451 /* Attatch to new segment */
452 shared_data = (struct shared_data *)shmat(shmid, NULL, 0);
454 if (shared_data == (struct shared_data *)(-1)) {
455 fprintf(stderr, "Can't attach shared data: %s\n",
461 /* Mark segment as destroyed, so it will disappear when we exit.
462 * Forks will inherit attached segments, so we should be OK.
464 if (shmctl(shmid, IPC_RMID, NULL) == -1) {
465 fprintf(stderr, "Can't destroy shared data: %s\n",
470 pthread_mutexattr_init(&mattr);
471 pthread_condattr_init(&cattr);
473 rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
475 fprintf(stderr, "Can't set shared mutex attr\n");
479 rc = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
481 fprintf(stderr, "Can't set shared cond attr\n");
485 pthread_mutex_init(&shared_data->mutex, &mattr);
486 pthread_cond_init(&shared_data->cond, &cattr);
488 pthread_mutexattr_destroy(&mattr);
489 pthread_condattr_destroy(&cattr);
494 static inline void shmem_lock(void)
496 l_mutex_lock(&shared_data->mutex);
499 static inline void shmem_unlock(void)
501 l_mutex_unlock(&shared_data->mutex);
504 static inline void shmem_wait(void)
506 l_cond_wait(&shared_data->cond, &shared_data->mutex);
509 static inline void shmem_wakeup_all(void)
511 l_cond_broadcast(&shared_data->cond);
514 static inline void shmem_reset(int total_threads)
516 if (shared_data == NULL)
519 memset(&shared_data->body, 0, sizeof(shared_data->body));
520 memset(counter_snapshot, 0, sizeof(counter_snapshot));
522 shared_data->stopping = 0;
523 shared_data->body.start_barrier = total_threads;
524 shared_data->body.stop_barrier = total_threads;
527 static inline void shmem_bump(__u32 counter)
529 static bool running_not_bumped = true;
531 if (shared_data == NULL || thread <= 0 || thread > MAX_THREADS)
535 shared_data->body.counters[thread - 1] += counter;
536 if (running_not_bumped) {
537 shared_data->body.thr_running++;
538 running_not_bumped = false;
543 static void shmem_total(int total_threads)
549 if (shared_data == NULL || total_threads > MAX_THREADS)
553 for (i = 0; i < total_threads; i++)
554 total += shared_data->body.counters[i];
556 secs = difftime(&shared_data->body.end_time,
557 &shared_data->body.start_time);
560 printf("Total: total "LPU64" threads %d sec %f %f/second\n",
561 total, total_threads, secs, total / secs);
566 static void shmem_snap(int total_threads, int live_threads)
568 struct timeval this_time;
575 if (shared_data == NULL || total_threads > MAX_THREADS)
579 memcpy(counter_snapshot[0], shared_data->body.counters,
580 total_threads * sizeof(counter_snapshot[0][0]));
581 running = shared_data->body.thr_running;
584 gettimeofday(&this_time, NULL);
586 for (i = 0; i < total_threads; i++) {
587 long long this_count =
588 counter_snapshot[0][i] - counter_snapshot[1][i];
590 if (this_count != 0) {
596 secs = difftime(&this_time, &prev_time);
597 if (prev_valid && secs > 1.0) /* someone screwed with the time? */
598 printf("%d/%d Total: %f/second\n", non_zero, total_threads,
601 memcpy(counter_snapshot[1], counter_snapshot[0],
602 total_threads * sizeof(counter_snapshot[0][0]));
603 prev_time = this_time;
605 running == total_threads)
609 static void shmem_stop(void)
611 if (shared_data == NULL)
614 shared_data->stopping = 1;
617 static void shmem_cleanup(void)
619 if (shared_data == NULL)
624 pthread_mutex_destroy(&shared_data->mutex);
625 pthread_cond_destroy(&shared_data->cond);
628 static int shmem_running(void)
630 return (shared_data == NULL || !shared_data->stopping);
633 static void shmem_end_time_locked(void)
635 shared_data->body.stop_barrier--;
636 if (shared_data->body.stop_barrier == 0)
637 gettimeofday(&shared_data->body.end_time, NULL);
640 static void shmem_start_time_locked(void)
642 shared_data->body.start_barrier--;
643 if (shared_data->body.start_barrier == 0) {
645 gettimeofday(&shared_data->body.start_time, NULL);
652 static int shmem_setup(void)
657 static inline void shmem_reset(int total_threads)
661 static inline void shmem_bump(__u32 counters)
665 static void shmem_lock()
669 static void shmem_unlock()
673 static void shmem_cleanup(void)
677 static int shmem_running(void)
683 extern command_t cmdlist[];
685 static int do_device(char *func, char *devname)
689 dev = parse_devname(func, devname);
693 lcfg_set_devname(devname);
698 int jt_obd_get_device()
703 int jt_obd_device(int argc, char **argv)
711 printf("current device is %d - %s\n",
712 cur_device, lcfg_get_devname() ? : "not set");
715 rc = do_device("device", argv[1]);
719 int jt_opt_device(int argc, char **argv)
727 rc = do_device("device", argv[1]);
730 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
732 ret = do_disconnect(argv[0], 0);
740 static void parent_sighandler (int sig)
745 int jt_opt_threads(int argc, char **argv)
747 static char cmdstr[128];
750 struct sigaction sigact;
751 struct sigaction saveact1;
752 struct sigaction saveact2;
753 unsigned long threads;
757 int report_count = -1;
764 threads = strtoul(argv[1], &end, 0);
767 report_count = strtoul(end + 1, &end, 0);
769 if (*end || threads > MAX_THREADS) {
770 fprintf(stderr, "error: %s: invalid thread count '%s'\n",
771 jt_cmdname(argv[0]), argv[1]);
775 verbose = get_verbose(argv[0], argv[2]);
776 if (verbose == BAD_VERBOSE)
780 snprintf(cmdstr, sizeof(cmdstr), "%s", argv[4]);
781 for (i = 5; i < argc; i++)
782 snprintf(cmdstr + strlen(cmdstr), sizeof(cmdstr),
785 printf("%s: starting %ld threads on device %s running %s\n",
786 argv[0], threads, argv[3], cmdstr);
789 shmem_reset(threads);
791 sigemptyset(&sigset);
792 sigaddset(&sigset, SIGALRM);
793 sigaddset(&sigset, SIGCHLD);
794 sigprocmask(SIG_BLOCK, &sigset, &saveset);
798 for (i = 1, next_thread = verbose; i <= threads; i++) {
801 fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
802 strerror(rc = errno));
804 } else if (rc == 0) {
805 sigprocmask(SIG_SETMASK, &saveset, NULL);
808 argv[2] = "--device";
809 exit(jt_opt_device(argc - 2, argv + 2));
810 } else if (be_verbose(verbose, NULL, i, &next_thread, threads))
811 printf("%s: thread #%d (PID %d) started\n",
816 if (!thread) { /* parent process */
817 int live_threads = threads;
819 sigemptyset(&sigset);
820 sigemptyset(&sigact.sa_mask);
821 sigact.sa_handler = parent_sighandler;
824 sigaction(SIGALRM, &sigact, &saveact1);
825 sigaction(SIGCHLD, &sigact, &saveact2);
827 while (live_threads > 0) {
831 if (verbose < 0) /* periodic stats */
837 while (live_threads > 0) {
838 ret = waitpid(0, &status, WNOHANG);
843 fprintf(stderr, "error: %s: wait - %s\n",
844 argv[0], strerror(errno));
850 * This is a hack. We _should_ be able
851 * to use WIFEXITED(status) to see if
852 * there was an error, but it appears
853 * to be broken and it always returns 1
856 int err = WEXITSTATUS(status);
857 if (err || WIFSIGNALED(status))
859 "%s: PID %d had rc=%d\n",
868 /* Show stats while all threads running */
870 shmem_snap(threads, live_threads);
871 if (report_count > 0 && --report_count == 0)
875 sigaction(SIGCHLD, &saveact2, NULL);
876 sigaction(SIGALRM, &saveact1, NULL);
879 shmem_total(threads);
880 sigprocmask(SIG_SETMASK, &saveset, NULL);
885 int jt_opt_threads(int argc, char **argv)
887 fprintf(stderr, "%s not-supported in a single-threaded runtime\n",
888 jt_cmdname(argv[0]));
893 int jt_opt_net(int argc, char **argv)
904 rc = jt_ptl_network (2, arg2);
907 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
912 int jt_obd_no_transno(int argc, char **argv)
914 struct obd_ioctl_data data;
915 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
918 memset(&data, 0, sizeof(data));
919 data.ioc_dev = cur_device;
924 memset(buf, 0, sizeof(rawbuf));
925 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
927 fprintf(stderr, "error: %s: invalid ioctl\n",
928 jt_cmdname(argv[0]));
931 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf);
933 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
934 strerror(rc = errno));
939 int jt_obd_set_readonly(int argc, char **argv)
941 struct obd_ioctl_data data;
942 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
945 memset(&data, 0, sizeof(data));
946 data.ioc_dev = cur_device;
951 memset(buf, 0, sizeof(rawbuf));
952 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
954 fprintf(stderr, "error: %s: invalid ioctl\n",
955 jt_cmdname(argv[0]));
958 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf);
960 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
961 strerror(rc = errno));
966 int jt_obd_abort_recovery(int argc, char **argv)
968 struct obd_ioctl_data data;
969 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
972 memset(&data, 0, sizeof(data));
973 data.ioc_dev = cur_device;
978 memset(buf, 0, sizeof(rawbuf));
979 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
981 fprintf(stderr, "error: %s: invalid ioctl\n",
982 jt_cmdname(argv[0]));
985 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf);
987 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
988 strerror(rc = errno));
993 int jt_get_version(int argc, char **argv)
996 char rawbuf[MAX_IOC_BUFLEN];
1002 rc = llapi_get_version(rawbuf, MAX_IOC_BUFLEN, &version);
1004 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
1007 printf("Lustre version: %s\n", version);
1009 printf("lctl version: %s\n", BUILD_VERSION);
1014 * Print an obd device line with the ost_conn_uuid inserted, if the obd
1017 static void print_obd_line(char *s)
1019 char buf[MAX_STRING_SIZE];
1020 char obd_name[MAX_OBD_NAME];
1024 if (sscanf(s, " %*d %*s osc %s %*s %*d ", obd_name) == 0)
1026 snprintf(buf, sizeof(buf),
1027 "/proc/fs/lustre/osc/%s/ost_conn_uuid", obd_name);
1028 if ((fp = fopen(buf, "r")) == NULL)
1033 if (sscanf(s, " %*d %*s mdc %s %*s %*d ", obd_name) == 0)
1035 snprintf(buf, sizeof(buf),
1036 "/proc/fs/lustre/mdc/%s/mds_conn_uuid", obd_name);
1037 if ((fp = fopen(buf, "r")) == NULL)
1041 /* should not ignore fgets(3)'s return value */
1042 if (!fgets(buf, sizeof(buf), fp)) {
1043 fprintf(stderr, "reading from %s: %s", buf, strerror(errno));
1049 /* trim trailing newlines */
1050 ptr = strrchr(buf, '\n');
1051 if (ptr) *ptr = '\0';
1052 ptr = strrchr(s, '\n');
1053 if (ptr) *ptr = '\0';
1055 printf("%s %s\n", s, buf);
1063 /* get device list by ioctl */
1064 int jt_obd_list_ioctl(int argc, char **argv)
1067 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1068 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
1072 /* Just ignore a -t option. Only supported with /proc. */
1073 else if (argc == 2 && strcmp(argv[1], "-t") != 0)
1076 for (index = 0;; index++) {
1077 memset(buf, 0, sizeof(rawbuf));
1078 data->ioc_version = OBD_IOCTL_VERSION;
1080 sizeof(rawbuf) - cfs_size_round(sizeof(*data));
1081 data->ioc_inlbuf1 = buf + cfs_size_round(sizeof(*data));
1082 data->ioc_len = obd_ioctl_packlen(data);
1083 data->ioc_count = index;
1085 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETDEVICE, buf);
1088 printf("%s\n", (char *)data->ioc_bulk);
1091 if (errno == ENOENT)
1092 /* no device or the last device */
1095 fprintf(stderr, "Error getting device list: %s: "
1096 "check dmesg.\n", strerror(errno));
1101 int jt_obd_list(int argc, char **argv)
1104 char buf[MAX_STRING_SIZE];
1110 else if (argc == 2) {
1111 if (strcmp(argv[1], "-t") == 0)
1117 fp = fopen(DEVICES_LIST, "r");
1119 fprintf(stderr, "error: %s: %s opening "DEVICES_LIST"\n",
1120 jt_cmdname(argv[0]), strerror(rc = errno));
1121 return jt_obd_list_ioctl(argc, argv);
1124 while (fgets(buf, sizeof(buf), fp) != NULL)
1126 print_obd_line(buf);
1134 struct jt_fid_space {
1140 int jt_obd_alloc_fids(struct jt_fid_space *space, struct lu_fid *fid,
1145 if (space->jt_seq == 0 || space->jt_id == space->jt_width) {
1146 struct obd_ioctl_data data;
1147 char rawbuf[MAX_IOC_BUFLEN];
1152 memset(&data, 0, sizeof(data));
1153 data.ioc_dev = cur_device;
1155 data.ioc_pbuf1 = (char *)&seqnr;
1156 data.ioc_plen1 = sizeof(seqnr);
1158 data.ioc_pbuf2 = (char *)&max_count;
1159 data.ioc_plen2 = sizeof(max_count);
1161 memset(buf, 0, sizeof(rawbuf));
1162 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1164 fprintf(stderr, "error: invalid ioctl rc = %d\n", rc);
1168 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_ALLOC_SEQ, buf);
1170 fprintf(stderr, "ioctl error: rc = %d\n", rc);
1174 space->jt_seq = *(__u64 *)data.ioc_pbuf1;
1175 space->jt_width = *(int *)data.ioc_pbuf2;
1178 fid->f_seq = space->jt_seq;
1179 fid->f_oid = space->jt_id;
1182 space->jt_id = min(space->jt_id + *count, space->jt_width);
1184 *count = space->jt_id - fid->f_oid;
1188 #define MD_STEP_COUNT 1000
1189 int jt_obd_md_common(int argc, char **argv, int cmd)
1191 struct obd_ioctl_data data;
1192 struct timeval start;
1193 struct timeval end_time;
1194 char rawbuf[MAX_IOC_BUFLEN];
1199 char *parent_basedir = NULL;
1201 int parent_base_id = 0;
1202 int parent_count = 1;
1203 __u64 child_base_id = -1;
1204 int stripe_count = 0;
1205 int stripe_index = -1;
1212 __u64 total_count = 0;
1214 struct jt_fid_space fid_space = {0};
1216 struct option long_opts[] = {
1217 {"child_base_id", required_argument, 0, 'b'},
1218 {"stripe_count", required_argument, 0, 'c'},
1219 {"parent_basedir", required_argument, 0, 'd'},
1220 {"parent_dircount", required_argument, 0, 'D'},
1221 {"stripe_index", required_argument, 0, 'i'},
1222 {"mode", required_argument, 0, 'm'},
1223 {"count", required_argument, 0, 'n'},
1224 {"time", required_argument, 0, 't'},
1225 {"version", no_argument, 0, 'v'},
1226 {"xattr_size", required_argument, 0, 'x'},
1231 while ((c = getopt_long(argc, argv, "b:c:d:D:m:n:t:vx:",
1232 long_opts, NULL)) >= 0) {
1235 child_base_id = strtoull(optarg, &end, 0);
1237 fprintf(stderr, "error: %s: bad child_base_id"
1238 " '%s'\n", jt_cmdname(argv[0]), optarg);
1243 stripe_count = strtoul(optarg, &end, 0);
1245 fprintf(stderr, "error: %s: bad stripe count"
1246 " '%s'\n", jt_cmdname(argv[0]), optarg);
1251 parent_basedir = optarg;
1254 parent_count = strtoul(optarg, &end, 0);
1256 fprintf(stderr, "error: %s: bad parent count"
1257 " '%s'\n", jt_cmdname(argv[0]), optarg);
1262 stripe_index = strtoul(optarg, &end, 0);
1264 fprintf(stderr, "error: %s: bad stripe index"
1265 " '%s'\n", jt_cmdname(argv[0]), optarg);
1270 mode = strtoul(optarg, &end, 0);
1272 fprintf(stderr, "error: %s: bad mode '%s'\n",
1273 jt_cmdname(argv[0]), optarg);
1278 total_count = strtoul(optarg, &end, 0);
1279 if (*end || total_count == 0) {
1280 fprintf(stderr, "%s: bad child count '%s'\n",
1281 jt_cmdname(argv[0]), optarg);
1286 seconds = strtoull(optarg, &end, 0);
1288 fprintf(stderr, "error: %s: seconds '%s'\n",
1289 jt_cmdname(argv[0]), optarg);
1297 xattr_size = strtoul(optarg, &end, 0);
1299 fprintf(stderr, "error: %s: xattr_size '%s'\n",
1300 jt_cmdname(argv[0]), optarg);
1303 SET_BUT_UNUSED(xattr_size);
1306 fprintf(stderr, "error: %s: option '%s' "
1307 "unrecognized\n", argv[0], argv[optind - 1]);
1312 memset(&data, 0, sizeof(data));
1313 data.ioc_dev = cur_device;
1314 if (child_base_id == -1) {
1317 name = argv[optind];
1320 if (optind < argc) {
1321 fprintf(stderr, "child_base_id and name can not"
1322 " specified at the same time\n");
1327 if (stripe_count == 0 && stripe_index != -1) {
1328 fprintf(stderr, "If stripe_count is 0, stripe_index can not"
1333 if (total_count == 0 && seconds == 0) {
1334 fprintf(stderr, "count or seconds needs to be indicated\n");
1338 if (parent_count <= 0) {
1339 fprintf(stderr, "parent count must < 0\n");
1346 /* threads interleave */
1347 if (parent_base_id != -1)
1348 parent_base_id += (thread - 1) % parent_count;
1350 if (child_base_id != -1)
1351 child_base_id += (thread - 1) * \
1352 (MAX_BASE_ID / nthreads);
1354 shmem_start_time_locked();
1358 /* If parent directory is not specified, try to get the directory
1360 if (parent_basedir == NULL) {
1363 fprintf(stderr, "parent_basedir or name must be"
1367 /*Get directory and name from name*/
1368 last_lash = strrchr(name, '/');
1369 if (last_lash == NULL || name[0] != '/') {
1370 fprintf(stderr, "Can not locate %s\n", name);
1374 if (last_lash == name) {
1375 sprintf(dirname, "%s", "/");
1378 int namelen = (unsigned long)last_lash -
1379 (unsigned long)name;
1380 snprintf(dirname, namelen, "%s", name);
1383 data.ioc_pbuf1 = dirname;
1384 data.ioc_plen1 = strlen(dirname);
1386 data.ioc_pbuf2 = name;
1387 data.ioc_plen2 = strlen(name);
1390 data.ioc_pbuf2 = name;
1391 data.ioc_plen2 = strlen(name);
1393 if (parent_base_id > 0)
1394 sprintf(dirname, "%s%d", parent_basedir,
1397 sprintf(dirname, "%s", parent_basedir);
1399 data.ioc_pbuf1 = dirname;
1400 data.ioc_plen1 = strlen(dirname);
1403 if (cmd == ECHO_MD_MKDIR || cmd == ECHO_MD_RMDIR)
1404 create_mode = S_IFDIR;
1406 create_mode = S_IFREG;
1408 data.ioc_obdo1.o_mode = mode | S_IFDIR;
1409 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE |
1410 OBD_MD_FLFLAGS | OBD_MD_FLGROUP;
1411 data.ioc_command = cmd;
1413 gettimeofday(&start, NULL);
1414 while (shmem_running()) {
1417 data.ioc_obdo2.o_id = child_base_id;
1418 data.ioc_obdo2.o_mode = mode | create_mode;
1419 data.ioc_obdo2.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE |
1420 OBD_MD_FLMODE | OBD_MD_FLFLAGS |
1422 data.ioc_obdo2.o_misc = stripe_count;
1423 data.ioc_obdo2.o_stripe_idx = stripe_index;
1425 if (total_count > 0) {
1426 if ((total_count - count) > MD_STEP_COUNT)
1427 data.ioc_count = MD_STEP_COUNT;
1429 data.ioc_count = total_count - count;
1431 data.ioc_count = MD_STEP_COUNT;
1434 if (cmd == ECHO_MD_CREATE || cmd == ECHO_MD_MKDIR) {
1435 /*Allocate fids for the create */
1436 rc = jt_obd_alloc_fids(&fid_space, &fid,
1439 fprintf(stderr, "Allocate fids error %d.\n",rc);
1442 data.ioc_obdo1.o_seq = fid.f_seq;
1443 data.ioc_obdo1.o_id = fid.f_oid;
1446 child_base_id += data.ioc_count;
1447 count += data.ioc_count;
1449 memset(buf, 0, sizeof(rawbuf));
1450 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1452 fprintf(stderr, "error: %s: invalid ioctl %d\n",
1453 jt_cmdname(argv[0]), rc);
1457 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_MD, buf);
1459 fprintf(stderr, "error: %s: %s\n",
1460 jt_cmdname(argv[0]), strerror(rc = errno));
1463 shmem_bump(data.ioc_count);
1465 gettimeofday(&end_time, NULL);
1466 diff = difftime(&end_time, &start);
1467 if (seconds > 0 && (__u64)diff > seconds)
1470 if (count >= total_count && total_count > 0)
1474 if (count > 0 && version) {
1475 gettimeofday(&end_time, NULL);
1476 diff = difftime(&end_time, &start);
1477 printf("%s: %d in %.3fs (%.3f /s): %s",
1478 jt_cmdname(argv[0]), count, diff,
1479 (double)count/diff, ctime(&end_time.tv_sec));
1485 shmem_end_time_locked();
1492 int jt_obd_test_create(int argc, char **argv)
1494 return jt_obd_md_common(argc, argv, ECHO_MD_CREATE);
1497 int jt_obd_test_mkdir(int argc, char **argv)
1499 return jt_obd_md_common(argc, argv, ECHO_MD_MKDIR);
1502 int jt_obd_test_destroy(int argc, char **argv)
1504 return jt_obd_md_common(argc, argv, ECHO_MD_DESTROY);
1507 int jt_obd_test_rmdir(int argc, char **argv)
1509 return jt_obd_md_common(argc, argv, ECHO_MD_RMDIR);
1512 int jt_obd_test_lookup(int argc, char **argv)
1514 return jt_obd_md_common(argc, argv, ECHO_MD_LOOKUP);
1517 int jt_obd_test_setxattr(int argc, char **argv)
1519 return jt_obd_md_common(argc, argv, ECHO_MD_SETATTR);
1522 int jt_obd_test_md_getattr(int argc, char **argv)
1524 return jt_obd_md_common(argc, argv, ECHO_MD_GETATTR);
1527 /* Create one or more objects, arg[4] may describe stripe meta-data. If
1528 * not, defaults assumed. This echo-client instance stashes the stripe
1529 * object ids. Use get_stripe on this node to print full lsm and
1530 * set_stripe on another node to cut/paste between nodes.
1532 /* create <count> [<file_create_mode>] [q|v|# verbosity] [striping] */
1533 int jt_obd_create(int argc, char **argv)
1535 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1536 struct obd_ioctl_data data;
1537 struct timeval next_time;
1538 __u64 count = 1, next_count, base_id = 0;
1539 int verbose = 1, mode = 0100644, rc = 0, i, valid_lsm = 0;
1542 memset(&data, 0, sizeof(data));
1543 data.ioc_dev = cur_device;
1544 if (argc < 2 || argc > 5)
1547 count = strtoull(argv[1], &end, 0);
1549 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1550 jt_cmdname(argv[0]), argv[1]);
1555 mode = strtoul(argv[2], &end, 0);
1557 fprintf(stderr, "error: %s: invalid mode '%s'\n",
1558 jt_cmdname(argv[0]), argv[2]);
1561 if (!(mode & S_IFMT))
1566 verbose = get_verbose(argv[0], argv[3]);
1567 if (verbose == BAD_VERBOSE)
1572 reset_lsmb (&lsm_buffer); /* will set default */
1574 rc = parse_lsm (&lsm_buffer, argv[4]);
1576 fprintf(stderr, "error: %s: invalid lsm '%s'\n",
1577 jt_cmdname(argv[0]), argv[4]);
1580 base_id = lsm_buffer.lsm.lsm_object_id;
1584 printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count);
1585 gettimeofday(&next_time, NULL);
1586 next_time.tv_sec -= verbose;
1588 for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) {
1589 data.ioc_obdo1.o_mode = mode;
1590 data.ioc_obdo1.o_id = base_id;
1591 data.ioc_obdo1.o_uid = 0;
1592 data.ioc_obdo1.o_gid = 0;
1593 data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE |
1594 OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;
1597 data.ioc_plen1 = sizeof lsm_buffer;
1598 data.ioc_pbuf1 = (char *)&lsm_buffer;
1601 memset(buf, 0, sizeof(rawbuf));
1602 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1604 fprintf(stderr, "error: %s: invalid ioctl\n",
1605 jt_cmdname(argv[0]));
1608 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf);
1609 obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
1612 fprintf(stderr, "error: %s: #%d - %s\n",
1613 jt_cmdname(argv[0]), i, strerror(rc = errno));
1616 if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) {
1617 fprintf(stderr,"error: %s: oid not valid #%d:"LPX64"\n",
1618 jt_cmdname(argv[0]), i, data.ioc_obdo1.o_valid);
1623 if (be_verbose(verbose, &next_time, i, &next_count, count))
1624 printf("%s: #%d is object id "LPX64"\n",
1625 jt_cmdname(argv[0]), i, data.ioc_obdo1.o_id);
1630 int jt_obd_setattr(int argc, char **argv)
1632 struct obd_ioctl_data data;
1633 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1637 memset(&data, 0, sizeof(data));
1638 data.ioc_dev = cur_device;
1642 data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1644 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1645 jt_cmdname(argv[0]), argv[1]);
1648 data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0);
1650 fprintf(stderr, "error: %s: invalid mode '%s'\n",
1651 jt_cmdname(argv[0]), argv[2]);
1654 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
1656 memset(buf, 0, sizeof(rawbuf));
1657 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1659 fprintf(stderr, "error: %s: invalid ioctl\n",
1660 jt_cmdname(argv[0]));
1663 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf);
1665 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
1666 strerror(rc = errno));
1671 int jt_obd_test_setattr(int argc, char **argv)
1673 struct obd_ioctl_data data;
1674 struct timeval start, next_time;
1675 __u64 i, count, next_count;
1676 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1682 if (argc < 2 || argc > 4)
1685 memset(&data, 0, sizeof(data));
1686 data.ioc_dev = cur_device;
1687 count = strtoull(argv[1], &end, 0);
1689 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1690 jt_cmdname(argv[0]), argv[1]);
1695 verbose = get_verbose(argv[0], argv[2]);
1696 if (verbose == BAD_VERBOSE)
1701 if (argv[3][0] == 't') {
1702 objid = strtoull(argv[3] + 1, &end, 0);
1704 objid += thread - 1;
1706 objid = strtoull(argv[3], &end, 0);
1708 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1709 jt_cmdname(argv[0]), argv[3]);
1714 gettimeofday(&start, NULL);
1715 next_time.tv_sec = start.tv_sec - verbose;
1716 next_time.tv_usec = start.tv_usec;
1718 printf("%s: setting "LPD64" attrs (objid "LPX64"): %s",
1719 jt_cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
1721 for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) {
1722 data.ioc_obdo1.o_id = objid;
1723 data.ioc_obdo1.o_mode = S_IFREG;
1724 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
1725 memset(buf, 0, sizeof(rawbuf));
1726 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1728 fprintf(stderr, "error: %s: invalid ioctl\n",
1729 jt_cmdname(argv[0]));
1732 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, &data);
1735 fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n",
1736 jt_cmdname(argv[0]), i, errno, strerror(rc = errno));
1740 (verbose, &next_time, i, &next_count, count))
1741 printf("%s: set attr #"LPD64"\n",
1742 jt_cmdname(argv[0]), i);
1750 gettimeofday(&end, NULL);
1752 diff = difftime(&end, &start);
1756 printf("%s: "LPD64" attrs in %.3fs (%.3f attr/s): %s",
1757 jt_cmdname(argv[0]), i, diff, i / diff,
1758 ctime(&end.tv_sec));
1763 int jt_obd_destroy(int argc, char **argv)
1765 struct obd_ioctl_data data;
1766 struct timeval next_time;
1767 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1768 __u64 count = 1, next_count;
1774 memset(&data, 0, sizeof(data));
1775 data.ioc_dev = cur_device;
1776 if (argc < 2 || argc > 4)
1779 id = strtoull(argv[1], &end, 0);
1780 if (*end || id == 0 || errno != 0) {
1781 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1782 jt_cmdname(argv[0]), argv[1]);
1786 count = strtoull(argv[2], &end, 0);
1789 "error: %s: invalid iteration count '%s'\n",
1790 jt_cmdname(argv[0]), argv[2]);
1796 verbose = get_verbose(argv[0], argv[3]);
1797 if (verbose == BAD_VERBOSE)
1801 printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count);
1802 gettimeofday(&next_time, NULL);
1803 next_time.tv_sec -= verbose;
1805 for (i = 1, next_count = verbose; i <= count && shmem_running(); i++, id++) {
1806 data.ioc_obdo1.o_id = id;
1807 data.ioc_obdo1.o_mode = S_IFREG | 0644;
1808 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
1810 memset(buf, 0, sizeof(rawbuf));
1811 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1813 fprintf(stderr, "error: %s: invalid ioctl\n",
1814 jt_cmdname(argv[0]));
1817 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf);
1818 obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
1821 fprintf(stderr, "error: %s: objid "LPX64": %s\n",
1822 jt_cmdname(argv[0]), id, strerror(rc = errno));
1826 if (be_verbose(verbose, &next_time, i, &next_count, count))
1827 printf("%s: #%d is object id "LPX64"\n",
1828 jt_cmdname(argv[0]), i, id);
1834 int jt_obd_getattr(int argc, char **argv)
1836 struct obd_ioctl_data data;
1837 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1844 memset(&data, 0, sizeof(data));
1845 data.ioc_dev = cur_device;
1846 data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1848 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1849 jt_cmdname(argv[0]), argv[1]);
1852 /* to help obd filter */
1853 data.ioc_obdo1.o_mode = 0100644;
1854 data.ioc_obdo1.o_valid = 0xffffffff;
1855 printf("%s: object id "LPX64"\n", jt_cmdname(argv[0]),data.ioc_obdo1.o_id);
1857 memset(buf, 0, sizeof(rawbuf));
1858 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1860 fprintf(stderr, "error: %s: invalid ioctl\n",
1861 jt_cmdname(argv[0]));
1864 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf);
1865 obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
1867 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
1868 strerror(rc = errno));
1870 printf("%s: object id "LPX64", mode %o\n", jt_cmdname(argv[0]),
1871 data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
1876 int jt_obd_test_getattr(int argc, char **argv)
1878 struct obd_ioctl_data data;
1879 struct timeval start, next_time;
1880 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1881 __u64 i, count, next_count;
1887 if (argc < 2 || argc > 4)
1890 memset(&data, 0, sizeof(data));
1891 data.ioc_dev = cur_device;
1892 count = strtoull(argv[1], &end, 0);
1894 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1895 jt_cmdname(argv[0]), argv[1]);
1900 verbose = get_verbose(argv[0], argv[2]);
1901 if (verbose == BAD_VERBOSE)
1906 if (argv[3][0] == 't') {
1907 objid = strtoull(argv[3] + 1, &end, 0);
1909 objid += thread - 1;
1911 objid = strtoull(argv[3], &end, 0);
1913 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1914 jt_cmdname(argv[0]), argv[3]);
1919 gettimeofday(&start, NULL);
1920 next_time.tv_sec = start.tv_sec - verbose;
1921 next_time.tv_usec = start.tv_usec;
1923 printf("%s: getting "LPD64" attrs (objid "LPX64"): %s",
1924 jt_cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
1926 for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) {
1927 data.ioc_obdo1.o_id = objid;
1928 data.ioc_obdo1.o_mode = S_IFREG;
1929 data.ioc_obdo1.o_valid = 0xffffffff;
1930 memset(buf, 0, sizeof(rawbuf));
1931 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
1933 fprintf(stderr, "error: %s: invalid ioctl\n",
1934 jt_cmdname(argv[0]));
1937 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data);
1940 fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n",
1941 jt_cmdname(argv[0]), i, errno, strerror(rc = errno));
1945 (verbose, &next_time, i, &next_count, count))
1946 printf("%s: got attr #"LPD64"\n",
1947 jt_cmdname(argv[0]), i);
1955 gettimeofday(&end, NULL);
1957 diff = difftime(&end, &start);
1961 printf("%s: "LPD64" attrs in %.3fs (%.3f attr/s): %s",
1962 jt_cmdname(argv[0]), i, diff, i / diff,
1963 ctime(&end.tv_sec));
1968 /* test_brw <cnt> count
1969 <r|w[r(repeat)x(noverify)]> mode
1970 <q|v|#(print interval)> verbosity
1971 <npages[+offset]> blocksize
1972 <[[<interleave_threads>]t(inc obj by thread#)]obj> object
1973 [p|g<args>] batch */
1974 int jt_obd_test_brw(int argc, char **argv)
1976 struct obd_ioctl_data data;
1977 struct timeval start, next_time;
1978 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
1979 __u64 count, next_count, len, stride, thr_offset = 0, objid = 3;
1980 int write = 0, verbose = 1, cmd, i, rc = 0, pages = 1;
1981 int offset_pages = 0;
1983 int repeat_offset = 0;
1984 unsigned long long ull;
1985 int nthr_per_obj = 0;
1990 if (argc < 2 || argc > 7) {
1991 fprintf(stderr, "error: %s: bad number of arguments: %d\n",
1992 jt_cmdname(argv[0]), argc);
1996 count = strtoull(argv[1], &end, 0);
1998 fprintf(stderr, "error: %s: bad iteration count '%s'\n",
1999 jt_cmdname(argv[0]), argv[1]);
2004 if (argv[2][0] == 'w' || argv[2][0] == '1')
2006 /* else it's a read */
2008 if (argv[2][0] != 0)
2009 for (i = 1; argv[2][i] != 0; i++)
2010 switch (argv[2][i]) {
2020 fprintf (stderr, "Can't parse cmd '%s'\n",
2027 verbose = get_verbose(argv[0], argv[3]);
2028 if (verbose == BAD_VERBOSE)
2033 pages = strtoul(argv[4], &end, 0);
2036 offset_pages = strtoul(end + 1, &end, 0);
2039 offset_pages < 0 || offset_pages >= pages) {
2040 fprintf(stderr, "error: %s: bad npages[+offset] parameter '%s'\n",
2041 jt_cmdname(argv[0]), argv[4]);
2048 (n = strtol(argv[5], &end, 0)) > 0 &&
2050 (ull = strtoull(end + 1, &end, 0)) > 0 &&
2054 } else if (thread &&
2055 argv[5][0] == 't') {
2057 objid = strtoull(argv[5] + 1, &end, 0);
2060 objid = strtoull(argv[5], &end, 0);
2063 fprintf(stderr, "error: %s: bad objid '%s'\n",
2064 jt_cmdname(argv[0]), argv[5]);
2069 memset(&data, 0, sizeof(data));
2070 data.ioc_dev = cur_device;
2072 /* communicate the 'type' of brw test and batching to echo_client.
2073 * don't start. we'd love to refactor this lctl->echo_client
2075 data.ioc_pbuf1 = (void *)1;
2079 switch(argv[6][0]) {
2080 case 'g': /* plug and unplug */
2081 data.ioc_pbuf1 = (void *)2;
2082 data.ioc_plen1 = strtoull(argv[6] + 1, &end,
2085 case 'p': /* prep and commit */
2086 data.ioc_pbuf1 = (void *)3;
2087 data.ioc_plen1 = strtoull(argv[6] + 1, &end,
2091 fprintf(stderr, "error: %s: batching '%s' "
2092 "needs to specify 'p' or 'g'\n",
2093 jt_cmdname(argv[0]), argv[6]);
2098 fprintf(stderr, "error: %s: bad batching '%s'\n",
2099 jt_cmdname(argv[0]), argv[6]);
2102 data.ioc_plen1 *= getpagesize();
2105 len = pages * getpagesize();
2106 thr_offset = offset_pages * getpagesize();
2112 if (nthr_per_obj != 0) {
2113 /* threads interleave */
2114 obj_idx = (thread - 1)/nthr_per_obj;
2116 stride *= nthr_per_obj;
2117 if ((thread - 1) % nthr_per_obj == 0) {
2118 shared_data->body.offsets[obj_idx] =
2119 stride + thr_offset;
2121 thr_offset += ((thread - 1) % nthr_per_obj) * len;
2123 /* threads disjoint */
2124 thr_offset += (thread - 1) * len;
2127 shmem_start_time_locked();
2132 data.ioc_obdo1.o_id = objid;
2133 data.ioc_obdo1.o_mode = S_IFREG;
2134 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLFLAGS;
2135 data.ioc_obdo1.o_flags = (verify ? OBD_FL_DEBUG_CHECK : 0);
2136 data.ioc_count = len;
2137 data.ioc_offset = (repeat_offset ? 0 : thr_offset);
2139 gettimeofday(&start, NULL);
2140 next_time.tv_sec = start.tv_sec - verbose;
2141 next_time.tv_usec = start.tv_usec;
2144 printf("%s: %s "LPU64"x%d pages (obj "LPX64", off "LPU64"): %s",
2145 jt_cmdname(argv[0]), write ? "writing" : "reading", count,
2146 pages, objid, data.ioc_offset, ctime(&start.tv_sec));
2148 cmd = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
2149 for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) {
2150 data.ioc_obdo1.o_valid &= ~(OBD_MD_FLBLOCKS|OBD_MD_FLGRANT);
2151 memset(buf, 0, sizeof(rawbuf));
2152 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2154 fprintf(stderr, "error: %s: invalid ioctl\n",
2155 jt_cmdname(argv[0]));
2158 rc = l2_ioctl(OBD_DEV_ID, cmd, buf);
2161 fprintf(stderr, "error: %s: #%d - %s on %s\n",
2162 jt_cmdname(argv[0]), i, strerror(rc = errno),
2163 write ? "write" : "read");
2165 } else if (be_verbose(verbose, &next_time,i, &next_count,count)) {
2167 printf("%s: %s number %d @ "LPD64":"LPU64" for %d\n",
2168 jt_cmdname(argv[0]), write ? "write" : "read", i,
2169 data.ioc_obdo1.o_id, data.ioc_offset,
2170 (int)(pages * getpagesize()));
2174 if (!repeat_offset) {
2176 if (stride == len) {
2177 data.ioc_offset += stride;
2178 } else if (i < count) {
2181 shared_data->body.offsets[obj_idx];
2182 shared_data->body.offsets[obj_idx] += len;
2186 data.ioc_offset += len;
2187 obj_idx = 0; /* avoids an unused var warning */
2196 gettimeofday(&end, NULL);
2198 diff = difftime(&end, &start);
2202 printf("%s: %s %dx%d pages in %.3fs (%.3f MB/s): %s",
2203 jt_cmdname(argv[0]), write ? "wrote" : "read",
2205 ((double)i * pages * getpagesize()) /
2207 ctime(&end.tv_sec));
2213 shmem_end_time_locked();
2220 int jt_obd_lov_getconfig(int argc, char **argv)
2222 struct obd_ioctl_data data;
2223 struct lov_desc desc;
2224 struct obd_uuid *uuidarray;
2225 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2230 memset(&data, 0, sizeof(data));
2231 data.ioc_dev = cur_device;
2237 fd = open(path, O_RDONLY);
2239 fprintf(stderr, "open \"%s\" failed: %s\n", path,
2244 memset(&desc, 0, sizeof(desc));
2245 obd_str2uuid(&desc.ld_uuid, argv[1]);
2246 desc.ld_tgt_count = ((OBD_MAX_IOCTL_BUFFER-sizeof(data)-sizeof(desc)) /
2247 (sizeof(*uuidarray) + sizeof(*obdgens)));
2250 uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
2252 fprintf(stderr, "error: %s: no memory for %d uuid's\n",
2253 jt_cmdname(argv[0]), desc.ld_tgt_count);
2257 obdgens = calloc(desc.ld_tgt_count, sizeof(*obdgens));
2259 fprintf(stderr, "error: %s: no memory for %d generation #'s\n",
2260 jt_cmdname(argv[0]), desc.ld_tgt_count);
2265 memset(buf, 0, sizeof(rawbuf));
2266 data.ioc_inllen1 = sizeof(desc);
2267 data.ioc_inlbuf1 = (char *)&desc;
2268 data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
2269 data.ioc_inlbuf2 = (char *)uuidarray;
2270 data.ioc_inllen3 = desc.ld_tgt_count * sizeof(*obdgens);
2271 data.ioc_inlbuf3 = (char *)obdgens;
2273 if (obd_ioctl_pack(&data, &buf, sizeof(rawbuf))) {
2274 fprintf(stderr, "error: %s: invalid ioctl\n",
2275 jt_cmdname(argv[0]));
2279 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
2280 if (rc == -ENOSPC) {
2285 fprintf(stderr, "error: %s: ioctl error: %s\n",
2286 jt_cmdname(argv[0]), strerror(rc = errno));
2288 struct obd_uuid *uuidp;
2292 if (obd_ioctl_unpack(&data, buf, sizeof(rawbuf))) {
2293 fprintf(stderr, "error: %s: invalid reply\n",
2294 jt_cmdname(argv[0]));
2298 if (desc.ld_default_stripe_count == (__u32)-1)
2299 printf("default_stripe_count: %d\n", -1);
2301 printf("default_stripe_count: %u\n",
2302 desc.ld_default_stripe_count);
2303 printf("default_stripe_size: "LPU64"\n",
2304 desc.ld_default_stripe_size);
2305 printf("default_stripe_offset: "LPU64"\n",
2306 desc.ld_default_stripe_offset);
2307 printf("default_stripe_pattern: %u\n", desc.ld_pattern);
2308 printf("obd_count: %u\n", desc.ld_tgt_count);
2309 printf("OBDS:\tobdidx\t\tobdgen\t\t obduuid\n");
2312 for (i = 0; i < desc.ld_tgt_count; i++, uuidp++, genp++)
2313 printf("\t%6u\t%14u\t\t %s\n", i, *genp, (char *)uuidp);
2324 int jt_obd_ldlm_regress_start(int argc, char **argv)
2327 struct obd_ioctl_data data;
2328 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2329 char argstring[200];
2330 int i, count = sizeof(argstring) - 1;
2332 memset(&data, 0, sizeof(data));
2333 data.ioc_dev = cur_device;
2337 argstring[0] = '\0';
2338 for (i = 1; i < argc; i++) {
2339 strncat(argstring, " ", count);
2341 strncat(argstring, argv[i], count);
2342 count -= strlen(argv[i]);
2345 if (strlen(argstring)) {
2346 data.ioc_inlbuf1 = argstring;
2347 data.ioc_inllen1 = strlen(argstring) + 1;
2350 memset(buf, 0, sizeof(rawbuf));
2351 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2353 fprintf(stderr, "error: %s: invalid ioctl\n",
2354 jt_cmdname(argv[0]));
2357 rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
2359 fprintf(stderr, "error: %s: test failed: %s\n",
2360 jt_cmdname(argv[0]), strerror(rc = errno));
2365 int jt_obd_ldlm_regress_stop(int argc, char **argv)
2368 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2369 struct obd_ioctl_data data;
2371 memset(&data, 0, sizeof(data));
2372 data.ioc_dev = cur_device;
2377 memset(buf, 0, sizeof(rawbuf));
2378 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2380 fprintf(stderr, "error: %s: invalid ioctl\n",
2381 jt_cmdname(argv[0]));
2384 rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
2387 fprintf(stderr, "error: %s: test failed: %s\n",
2388 jt_cmdname(argv[0]), strerror(rc = errno));
2392 static int do_activate(int argc, char **argv, int flag)
2394 struct obd_ioctl_data data;
2395 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2398 memset(&data, 0, sizeof(data));
2399 data.ioc_dev = cur_device;
2403 /* reuse offset for 'active' */
2404 data.ioc_offset = flag;
2406 memset(buf, 0, sizeof(rawbuf));
2407 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2409 fprintf(stderr, "error: %s: invalid ioctl\n",
2410 jt_cmdname(argv[0]));
2413 rc = l2_ioctl(OBD_DEV_ID, IOC_OSC_SET_ACTIVE, buf);
2415 fprintf(stderr, "error: %s: failed: %s\n",
2416 jt_cmdname(argv[0]), strerror(rc = errno));
2421 int jt_obd_deactivate(int argc, char **argv)
2423 return do_activate(argc, argv, 0);
2426 int jt_obd_activate(int argc, char **argv)
2428 return do_activate(argc, argv, 1);
2431 int jt_obd_recover(int argc, char **argv)
2434 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2435 struct obd_ioctl_data data;
2437 memset(&data, 0, sizeof(data));
2438 data.ioc_dev = cur_device;
2443 data.ioc_inllen1 = strlen(argv[1]) + 1;
2444 data.ioc_inlbuf1 = argv[1];
2447 memset(buf, 0, sizeof(rawbuf));
2448 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2450 fprintf(stderr, "error: %s: invalid ioctl\n",
2451 jt_cmdname(argv[0]));
2454 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CLIENT_RECOVER, buf);
2456 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
2457 strerror(rc = errno));
2463 int jt_obd_mdc_lookup(int argc, char **argv)
2465 struct obd_ioctl_data data;
2466 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2467 char *parent, *child;
2468 int rc, fd, verbose = 1;
2470 if (argc < 3 || argc > 4)
2476 verbose = get_verbose(argv[0], argv[3]);
2478 memset(&data, 0, sizeof(data));
2479 data.ioc_dev = cur_device;
2481 data.ioc_inllen1 = strlen(child) + 1;
2482 data.ioc_inlbuf1 = child;
2484 memset(buf, 0, sizeof(rawbuf));
2485 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2487 fprintf(stderr, "error: %s: invalid ioctl\n",
2488 jt_cmdname(argv[0]));
2492 fd = open(parent, O_RDONLY);
2494 fprintf(stderr, "open \"%s\" failed: %s\n", parent,
2499 rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
2501 fprintf(stderr, "error: %s: ioctl error: %s\n",
2502 jt_cmdname(argv[0]), strerror(rc = errno));
2507 rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
2509 fprintf(stderr, "error: %s: invalid reply\n",
2510 jt_cmdname(argv[0]));
2513 printf("%s: mode %o uid %d gid %d\n", child,
2514 data.ioc_obdo1.o_mode, data.ioc_obdo1.o_uid,
2515 data.ioc_obdo1.o_gid);
2521 int jt_cfg_dump_log(int argc, char **argv)
2523 struct obd_ioctl_data data;
2524 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2530 memset(&data, 0, sizeof(data));
2531 data.ioc_dev = cur_device;
2532 data.ioc_inllen1 = strlen(argv[1]) + 1;
2533 data.ioc_inlbuf1 = argv[1];
2535 memset(buf, 0, sizeof(rawbuf));
2536 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2538 fprintf(stderr, "error: %s: invalid ioctl\n",
2539 jt_cmdname(argv[0]));
2542 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DUMP_LOG, buf);
2544 fprintf(stderr, "OBD_IOC_DUMP_LOG failed: %s\n",
2550 int jt_llog_catlist(int argc, char **argv)
2552 struct obd_ioctl_data data;
2553 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2559 memset(&data, 0, sizeof(data));
2560 data.ioc_dev = cur_device;
2561 data.ioc_inllen1 = sizeof(rawbuf) - cfs_size_round(sizeof(data));
2562 memset(buf, 0, sizeof(rawbuf));
2563 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2565 fprintf(stderr, "error: %s: invalid ioctl\n",
2566 jt_cmdname(argv[0]));
2569 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf);
2571 fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
2573 fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n",
2579 int jt_llog_info(int argc, char **argv)
2581 struct obd_ioctl_data data;
2582 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2588 memset(&data, 0, sizeof(data));
2589 data.ioc_dev = cur_device;
2590 data.ioc_inllen1 = strlen(argv[1]) + 1;
2591 data.ioc_inlbuf1 = argv[1];
2592 data.ioc_inllen2 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) -
2593 cfs_size_round(data.ioc_inllen1);
2594 memset(buf, 0, sizeof(rawbuf));
2595 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2597 fprintf(stderr, "error: %s: invalid ioctl\n",
2598 jt_cmdname(argv[0]));
2602 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf);
2604 fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
2606 fprintf(stderr, "OBD_IOC_LLOG_INFO failed: %s\n",
2612 int jt_llog_print(int argc, char **argv)
2614 struct obd_ioctl_data data;
2615 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2618 if (argc != 2 && argc != 4)
2621 memset(&data, 0, sizeof(data));
2622 data.ioc_dev = cur_device;
2623 data.ioc_inllen1 = strlen(argv[1]) + 1;
2624 data.ioc_inlbuf1 = argv[1];
2626 data.ioc_inllen2 = strlen(argv[2]) + 1;
2627 data.ioc_inlbuf2 = argv[2];
2628 data.ioc_inllen3 = strlen(argv[3]) + 1;
2629 data.ioc_inlbuf3 = argv[3];
2631 char from[2] = "1", to[3] = "-1";
2632 data.ioc_inllen2 = strlen(from) + 1;
2633 data.ioc_inlbuf2 = from;
2634 data.ioc_inllen3 = strlen(to) + 1;
2635 data.ioc_inlbuf3 = to;
2637 data.ioc_inllen4 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) -
2638 cfs_size_round(data.ioc_inllen1) -
2639 cfs_size_round(data.ioc_inllen2) -
2640 cfs_size_round(data.ioc_inllen3);
2641 memset(buf, 0, sizeof(rawbuf));
2642 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2644 fprintf(stderr, "error: %s: invalid ioctl\n",
2645 jt_cmdname(argv[0]));
2649 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_PRINT, buf);
2651 fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
2653 fprintf(stderr, "OBD_IOC_LLOG_PRINT failed: %s\n",
2659 int jt_llog_cancel(int argc, char **argv)
2661 struct obd_ioctl_data data;
2662 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2668 memset(&data, 0, sizeof(data));
2669 data.ioc_dev = cur_device;
2670 data.ioc_inllen1 = strlen(argv[1]) + 1;
2671 data.ioc_inlbuf1 = argv[1];
2672 data.ioc_inllen2 = strlen(argv[2]) + 1;
2673 data.ioc_inlbuf2 = argv[2];
2674 data.ioc_inllen3 = strlen(argv[3]) + 1;
2675 data.ioc_inlbuf3 = argv[3];
2676 memset(buf, 0, sizeof(rawbuf));
2677 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2679 fprintf(stderr, "error: %s: invalid ioctl\n",
2680 jt_cmdname(argv[0]));
2684 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CANCEL, buf);
2686 fprintf(stdout, "index %s be canceled.\n", argv[3]);
2688 fprintf(stderr, "OBD_IOC_LLOG_CANCEL failed: %s\n",
2694 int jt_llog_check(int argc, char **argv)
2696 struct obd_ioctl_data data;
2697 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2700 if (argc != 2 && argc != 4)
2703 memset(&data, 0, sizeof(data));
2704 data.ioc_dev = cur_device;
2705 data.ioc_inllen1 = strlen(argv[1]) + 1;
2706 data.ioc_inlbuf1 = argv[1];
2708 data.ioc_inllen2 = strlen(argv[2]) + 1;
2709 data.ioc_inlbuf2 = argv[2];
2710 data.ioc_inllen3 = strlen(argv[3]) + 1;
2711 data.ioc_inlbuf3 = argv[3];
2713 char from[2] = "1", to[3] = "-1";
2714 data.ioc_inllen2 = strlen(from) + 1;
2715 data.ioc_inlbuf2 = from;
2716 data.ioc_inllen3 = strlen(to) + 1;
2717 data.ioc_inlbuf3 = to;
2719 data.ioc_inllen4 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) -
2720 cfs_size_round(data.ioc_inllen1) -
2721 cfs_size_round(data.ioc_inllen2) -
2722 cfs_size_round(data.ioc_inllen3);
2723 memset(buf, 0, sizeof(rawbuf));
2724 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2726 fprintf(stderr, "error: %s: invalid ioctl\n",
2727 jt_cmdname(argv[0]));
2731 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CHECK, buf);
2733 fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
2735 fprintf(stderr, "OBD_IOC_LLOG_CHECK failed: %s\n",
2740 int jt_llog_remove(int argc, char **argv)
2742 struct obd_ioctl_data data;
2743 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
2746 if (argc != 3 && argc != 2)
2749 memset(&data, 0, sizeof(data));
2750 data.ioc_dev = cur_device;
2751 data.ioc_inllen1 = strlen(argv[1]) + 1;
2752 data.ioc_inlbuf1 = argv[1];
2754 data.ioc_inllen2 = strlen(argv[2]) + 1;
2755 data.ioc_inlbuf2 = argv[2];
2757 memset(buf, 0, sizeof(rawbuf));
2758 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
2760 fprintf(stderr, "error: %s: invalid ioctl\n",
2761 jt_cmdname(argv[0]));
2765 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_REMOVE, buf);
2768 fprintf(stdout, "log %s are removed.\n", argv[2]);
2770 fprintf(stdout, "the log in catalog %s are removed. \n", argv[1]);
2772 fprintf(stderr, "OBD_IOC_LLOG_REMOVE failed: %s\n",
2778 /* attach a regular file to virtual block device.
2781 * 1: error, it always means the command run failed
2784 static int jt_blockdev_run_process(const char *file, char *argv[])
2790 if (pid == 0) { /* child process */
2791 /* don't print error messages */
2793 (void)execvp(file, argv);
2795 } else if (pid > 0) {
2798 rc = waitpid(pid, &status, 0);
2799 if (rc < 0 || !WIFEXITED(status))
2802 return WEXITSTATUS(status);
2808 static int jt_blockdev_find_module(const char *module)
2814 fp = fopen("/proc/modules", "r");
2818 while (fgets(buf, 1024, fp) != NULL) {
2819 *strchr(buf, ' ') = 0;
2820 if (strcmp(module, buf) == 0) {
2830 static int jt_blockdev_probe_module(const char *module)
2836 if (jt_blockdev_find_module(module) == 1)
2839 /* run modprobe first */
2841 argv[c++] = "/sbin/modprobe";
2843 argv[c++] = (char *)module;
2845 rc = jt_blockdev_run_process("modprobe", argv);
2849 /* cannot find the module in default directory ... */
2850 sprintf(buf, "../llite/%s.ko", module);
2852 argv[c++] = "/sbin/insmod";
2855 rc = jt_blockdev_run_process("insmod", argv);
2859 int jt_blockdev_attach(int argc, char **argv)
2863 char *filename, *devname;
2869 if (jt_blockdev_probe_module("llite_lloop") < 0) {
2870 fprintf(stderr, "error: cannot find module llite_lloop.(k)o\n");
2877 fd = open(filename, O_RDWR);
2879 fprintf(stderr, "file %s can't be opened(%s)\n\n",
2880 filename, strerror(errno));
2884 rc = ioctl(fd, LL_IOC_LLOOP_ATTACH, &dev);
2887 fprintf(stderr, "attach error(%s)\n", strerror(rc));
2891 rc = stat(devname, &st);
2892 if (rc == 0 && (!S_ISBLK(st.st_mode) || st.st_rdev != dev)) {
2894 } else if (rc < 0) {
2895 if (errno == ENOENT &&
2896 !mknod(devname, S_IFBLK|S_IRUSR|S_IWUSR, dev))
2903 fprintf(stderr, "error: the file %s could be attached to block "
2904 "device %X but creating %s failed: %s\n"
2905 "now detaching the block device..",
2906 filename, (int)dev, devname, strerror(rc));
2908 (void)ioctl(fd, LL_IOC_LLOOP_DETACH_BYDEV, dev);
2909 fprintf(stderr, "%s\n", strerror(errno));
2916 int jt_blockdev_detach(int argc, char **argv)
2925 fd = open(filename, O_RDONLY);
2927 fprintf(stderr, "cannot open file %s error %s\n",
2928 filename, strerror(errno));
2932 rc = ioctl(fd, LL_IOC_LLOOP_DETACH, 0);
2935 fprintf(stderr, "detach error(%s)\n", strerror(rc));
2937 (void)unlink(filename);
2944 int jt_blockdev_info(int argc, char **argv)
2954 fd = open(filename, O_RDONLY);
2956 fprintf(stderr, "cannot open file %s error: %s\n",
2957 filename, strerror(errno));
2961 rc = ioctl(fd, LL_IOC_LLOOP_INFO, &fid);
2964 fprintf(stderr, "error: %s\n", strerror(errno));
2967 fprintf(stdout, "lloop device info: ");
2968 if (fid_is_zero(&fid))
2969 fprintf(stdout, "Not attached\n");
2971 fprintf(stdout, "attached to inode "DFID"\n", PFID(&fid));
2977 static void signal_server(int sig)
2979 if (sig == SIGINT) {
2980 do_disconnect("sigint", 1);
2983 fprintf(stderr, "%s: got signal %d\n", jt_cmdname("sigint"), sig);
2986 int obd_initialize(int argc, char **argv)
2990 for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++)
2991 lsm_buffer.lsm.lsm_oinfo[i] = lov_oinfos + i;
2993 if (shmem_setup() != 0)
2996 register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH,
2997 OBD_DEV_MAJOR, OBD_DEV_MINOR);
3002 void obd_finalize(int argc, char **argv)
3004 struct sigaction sigact;
3006 sigact.sa_handler = signal_server;
3007 sigfillset(&sigact.sa_mask);
3008 sigact.sa_flags = SA_RESTART;
3009 sigaction(SIGINT, &sigact, NULL);
3012 do_disconnect(argv[0], 1);
3015 static int check_pool_cmd(enum lcfg_command_type cmd,
3016 char *fsname, char *poolname,
3021 rc = llapi_search_ost(fsname, poolname, ostname);
3022 if (rc < 0 && (cmd != LCFG_POOL_NEW)) {
3023 fprintf(stderr, "Pool %s.%s not found\n",
3029 case LCFG_POOL_NEW: {
3030 LASSERT(ostname == NULL);
3032 fprintf(stderr, "Pool %s.%s already exists\n",
3038 case LCFG_POOL_DEL: {
3039 LASSERT(ostname == NULL);
3041 fprintf(stderr, "Pool %s.%s not empty, "
3042 "please remove all members\n",
3048 case LCFG_POOL_ADD: {
3050 fprintf(stderr, "OST %s is already in pool %s.%s\n",
3051 ostname, fsname, poolname);
3054 rc = llapi_search_ost(fsname, NULL, ostname);
3056 fprintf(stderr, "OST %s is not part of the '%s' fs.\n",
3062 case LCFG_POOL_REM: {
3064 fprintf(stderr, "OST %s not found in pool %s.%s\n",
3065 ostname, fsname, poolname);
3076 /* This check only verifies that the changes have been "pushed out" to
3077 the client successfully. This involves waiting for a config update,
3078 and so may fail because of problems in that code or post-command
3079 network loss. So reporting a warning is appropriate, but not a failure.
3081 static int check_pool_cmd_result(enum lcfg_command_type cmd,
3082 char *fsname, char *poolname,
3089 case LCFG_POOL_NEW: {
3091 rc = llapi_search_ost(fsname, poolname, NULL);
3097 } while ((rc < 0) && (cpt > 0));
3099 fprintf(stderr, "Pool %s.%s created\n",
3103 fprintf(stderr, "Warning, pool %s.%s not found\n",
3108 case LCFG_POOL_DEL: {
3110 rc = llapi_search_ost(fsname, poolname, NULL);
3116 } while ((rc >= 0) && (cpt > 0));
3118 fprintf(stderr, "Pool %s.%s destroyed\n",
3122 fprintf(stderr, "Warning, pool %s.%s still found\n",
3127 case LCFG_POOL_ADD: {
3129 rc = llapi_search_ost(fsname, poolname, ostname);
3135 } while ((rc != 1) && (cpt > 0));
3137 fprintf(stderr, "OST %s added to pool %s.%s\n",
3138 ostname, fsname, poolname);
3141 fprintf(stderr, "Warning, OST %s not found in pool %s.%s\n",
3142 ostname, fsname, poolname);
3146 case LCFG_POOL_REM: {
3148 rc = llapi_search_ost(fsname, poolname, ostname);
3154 } while ((rc == 1) && (cpt > 0));
3156 fprintf(stderr, "OST %s removed from pool %s.%s\n",
3157 ostname, fsname, poolname);
3160 fprintf(stderr, "Warning, OST %s still found in pool %s.%s\n",
3161 ostname, fsname, poolname);
3171 static int check_and_complete_ostname(char *fsname, char *ostname)
3174 char real_ostname[MAX_OBD_NAME + 1];
3177 /* if OST name does not start with fsname, we add it */
3178 /* if not check if the fsname is the right one */
3179 ptr = strchr(ostname, '-');
3181 sprintf(real_ostname, "%s-%s", fsname, ostname);
3182 } else if (strncmp(ostname, fsname, strlen(fsname)) != 0) {
3183 fprintf(stderr, "%s does not start with fsname %s\n",
3187 strcpy(real_ostname, ostname);
3189 /* real_ostname is fsname-????? */
3190 ptr = real_ostname + strlen(fsname) + 1;
3191 if (strncmp(ptr, "OST", 3) != 0) {
3192 fprintf(stderr, "%s does not start by %s-OST nor OST\n",
3196 /* real_ostname is fsname-OST????? */
3198 for (i = 0; i < 4; i++) {
3199 if (!isxdigit(*ptr)) {
3201 "ost's index in %s is not an hexa number\n",
3207 /* real_ostname is fsname-OSTXXXX????? */
3208 /* if OST name does not end with _UUID, we add it */
3210 strcat(real_ostname, "_UUID");
3211 } else if (strcmp(ptr, "_UUID") != 0) {
3213 "ostname %s does not end with _UUID\n", ostname);
3216 /* real_ostname is fsname-OSTXXXX_UUID */
3217 strcpy(ostname, real_ostname);
3221 /* returns 0 or -errno */
3222 static int pool_cmd(enum lcfg_command_type cmd,
3223 char *cmdname, char *fullpoolname,
3224 char *fsname, char *poolname, char *ostname)
3227 struct obd_ioctl_data data;
3228 struct lustre_cfg_bufs bufs;
3229 struct lustre_cfg *lcfg;
3230 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
3232 rc = check_pool_cmd(cmd, fsname, poolname, ostname);
3234 fprintf(stderr, "Can't verify pool command since there "
3235 "is no local MDT or client, proceeding anyhow...\n");
3239 lustre_cfg_bufs_reset(&bufs, NULL);
3240 lustre_cfg_bufs_set_string(&bufs, 0, cmdname);
3241 lustre_cfg_bufs_set_string(&bufs, 1, fullpoolname);
3242 if (ostname != NULL)
3243 lustre_cfg_bufs_set_string(&bufs, 2, ostname);
3245 lcfg = lustre_cfg_new(cmd, &bufs);
3251 memset(&data, 0, sizeof(data));
3252 rc = data.ioc_dev = get_mgs_device();
3256 data.ioc_type = LUSTRE_CFG_TYPE;
3257 data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount,
3258 lcfg->lcfg_buflens);
3259 data.ioc_pbuf1 = (void *)lcfg;
3261 memset(buf, 0, sizeof(rawbuf));
3262 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
3264 fprintf(stderr, "error: %s: invalid ioctl\n",
3265 jt_cmdname(cmdname));
3268 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_POOL, buf);
3272 lustre_cfg_free(lcfg);
3277 * this function tranforms a rule [start-end/step] into an array
3278 * of matching numbers
3279 * supported forms are:
3280 * [start] : just this number
3281 * [start-end] : all numbers from start to end
3282 * [start-end/step] : numbers from start to end with increment of step
3283 * on return, format contains a printf format string which can be used
3284 * to generate all the strings
3286 static int get_array_idx(char *rule, char *format, int **array)
3288 char *start, *end, *ptr;
3289 unsigned int lo, hi, step;
3294 start = strchr(rule, '[');
3295 end = strchr(rule, ']');
3296 if ((start == NULL) || (end == NULL)) {
3297 *array = malloc(sizeof(int));
3300 strcpy(format, rule);
3308 /* put in format the printf format (the rule without the range) */
3309 sprintf(format, "%s%%.4x%s", rule, end);
3314 /* loop on , separator */
3316 /* extract the 3 fields */
3317 rc = sscanf(start, "%x-%x/%u", &lo, &hi, &step);
3324 *array = realloc(*array, array_sz * sizeof(int));
3327 (*array)[array_idx] = lo;
3333 /* do not break to share code with case 3: */
3336 if ((hi < lo) || (step == 0))
3338 array_sz += (hi - lo) / step + 1;
3339 *array = realloc(*array, sizeof(int) * array_sz);
3342 for (i = lo; i <= hi; i+=step, array_idx++)
3343 (*array)[array_idx] = i;
3347 ptr = strchr(start, ',');
3351 } while (ptr != NULL);
3355 static int extract_fsname_poolname(char *arg, char *fsname, char *poolname)
3361 strcpy(fsname, arg);
3362 ptr = strchr(fsname, '.');
3364 fprintf(stderr, ". is missing in %s\n", fsname);
3371 fprintf(stderr, "fsname is empty\n");
3376 len = strlen(ptr + 1);
3378 fprintf(stderr, "poolname is empty\n");
3382 if (len > LOV_MAXPOOLNAME) {
3384 "poolname %s is too long (length is %d max is %d)\n",
3385 ptr + 1, len, LOV_MAXPOOLNAME);
3389 strncpy(poolname, ptr + 1, LOV_MAXPOOLNAME);
3390 poolname[LOV_MAXPOOLNAME] = '\0';
3395 fprintf(stderr, "argument %s must be <fsname>.<poolname>\n", arg);
3399 int jt_pool_cmd(int argc, char **argv)
3401 enum lcfg_command_type cmd;
3402 char fsname[PATH_MAX + 1];
3403 char poolname[LOV_MAXPOOLNAME + 1];
3404 char *ostnames_buf = NULL;
3406 int *array = NULL, array_sz;
3414 case 1: return CMD_HELP;
3416 if (strcmp("pool_new", argv[0]) == 0)
3417 cmd = LCFG_POOL_NEW;
3418 else if (strcmp("pool_destroy", argv[0]) == 0)
3419 cmd = LCFG_POOL_DEL;
3420 else if (strcmp("pool_list", argv[0]) == 0)
3421 return llapi_poollist(argv[1]);
3422 else return CMD_HELP;
3424 rc = extract_fsname_poolname(argv[1], fsname, poolname);
3428 rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL);
3432 check_pool_cmd_result(cmd, fsname, poolname, NULL);
3436 char format[2*MAX_OBD_NAME];
3438 if (strcmp("pool_remove", argv[0]) == 0) {
3439 cmd = LCFG_POOL_REM;
3440 } else if (strcmp("pool_add", argv[0]) == 0) {
3441 cmd = LCFG_POOL_ADD;
3446 rc = extract_fsname_poolname(argv[1], fsname, poolname);
3450 for (i = 2; i < argc; i++) {
3453 array_sz = get_array_idx(argv[i], format, &array);
3457 cmds = malloc(array_sz * sizeof(cmds[0]));
3459 ostnames_buf = malloc(array_sz *
3460 (MAX_OBD_NAME + 1));
3467 for (j = 0; j < array_sz; j++) {
3468 char ostname[MAX_OBD_NAME + 1];
3470 snprintf(ostname, MAX_OBD_NAME, format,
3472 ostname[MAX_OBD_NAME] = '\0';
3474 rc = check_and_complete_ostname(fsname,ostname);
3482 if (ostnames_buf != NULL) {
3484 &ostnames_buf[(MAX_OBD_NAME + 1) * j];
3485 strcpy(cmds[j].ostname, ostname);
3487 cmds[j].ostname = NULL;
3489 cmds[j].rc = pool_cmd(cmd, argv[0], argv[1],
3492 /* Return an err if any of the add/dels fail */
3496 for (j = 0; j < array_sz; j++) {
3498 char ostname[MAX_OBD_NAME + 1];
3500 if (!cmds[j].ostname) {
3501 snprintf(ostname, MAX_OBD_NAME,
3503 ostname[MAX_OBD_NAME] = '\0';
3504 check_and_complete_ostname(
3510 check_pool_cmd_result(cmd, fsname,
3534 int jt_get_obj_version(int argc, char **argv)
3537 struct obd_ioctl_data data;
3539 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf, *fidstr;
3546 while (*fidstr == '[')
3548 sscanf(fidstr, SFID, RFID(&fid));
3549 if (!fid_is_sane(&fid)) {
3550 fprintf(stderr, "bad FID format [%s], should be "DFID"\n",
3551 fidstr, (__u64)1, 2, 0);
3555 memset(&data, 0, sizeof data);
3556 data.ioc_dev = cur_device;
3557 data.ioc_inlbuf1 = (char *) &fid;
3558 data.ioc_inllen1 = sizeof fid;
3559 data.ioc_inlbuf2 = (char *) &version;
3560 data.ioc_inllen2 = sizeof version;
3562 memset(buf, 0, sizeof *buf);
3563 rc = obd_ioctl_pack(&data, &buf, sizeof rawbuf);
3565 fprintf(stderr, "error: %s: packing ioctl arguments: %s\n",
3566 jt_cmdname(argv[0]), strerror(-rc));
3570 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GET_OBJ_VERSION, buf);
3572 fprintf(stderr, "error: %s: ioctl: %s\n",
3573 jt_cmdname(argv[0]), strerror(errno));
3577 obd_ioctl_unpack(&data, buf, sizeof rawbuf);
3578 printf(LPX64"\n", version);
3582 void llapi_ping_target(char *obd_type, char *obd_name,
3583 char *obd_uuid, void *args)
3586 struct obd_ioctl_data data;
3587 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
3589 memset(&data, 0, sizeof(data));
3590 data.ioc_inlbuf4 = obd_name;
3591 data.ioc_inllen4 = strlen(obd_name) + 1;
3592 data.ioc_dev = OBD_DEV_BY_DEVNAME;
3593 memset(buf, 0, sizeof(rawbuf));
3594 if (obd_ioctl_pack(&data, &buf, sizeof(rawbuf))) {
3595 fprintf(stderr, "error: invalid ioctl\n");
3598 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_PING_TARGET, buf);
3601 if (rc == ENOTCONN || rc == ESHUTDOWN) {
3602 printf("%s: INACTIVE\n", obd_name);
3604 printf("%s: check error: %s\n",
3605 obd_name, strerror(errno));
3607 printf("%s: active\n", obd_name);
3611 int jt_changelog_register(int argc, char **argv)
3613 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
3614 struct obd_ioctl_data data;
3620 else if (argc == 2 && strcmp(argv[1], "-n") != 0)
3625 memset(&data, 0, sizeof(data));
3626 data.ioc_dev = cur_device;
3627 memset(buf, 0, sizeof(rawbuf));
3628 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
3630 fprintf(stderr, "error: %s: invalid ioctl\n",
3631 jt_cmdname(argv[0]));
3635 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_REG, buf);
3637 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
3638 strerror(rc = errno));
3641 obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
3643 if (data.ioc_u32_1 == 0) {
3644 fprintf(stderr, "received invalid userid!\n");
3648 if (lcfg_get_devname() != NULL)
3649 strcpy(devname, lcfg_get_devname());
3651 sprintf(devname, "dev %d", cur_device);
3654 /* -n means bare name */
3655 printf(CHANGELOG_USER_PREFIX"%u\n", data.ioc_u32_1);
3657 printf("%s: Registered changelog userid '"CHANGELOG_USER_PREFIX
3658 "%u'\n", devname, data.ioc_u32_1);
3662 int jt_changelog_deregister(int argc, char **argv)
3664 char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
3665 struct obd_ioctl_data data;
3669 if (argc != 2 || cur_device < 0)
3672 id = strtol(argv[1] + strlen(CHANGELOG_USER_PREFIX), NULL, 10);
3673 if ((id == 0) || (strncmp(argv[1], CHANGELOG_USER_PREFIX,
3674 strlen(CHANGELOG_USER_PREFIX)) != 0)) {
3675 fprintf(stderr, "expecting id of the form '"
3676 CHANGELOG_USER_PREFIX"<num>'; got '%s'\n", argv[1]);
3680 memset(&data, 0, sizeof(data));
3681 data.ioc_dev = cur_device;
3682 data.ioc_u32_1 = id;
3683 memset(buf, 0, sizeof(rawbuf));
3684 rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
3686 fprintf(stderr, "error: %s: invalid ioctl\n",
3687 jt_cmdname(argv[0]));
3691 rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_DEREG, buf);
3693 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
3694 strerror(rc = errno));
3697 obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
3699 if (data.ioc_u32_1 != id) {
3700 fprintf(stderr, "No changelog user '%s'. Blocking user"
3701 " is '"CHANGELOG_USER_PREFIX"%d'.\n", argv[1],
3706 if (lcfg_get_devname() != NULL)
3707 strcpy(devname, lcfg_get_devname());
3709 sprintf(devname, "dev %d", cur_device);
3711 printf("%s: Deregistered changelog user '"CHANGELOG_USER_PREFIX"%d'\n",
3712 devname, data.ioc_u32_1);