1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
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>
10 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
29 #include <sys/ioctl.h>
31 #include <sys/socket.h>
32 #include <sys/types.h>
40 #include <linux/lustre_lib.h>
41 #include <linux/lustre_idl.h>
42 #include <linux/lustre_dlm.h>
48 #include <netinet/in.h>
52 #include <asm/page.h> /* needed for PAGE_SIZE - rread */
55 #include <linux/list.h>
67 # define MAX_SHMEM_COUNT 1024
68 static long long *shared_counters;
69 static long long counter_snapshot[2][MAX_SHMEM_COUNT];
70 struct timeval prev_time;
74 uint64_t conn_addr = -1;
82 static int getfd(char *func);
83 static char *cmdname(char *func);
85 #define IOCINIT(data) \
87 memset(&data, 0, sizeof(data)); \
88 data.ioc_version = OBD_IOCTL_VERSION; \
89 data.ioc_addr = conn_addr; \
90 data.ioc_cookie = conn_cookie; \
91 data.ioc_len = sizeof(data); \
93 fprintf(stderr, "No device open, use device\n"); \
99 pack "LL LL LL LL LL LL LL L L L L L L L L L a60 a60 L L L",
118 0, 0, # struct list_head
124 char *obdo_print(struct obdo *obd)
128 sprintf(buf, "id: %Ld\ngrp: %Ld\natime: %Ld\nmtime: %Ld\nctime: %Ld\n"
129 "size: %Ld\nblocks: %Ld\nblksize: %d\nmode: %o\nuid: %d\n"
130 "gid: %d\nflags: %x\nobdflags: %x\nnlink: %d,\nvalid %x\n",
142 obd->o_flags, obd->o_obdflags, obd->o_nlink, obd->o_valid);
148 #define N2D_OFF 0x100 /* So we can tell between error codes and devices */
150 static int do_name2dev(char *func, char *name)
152 struct obd_ioctl_data data;
160 data.ioc_inllen1 = strlen(name) + 1;
161 data.ioc_inlbuf1 = name;
163 if (obd_ioctl_pack(&data, &buf, max)) {
164 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(func));
167 rc = ioctl(fd, OBD_IOC_NAME2DEV, buf);
169 fprintf(stderr, "error: %s: %s - %s\n", cmdname(func),
170 name, strerror(rc = errno));
174 memcpy((char *)(&data), buf, sizeof(data));
176 return data.ioc_dev + N2D_OFF;
180 * resolve a device name to a device number.
181 * supports a number or name.
182 * FIXME: support UUID
184 static int parse_devname(char * func, char *name)
191 if (name[0] == '$') {
192 rc = do_name2dev(func, name + 1);
195 printf("%s is device %d\n", name,
198 fprintf(stderr, "error: %s: %s: %s\n", cmdname(func),
199 name, "device not found");
202 ret = strtoul(name, NULL, 0);
207 static char *cmdname(char *func)
209 static char buf[512];
212 sprintf(buf, "%s-%d", func, thread);
219 static int getfd(char *func)
222 fd = open("/dev/obd", O_RDWR);
224 fprintf(stderr, "error: %s: opening /dev/obd: %s\n"
225 "hint: lustre kernel modules may not be loaded.\n",
226 cmdname(func), strerror(errno));
232 #define difftime(a, b) \
233 ((double)(a)->tv_sec - (b)->tv_sec + \
234 ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
236 static int be_verbose(int verbose, struct timeval *next_time,
237 int num, int *next_num, int num_total)
244 if (next_time != NULL)
245 gettimeofday(&now, NULL);
247 /* A positive verbosity means to print every X iterations */
249 (next_num == NULL || num >= *next_num || num >= num_total)) {
250 *next_num += verbose;
252 next_time->tv_sec = now.tv_sec - verbose;
253 next_time->tv_usec = now.tv_usec;
258 /* A negative verbosity means to print at most each X seconds */
259 if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0) {
260 next_time->tv_sec = now.tv_sec - verbose;
261 next_time->tv_usec = now.tv_usec;
270 static int get_verbose(const char *arg)
274 if (!arg || arg[0] == 'v')
276 else if (arg[0] == 's' || arg[0] == 'q')
279 verbose = (int)strtoul(arg, NULL, 0);
282 printf("Print status every %d seconds\n", -verbose);
283 else if (verbose == 1)
284 printf("Print status every operation\n");
285 else if (verbose > 1)
286 printf("Print status every %d operations\n", verbose);
291 int do_disconnect(char *func, int verbose)
294 struct obd_ioctl_data data;
301 rc = ioctl(fd, OBD_IOC_DISCONNECT, &data);
303 fprintf(stderr, "error: %s: %x %s\n", cmdname(func),
304 OBD_IOC_DISCONNECT, strerror(errno));
307 printf("%s: disconnected conn %Lx\n", cmdname(func),
316 static void shmem_setup(void)
318 int shmid = shmget(IPC_PRIVATE, sizeof(counter_snapshot[0]), 0600);
321 fprintf(stderr, "Can't create shared memory counters: %s\n",
326 shared_counters = (long long *)shmat(shmid, NULL, 0);
328 if (shared_counters == (long long *)(-1)) {
329 fprintf(stderr, "Can't attach shared memory counters: %s\n",
331 shared_counters = NULL;
336 static inline void shmem_reset(void)
338 if (shared_counters == NULL)
341 memset(shared_counters, 0, sizeof(counter_snapshot[0]));
342 memset(counter_snapshot, 0, sizeof(counter_snapshot));
343 gettimeofday(&prev_time, NULL);
346 static inline void shmem_bump(void)
348 if (shared_counters == NULL || thread <= 0 || thread > MAX_SHMEM_COUNT)
351 shared_counters[thread - 1]++;
354 static void shmem_snap(int n)
356 struct timeval this_time;
362 if (shared_counters == NULL || n > MAX_SHMEM_COUNT)
365 memcpy(counter_snapshot[1], counter_snapshot[0],
366 n * sizeof(counter_snapshot[0][0]));
367 memcpy(counter_snapshot[0], shared_counters,
368 n * sizeof(counter_snapshot[0][0]));
369 gettimeofday(&this_time, NULL);
371 for (i = 0; i < n; i++) {
372 long long this_count =
373 counter_snapshot[0][i] - counter_snapshot[1][i];
375 if (this_count != 0) {
381 secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) -
382 (prev_time.tv_sec + prev_time.tv_usec / 1000000.0);
384 printf("%d/%d Total: %f/second\n", non_zero, n, total / secs);
386 prev_time = this_time;
389 #define SHMEM_SETUP() shmem_setup()
390 #define SHMEM_RESET() shmem_reset()
391 #define SHMEM_BUMP() shmem_bump()
392 #define SHMEM_SNAP(n) shmem_snap(n)
394 #define SHMEM_SETUP()
395 #define SHMEM_RESET()
397 #define SHMEM_SNAP(n)
400 extern command_t cmdlist[];
402 static int do_device(char *func, int dev)
404 struct obd_ioctl_data data;
406 memset(&data, 0, sizeof(data));
413 if (obd_ioctl_pack(&data, &buf, max)) {
414 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(func));
418 return ioctl(fd, OBD_IOC_DEVICE, buf);
421 int jt_obd_device(int argc, char **argv)
424 do_disconnect(argv[0], 1);
429 dev = parse_devname(argv[0], argv[1]);
433 rc = do_device(argv[0], dev);
435 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
436 strerror(rc = errno));
441 int jt_obd_connect(int argc, char **argv)
443 struct obd_ioctl_data data;
448 do_disconnect(argv[0], 1);
450 #warning Robert: implement timeout per lctl usage for probe
454 rc = ioctl(fd, OBD_IOC_CONNECT, &data);
456 fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
457 OBD_IOC_CONNECT, strerror(rc = errno));
459 conn_addr = data.ioc_addr;
460 conn_cookie = data.ioc_cookie;
465 int jt_obd_disconnect(int argc, char **argv)
473 return do_disconnect(argv[0], 0);
476 int jt_opt_device(int argc, char **argv)
483 fprintf(stderr, "usage: %s devno <command [args ...]>\n",
488 rc = do_device("device", parse_devname(argv[0], argv[1]));
493 rc = jt_obd_connect(1, arg2);
497 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
499 ret = do_disconnect(argv[0], 0);
506 int jt_opt_threads(int argc, char **argv)
508 int threads, next_thread;
515 "usage: %s numthreads verbose devno <cmd [args ...]>\n",
520 threads = strtoul(argv[1], NULL, 0);
522 verbose = get_verbose(argv[2]);
525 printf("%s: starting %d threads on device %s running %s\n",
526 argv[0], threads, argv[3], argv[4]);
530 for (i = 1, next_thread = verbose; i <= threads; i++) {
533 fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
534 strerror(rc = errno));
536 } else if (rc == 0) {
538 argv[2] = "--device";
539 return jt_opt_device(argc - 2, argv + 2);
540 } else if (be_verbose(verbose, NULL, i, &next_thread, threads))
541 printf("%s: thread #%d (PID %d) started\n",
546 if (!thread) { /* parent process */
547 int live_threads = threads;
549 while (live_threads > 0) {
553 ret = waitpid(0, &status, verbose < 0 ? WNOHANG : 0);
564 fprintf(stderr, "error: %s: wait - %s\n",
565 argv[0], strerror(errno));
570 * This is a hack. We _should_ be able to use
571 * WIFEXITED(status) to see if there was an
572 * error, but it appears to be broken and it
573 * always returns 1 (OK). See wait(2).
575 int err = WEXITSTATUS(status);
578 "%s: PID %d had rc=%d\n",
591 int jt_obd_detach(int argc, char **argv)
593 struct obd_ioctl_data data;
601 if (obd_ioctl_pack(&data, &buf, max)) {
602 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
606 rc = ioctl(fd, OBD_IOC_DETACH, buf);
608 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
609 strerror(rc = errno));
614 int jt_obd_cleanup(int argc, char **argv)
616 struct obd_ioctl_data data;
624 rc = ioctl(fd, OBD_IOC_CLEANUP, &data);
626 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
627 strerror(rc = errno));
632 int jt_obd_newdev(int argc, char **argv)
635 struct obd_ioctl_data data;
645 rc = ioctl(fd, OBD_IOC_NEWDEV, &data);
647 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
648 strerror(rc = errno));
650 printf("Current device set to %d\n", data.ioc_dev);
656 int jt_obd_list(int argc, char **argv)
660 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
665 memset(buf, 0, sizeof(buf));
666 data->ioc_version = OBD_IOCTL_VERSION;
667 data->ioc_addr = conn_addr;
668 data->ioc_cookie = conn_addr;
669 data->ioc_len = sizeof(buf);
670 data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
675 rc = ioctl(fd, OBD_IOC_LIST, data);
677 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
678 strerror(rc = errno));
680 printf("%s", data->ioc_bulk);
686 int jt_obd_attach(int argc, char **argv)
688 struct obd_ioctl_data data;
693 if (argc != 2 && argc != 3 && argc != 4)
696 data.ioc_inllen1 = strlen(argv[1]) + 1;
697 data.ioc_inlbuf1 = argv[1];
699 data.ioc_inllen2 = strlen(argv[2]) + 1;
700 data.ioc_inlbuf2 = argv[2];
704 data.ioc_inllen3 = strlen(argv[3]) + 1;
705 data.ioc_inlbuf3 = argv[3];
708 if (obd_ioctl_pack(&data, &buf, max)) {
709 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
713 rc = ioctl(fd, OBD_IOC_ATTACH, buf);
715 fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
716 OBD_IOC_ATTACH, strerror(rc = errno));
717 else if (argc == 3) {
719 if (strlen(argv[2]) > 128) {
720 printf("Name too long to set environment\n");
723 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
724 rc = setenv(name, argv[1], 1);
726 printf("error setting env variable %s\n", name);
733 int jt_obd_name2dev(int argc, char **argv)
740 rc = do_name2dev(argv[0], argv[1]);
742 int dev = rc - N2D_OFF;
743 rc = do_device(argv[0], dev);
750 int jt_obd_setup(int argc, char **argv)
752 struct obd_ioctl_data data;
762 data.ioc_dev = parse_devname(argv[0], argv[1]);
763 if (data.ioc_dev < 0)
765 data.ioc_inllen1 = strlen(argv[1]) + 1;
766 data.ioc_inlbuf1 = argv[1];
769 data.ioc_inllen2 = strlen(argv[2]) + 1;
770 data.ioc_inlbuf2 = argv[2];
773 if (obd_ioctl_pack(&data, &buf, max)) {
774 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
777 rc = ioctl(fd, OBD_IOC_SETUP, buf);
779 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
780 strerror(rc = errno));
786 int jt_obd_create(int argc, char **argv)
788 struct obd_ioctl_data data;
789 struct timeval next_time;
790 int count = 1, next_count;
795 if (argc < 2 || argc > 4)
798 count = strtoul(argv[1], NULL, 0);
801 data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
803 data.ioc_obdo1.o_mode = 0100644;
804 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
807 verbose = get_verbose(argv[3]);
809 printf("%s: %d objects\n", cmdname(argv[0]), count);
810 gettimeofday(&next_time, NULL);
811 next_time.tv_sec -= verbose;
813 for (i = 1, next_count = verbose; i <= count; i++) {
814 rc = ioctl(fd, OBD_IOC_CREATE, &data);
817 fprintf(stderr, "error: %s: #%d - %s\n",
818 cmdname(argv[0]), i, strerror(rc = errno));
821 if (be_verbose(verbose, &next_time, i, &next_count, count))
822 printf("%s: #%d is object id %Ld\n", cmdname(argv[0]),
823 i, data.ioc_obdo1.o_id);
828 int jt_obd_setattr(int argc, char **argv)
830 struct obd_ioctl_data data;
837 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
838 data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], NULL, 0);
839 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
841 rc = ioctl(fd, OBD_IOC_SETATTR, &data);
843 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
844 strerror(rc = errno));
849 int jt_obd_destroy(int argc, char **argv)
851 struct obd_ioctl_data data;
858 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
859 data.ioc_obdo1.o_mode = S_IFREG | 0644;
861 rc = ioctl(fd, OBD_IOC_DESTROY, &data);
863 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
864 strerror(rc = errno));
869 int jt_obd_getattr(int argc, char **argv)
871 struct obd_ioctl_data data;
878 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
879 /* to help obd filter */
880 data.ioc_obdo1.o_mode = 0100644;
881 data.ioc_obdo1.o_valid = 0xffffffff;
882 printf("%s: object id %Ld\n", cmdname(argv[0]), data.ioc_obdo1.o_id);
884 rc = ioctl(fd, OBD_IOC_GETATTR, &data);
886 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
887 strerror(rc = errno));
889 printf("%s: object id %Ld, mode %o\n", cmdname(argv[0]),
890 data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
895 int jt_obd_test_getattr(int argc, char **argv)
897 struct obd_ioctl_data data;
898 struct timeval start, next_time;
899 int i, count, next_count;
903 if (argc != 2 && argc != 3)
907 count = strtoul(argv[1], NULL, 0);
910 verbose = get_verbose(argv[2]);
914 data.ioc_obdo1.o_valid = 0xffffffff;
915 data.ioc_obdo1.o_id = 2;
916 gettimeofday(&start, NULL);
917 next_time.tv_sec = start.tv_sec - verbose;
918 next_time.tv_usec = start.tv_usec;
920 printf("%s: getting %d attrs (testing only): %s",
921 cmdname(argv[0]), count, ctime(&start.tv_sec));
923 for (i = 1, next_count = verbose; i <= count; i++) {
924 rc = ioctl(fd, OBD_IOC_GETATTR, &data);
927 fprintf(stderr, "error: %s: #%d - %s\n",
928 cmdname(argv[0]), i, strerror(rc = errno));
932 (verbose, &next_time, i, &next_count, count))
933 printf("%s: got attr #%d\n", cmdname(argv[0]),
942 gettimeofday(&end, NULL);
944 diff = difftime(&end, &start);
948 printf("%s: %d attrs in %.4gs (%.4g attr/s): %s",
949 cmdname(argv[0]), i, diff, (double)i / diff,
955 int jt_obd_test_brw(int argc, char **argv)
957 struct obd_ioctl_data data;
958 struct timeval start, next_time;
959 int pages = 1, objid = 3, count, next_count;
960 int verbose = 1, write = 0, rw;
966 if (argc < 2 || argc > 6)
969 count = strtoul(argv[1], NULL, 0);
972 if (argv[2][0] == 'w' || argv[2][0] == '1')
974 else if (argv[2][0] == 'r' || argv[2][0] == '0')
977 verbose = get_verbose(argv[3]);
981 pages = strtoul(argv[4], NULL, 0);
983 objid = strtoul(argv[5], NULL, 0);
985 len = pages * PAGE_SIZE;
988 data.ioc_obdo1.o_id = objid;
989 data.ioc_count = len;
992 gettimeofday(&start, NULL);
993 next_time.tv_sec = start.tv_sec - verbose;
994 next_time.tv_usec = start.tv_usec;
997 printf("%s: %s %dx%d pages (testing only): %s",
998 cmdname(argv[0]), write ? "writing" : "reading",
999 count, pages, ctime(&start.tv_sec));
1001 rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
1002 for (i = 1, next_count = verbose, offset = 0; i <= count; i++) {
1003 rc = ioctl(fd, rw, &data);
1006 fprintf(stderr, "error: %s: #%d - %s on %s\n",
1007 cmdname(argv[0]), i, strerror(rc = errno),
1008 write ? "write" : "read");
1010 } else if (be_verbose
1011 (verbose, &next_time, i, &next_count, count))
1012 printf("%s: %s number %d\n", cmdname(argv[0]),
1013 write ? "write" : "read", i);
1015 data.ioc_offset += len;
1022 gettimeofday(&end, NULL);
1024 diff = difftime(&end, &start);
1028 printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s",
1029 cmdname(argv[0]), write ? "wrote" : "read",
1030 i, pages, diff, (double)i * pages / diff,
1031 ctime(&end.tv_sec));
1036 int jt_obd_lov_config(int argc, char **argv)
1038 struct obd_ioctl_data data;
1039 struct lov_desc desc;
1047 if (strlen(argv[1]) > sizeof(uuid_t) - 1) {
1048 fprintf(stderr, "lov_config: no %dB memory for uuid's\n",
1053 memset(&desc, 0, sizeof(desc));
1054 strcpy(desc.ld_uuid, argv[1]);
1055 desc.ld_default_stripe_count = strtoul(argv[2], NULL, 0);
1056 desc.ld_default_stripe_size = strtoul(argv[3], NULL, 0);
1057 desc.ld_default_stripe_offset = (__u64) strtoul(argv[4], NULL, 0);
1058 desc.ld_pattern = strtoul(argv[5], NULL, 0);
1059 desc.ld_tgt_count = argc - 6;
1062 size = sizeof(uuid_t) * desc.ld_tgt_count;
1063 uuidarray = malloc(size);
1065 fprintf(stderr, "lov_config: no %dB memory for uuid's\n", size);
1068 memset(uuidarray, 0, size);
1069 for (i = 6; i < argc; i++) {
1070 char *buf = (char *)(uuidarray + i - 6);
1071 if (strlen(argv[i]) >= sizeof(uuid_t)) {
1072 fprintf(stderr, "lov_config: arg %d (%s) too long\n",
1077 strcpy(buf, argv[i]);
1080 data.ioc_inllen1 = sizeof(desc);
1081 data.ioc_inlbuf1 = (char *)&desc;
1082 data.ioc_inllen2 = size;
1083 data.ioc_inlbuf2 = (char *)uuidarray;
1085 if (obd_ioctl_pack(&data, &buf, max)) {
1086 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1090 rc = ioctl(fd, OBD_IOC_LOV_CONFIG, buf);
1092 fprintf(stderr, "lov_config: error: %s: %s\n",
1093 cmdname(argv[0]), strerror(rc = errno));
1098 int jt_obd_test_ldlm(int argc, char **argv)
1100 struct obd_ioctl_data data;
1107 rc = ioctl(fd, IOC_LDLM_TEST, &data);
1109 fprintf(stderr, "error: %s: test failed: %s\n",
1110 cmdname(argv[0]), strerror(rc = errno));
1114 int jt_obd_dump_ldlm(int argc, char **argv)
1116 struct obd_ioctl_data data;
1123 rc = ioctl(fd, IOC_LDLM_DUMP, &data);
1125 fprintf(stderr, "error: %s failed: %s\n",
1126 cmdname(argv[0]), strerror(rc = errno));
1130 int jt_obd_ldlm_regress_start(int argc, char **argv)
1133 struct obd_ioctl_data data;
1141 data.ioc_inllen1 = strlen(argv[1]) + 1;
1142 data.ioc_inlbuf1 = argv[1];
1144 data.ioc_inllen1 = 0;
1147 if (obd_ioctl_pack(&data, &buf, max)) {
1148 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1152 rc = ioctl(fd, IOC_LDLM_REGRESS_START, buf);
1155 fprintf(stderr, "error: %s: test failed: %s\n",
1156 cmdname(argv[0]), strerror(rc = errno));
1161 int jt_obd_ldlm_regress_stop(int argc, char **argv)
1164 struct obd_ioctl_data data;
1170 rc = ioctl(fd, IOC_LDLM_REGRESS_STOP, &data);
1173 fprintf(stderr, "error: %s: test failed: %s\n",
1174 cmdname(argv[0]), strerror(rc = errno));
1178 int jt_obd_newconn(int argc, char **argv)
1181 struct obd_ioctl_data data;
1187 rc = ioctl(fd, OBD_IOC_RECOVD_NEWCONN, &data);
1189 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1190 strerror(rc = errno));
1195 static void signal_server(int sig)
1197 if (sig == SIGINT) {
1198 do_disconnect("sigint", 1);
1201 fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig);
1204 int obd_initialize(int argc, char **argv)
1211 void obd_cleanup(int argc, char **argv)
1213 struct sigaction sigact;
1215 sigact.sa_handler = signal_server;
1216 sigfillset(&sigact.sa_mask);
1217 sigact.sa_flags = SA_RESTART;
1218 sigaction(SIGINT, &sigact, NULL);
1220 do_disconnect(argv[0], 1);