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 <liblustre.h>
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>
53 #include <netinet/in.h>
57 #include <asm/page.h> /* needed for PAGE_SIZE - rread */
60 #include <linux/list.h>
64 #include <portals/ptlctl.h>
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;
79 uint64_t conn_addr = -1;
83 int max = sizeof(rawbuf);
89 struct lov_stripe_md lsm;
92 static char *cmdname(char *func);
94 #define IOC_INIT(data) \
96 memset(&data, 0, sizeof(data)); \
97 data.ioc_addr = conn_addr; \
98 data.ioc_cookie = conn_cookie; \
101 #define IOC_PACK(func, data) \
103 memset(buf, 0, sizeof(rawbuf)); \
104 if (obd_ioctl_pack(&data, &buf, max)) { \
105 fprintf(stderr, "error: %s: invalid ioctl\n", \
111 #define IOC_UNPACK(func, data) \
113 if (obd_ioctl_unpack(&data, buf, max)) { \
114 fprintf(stderr, "error: %s: invalid reply\n", \
120 char *obdo_print(struct obdo *obd)
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);
136 #define BAD_VERBOSE (-999999999)
138 #define N2D_OFF 0x100 /* So we can tell between error codes and devices */
140 static int do_name2dev(char *func, char *name)
142 struct obd_ioctl_data data;
147 data.ioc_inllen1 = strlen(name) + 1;
148 data.ioc_inlbuf1 = name;
150 IOC_PACK(func, data);
151 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf);
153 fprintf(stderr, "error: %s: %s - %s\n", cmdname(func),
154 name, strerror(rc = errno));
157 IOC_UNPACK(func, data);
159 return data.ioc_dev + N2D_OFF;
163 * resolve a device name to a device number.
164 * supports a number or name.
165 * FIXME: support UUID
167 static int parse_devname(char *func, char *name)
174 if (name[0] == '$') {
175 rc = do_name2dev(func, name + 1);
178 printf("%s is device %d\n", name, ret);
180 fprintf(stderr, "error: %s: %s: %s\n", cmdname(func),
181 name, "device not found");
184 ret = strtoul(name, NULL, 0);
190 lsm_string (struct lov_stripe_md *lsm)
192 static char buffer[4096];
194 int space = sizeof (buffer);
201 nob = snprintf(p, space, LPX64, lsm->lsm_object_id);
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);
213 for (i = 0; i < lsm->lsm_stripe_count; i++) {
214 nob = snprintf (p, space, ":"LPX64,
215 lsm->lsm_oinfo[i].loi_id);
221 if (space == 0) { /* probable overflow */
222 fprintf (stderr, "lsm_string() overflowed buffer\n");
230 reset_lsmb (union lsm_buffer *lsmb)
232 memset (lsmb->space, 0, sizeof (lsmb->space));
233 lsmb->lsm.lsm_magic = LOV_MAGIC;
237 parse_lsm (union lsm_buffer *lsmb, char *string)
239 struct lov_stripe_md *lsm = &lsmb->lsm;
244 * object_id[=size#count[@offset][:id]*]
249 lsm->lsm_object_id = strtoull (string, &end, 0);
261 lsm->lsm_stripe_size = strtoul (string, &end, 0);
270 lsm->lsm_stripe_count = strtoul (string, &end, 0);
275 if (*string == '@') {
277 lsm->lsm_stripe_offset = strtol (string, &end, 0);
283 if (*string == 0) /* don't have to specify obj ids */
286 for (i = 0; i < lsm->lsm_stripe_count; i++) {
290 lsm->lsm_oinfo[i].loi_id = strtoull (string, &end, 0);
300 static char *cmdname(char *func)
302 static char buf[512];
305 sprintf(buf, "%s-%d", func, thread);
312 #define difftime(a, b) \
313 ((double)(a)->tv_sec - (b)->tv_sec + \
314 ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
316 static int be_verbose(int verbose, struct timeval *next_time,
317 __u64 num, __u64 *next_num, int num_total)
324 if (next_time != NULL)
325 gettimeofday(&now, NULL);
327 /* A positive verbosity means to print every X iterations */
329 (next_num == NULL || num >= *next_num || num >= num_total)) {
330 *next_num += verbose;
332 next_time->tv_sec = now.tv_sec - verbose;
333 next_time->tv_usec = now.tv_usec;
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;
350 static int get_verbose(char *func, const char *arg)
355 if (!arg || arg[0] == 'v')
357 else if (arg[0] == 's' || arg[0] == 'q')
360 verbose = (int)strtoul(arg, &end, 0);
362 fprintf(stderr, "error: %s: bad verbose option '%s'\n",
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);
378 int do_disconnect(char *func, int verbose)
381 struct obd_ioctl_data data;
388 IOC_PACK(func, data);
389 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DISCONNECT, buf);
391 fprintf(stderr, "error: %s: OPD_IOC_DISCONNECT %s\n",
392 cmdname(func),strerror(errno));
395 printf("%s: disconnected conn "LPX64"\n", cmdname(func),
404 static void shmem_setup(void)
406 /* Create new segment */
407 int shmid = shmget(IPC_PRIVATE, sizeof(counter_snapshot[0]), 0600);
410 fprintf(stderr, "Can't create shared memory counters: %s\n",
415 /* Attatch to new segment */
416 shared_counters = (long long *)shmat(shmid, NULL, 0);
418 if (shared_counters == (long long *)(-1)) {
419 fprintf(stderr, "Can't attach shared memory counters: %s\n",
421 shared_counters = NULL;
425 /* Mark segment as destroyed, so it will disappear when we exit.
426 * Forks will inherit attached segments, so we should be OK.
428 if (shmctl(shmid, IPC_RMID, NULL) == -1) {
429 fprintf(stderr, "Can't destroy shared memory counters: %s\n",
434 static inline void shmem_reset(void)
436 if (shared_counters == NULL)
439 memset(shared_counters, 0, sizeof(counter_snapshot[0]));
440 memset(counter_snapshot, 0, sizeof(counter_snapshot));
441 gettimeofday(&prev_time, NULL);
444 static inline void shmem_bump(void)
446 if (shared_counters == NULL || thread <= 0 || thread > MAX_SHMEM_COUNT)
449 shared_counters[thread - 1]++;
452 static void shmem_snap(int n)
454 struct timeval this_time;
460 if (shared_counters == NULL || n > MAX_SHMEM_COUNT)
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);
469 for (i = 0; i < n; i++) {
470 long long this_count =
471 counter_snapshot[0][i] - counter_snapshot[1][i];
473 if (this_count != 0) {
479 secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) -
480 (prev_time.tv_sec + prev_time.tv_usec / 1000000.0);
482 printf("%d/%d Total: %f/second\n", non_zero, n, total / secs);
484 prev_time = this_time;
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)
492 #define SHMEM_SETUP()
493 #define SHMEM_RESET()
495 #define SHMEM_SNAP(n)
498 extern command_t cmdlist[];
500 static int do_device(char *func, int dev)
502 struct obd_ioctl_data data;
504 memset(&data, 0, sizeof(data));
508 IOC_PACK(func, data);
509 return l_ioctl(OBD_DEV_ID, OBD_IOC_DEVICE, buf);
512 int jt_obd_device(int argc, char **argv)
515 do_disconnect(argv[0], 1);
520 dev = parse_devname(argv[0], argv[1]);
524 rc = do_device(argv[0], dev);
526 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
527 strerror(rc = errno));
532 int jt_obd_connect(int argc, char **argv)
534 struct obd_ioctl_data data;
539 do_disconnect(argv[0], 1);
541 /* XXX TODO: implement timeout per lctl usage for probe */
545 IOC_PACK(argv[0], data);
546 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CONNECT, buf);
547 IOC_UNPACK(argv[0], data);
549 fprintf(stderr, "error: %s: OBD_IOC_CONNECT %s\n",
550 cmdname(argv[0]), strerror(rc = errno));
552 conn_addr = data.ioc_addr;
553 conn_cookie = data.ioc_cookie;
558 int jt_obd_disconnect(int argc, char **argv)
566 return do_disconnect(argv[0], 0);
569 int jt_opt_device(int argc, char **argv)
578 rc = do_device("device", parse_devname(argv[0], argv[1]));
583 rc = jt_obd_connect(1, arg2);
587 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
589 ret = do_disconnect(argv[0], 0);
596 int jt_opt_threads(int argc, char **argv)
598 __u64 threads, next_thread;
607 threads = strtoull(argv[1], &end, 0);
609 fprintf(stderr, "error: %s: invalid page count '%s'\n",
610 cmdname(argv[0]), argv[1]);
614 verbose = get_verbose(argv[0], argv[2]);
615 if (verbose == BAD_VERBOSE)
619 printf("%s: starting "LPD64" threads on device %s running %s\n",
620 argv[0], threads, argv[3], argv[4]);
624 for (i = 1, next_thread = verbose; i <= threads; i++) {
627 fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
628 strerror(rc = errno));
630 } else if (rc == 0) {
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",
640 if (!thread) { /* parent process */
641 int live_threads = threads;
643 while (live_threads > 0) {
647 ret = waitpid(0, &status, verbose < 0 ? WNOHANG : 0);
658 fprintf(stderr, "error: %s: wait - %s\n",
659 argv[0], strerror(errno));
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).
669 int err = WEXITSTATUS(status);
670 if (err || WIFSIGNALED(status))
672 "%s: PID %d had rc=%d\n",
685 int jt_obd_detach(int argc, char **argv)
687 struct obd_ioctl_data data;
695 IOC_PACK(argv[0], data);
696 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DETACH, buf);
698 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
699 strerror(rc = errno));
704 int jt_obd_cleanup(int argc, char **argv)
706 struct obd_ioctl_data data;
712 if (argc != 1 && argc != 2)
716 if (strcmp(argv[1], "force"))
718 data.ioc_inllen1 = 1;
719 data.ioc_inlbuf1 = &force;
722 IOC_PACK(argv[0], data);
723 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEANUP, buf);
725 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
726 strerror(rc = errno));
731 int jt_obd_no_transno(int argc, char **argv)
733 struct obd_ioctl_data data;
741 IOC_PACK(argv[0], data);
742 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf);
744 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
745 strerror(rc = errno));
750 int jt_obd_set_readonly(int argc, char **argv)
752 struct obd_ioctl_data data;
760 IOC_PACK(argv[0], data);
761 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf);
763 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
764 strerror(rc = errno));
769 int jt_obd_newdev(int argc, char **argv)
772 struct obd_ioctl_data data;
779 IOC_PACK(argv[0], data);
780 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NEWDEV, buf);
782 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
783 strerror(rc = errno));
785 IOC_UNPACK(argv[0], data);
786 printf("Current device set to %d\n", data.ioc_dev);
792 int jt_get_version(int argc, char **argv)
796 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
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);
808 rc = l_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf);
810 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
811 strerror(rc = errno));
813 printf("Lustre version: %s\n", data->ioc_bulk);
816 printf("lctl version: %s\n", BUILD_VERSION);
820 int jt_obd_list(int argc, char **argv)
824 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
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);
836 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
838 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
839 strerror(rc = errno));
841 printf("%s", data->ioc_bulk);
847 int jt_obd_attach(int argc, char **argv)
849 struct obd_ioctl_data data;
854 if (argc != 2 && argc != 3 && argc != 4)
857 data.ioc_inllen1 = strlen(argv[1]) + 1;
858 data.ioc_inlbuf1 = argv[1];
860 data.ioc_inllen2 = strlen(argv[2]) + 1;
861 data.ioc_inlbuf2 = argv[2];
865 data.ioc_inllen3 = strlen(argv[3]) + 1;
866 data.ioc_inlbuf3 = argv[3];
869 IOC_PACK(argv[0], data);
870 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ATTACH, buf);
872 fprintf(stderr, "error: %s: OBD_IOC_ATTACH %s\n",
873 cmdname(argv[0]), strerror(rc = errno));
874 else if (argc == 3) {
876 if (strlen(argv[2]) > 128) {
877 printf("Name too long to set environment\n");
880 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
881 rc = setenv(name, argv[1], 1);
883 printf("error setting env variable %s\n", name);
890 int jt_obd_name2dev(int argc, char **argv)
897 rc = do_name2dev(argv[0], argv[1]);
899 int dev = rc - N2D_OFF;
900 rc = do_device(argv[0], dev);
907 int jt_obd_setup(int argc, char **argv)
909 struct obd_ioctl_data data;
919 data.ioc_dev = parse_devname(argv[0], argv[1]);
920 if (data.ioc_dev < 0)
922 data.ioc_inllen1 = strlen(argv[1]) + 1;
923 data.ioc_inlbuf1 = argv[1];
926 data.ioc_inllen2 = strlen(argv[2]) + 1;
927 data.ioc_inlbuf2 = argv[2];
930 data.ioc_inllen3 = strlen(argv[3]) + 1;
931 data.ioc_inlbuf3 = argv[3];
934 IOC_PACK(argv[0], data);
935 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETUP, buf);
937 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
938 strerror(rc = errno));
943 /* Get echo client's stripe meta-data for the given object
945 int jt_obd_get_stripe (int argc, char **argv)
947 struct obd_ioctl_data data;
955 id = strtoull (argv[1], &end, 0);
957 fprintf (stderr, "Error: %s: invalid object id '%s'\n",
958 cmdname (argv[0]), argv[1]);
962 memset (&lsm_buffer, 0, sizeof (lsm_buffer));
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);
971 IOC_PACK(argv[0], data);
972 rc = l_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf);
973 IOC_UNPACK(argv[0], data);
976 fprintf (stderr, "Error: %s: rc %d(%s)\n",
977 cmdname (argv[0]), rc, strerror (errno));
981 printf ("%s\n", lsm_string (&lsm_buffer.lsm));
986 /* Set stripe meta-data for 1 or more objects. Object must be new to
987 * this echo client instance.
989 int jt_obd_set_stripe (int argc, char **argv)
991 struct obd_ioctl_data data;
997 if (argc < 2 || argc > 3)
1000 rc = parse_lsm (&lsm_buffer, argv[1]);
1002 fprintf (stderr, "error: %s: invalid object '%s'\n",
1003 cmdname (argv[0]), argv[1]);
1008 count = strtol (argv[2], &end, 0);
1010 fprintf (stderr, "error: %s: invalid count '%s'\n",
1011 cmdname (argv[0]), argv[1]);
1016 for (i = 0; i < count; i++) {
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);
1024 IOC_PACK (argv[0], data);
1025 rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
1026 IOC_UNPACK (argv[0], data);
1029 fprintf (stderr, "Error: %s: rc %d(%s)\n",
1030 cmdname (argv[0]), rc, strerror (errno));
1038 /* Clear stripe meta-data info for an object on this echo-client instance
1040 int jt_obd_unset_stripe (int argc, char **argv)
1042 struct obd_ioctl_data data;
1050 id = strtoll (argv[1], &end, 0);
1052 fprintf (stderr, "error: %s: invalid object id '%s'\n",
1053 cmdname (argv[0]), argv[1]);
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;
1062 IOC_PACK (argv[0], data);
1063 rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
1064 IOC_UNPACK (argv[0], data);
1067 fprintf (stderr, "Error: %s: rc %d(%s)\n",
1068 cmdname (argv[0]), rc, strerror (errno));
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.
1078 int jt_obd_create(int argc, char **argv)
1080 static __u64 base_id = 1;
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;
1089 if (argc < 2 || argc > 5)
1092 count = strtoull(argv[1], &end, 0);
1094 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1095 cmdname(argv[0]), argv[1]);
1100 mode = strtoul(argv[2], &end, 0);
1102 fprintf(stderr, "error: %s: invalid mode '%s'\n",
1103 cmdname(argv[0]), argv[2]);
1106 if (!(mode & S_IFMT))
1111 verbose = get_verbose(argv[0], argv[3]);
1112 if (verbose == BAD_VERBOSE)
1117 reset_lsmb (&lsm_buffer); /* will set default */
1119 rc = parse_lsm (&lsm_buffer, argv[4]);
1121 fprintf(stderr, "error: %s: invalid lsm '%s'\n",
1122 cmdname(argv[0]), argv[4]);
1125 base_id = lsm_buffer.lsm.lsm_object_id;
1128 printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
1129 gettimeofday(&next_time, NULL);
1130 next_time.tv_sec -= verbose;
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;
1140 data.ioc_plen1 = sizeof (lsm_buffer);
1141 data.ioc_pbuf1 = (char *)&lsm_buffer;
1143 IOC_PACK(argv[0], data);
1144 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf);
1145 IOC_UNPACK(argv[0], data);
1148 fprintf(stderr, "error: %s: #%d - %s\n",
1149 cmdname(argv[0]), i, strerror(rc = errno));
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);
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);
1166 int jt_obd_setattr(int argc, char **argv)
1168 struct obd_ioctl_data data;
1176 data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1178 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1179 cmdname(argv[0]), argv[1]);
1182 data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0);
1184 fprintf(stderr, "error: %s: invalid mode '%s'\n",
1185 cmdname(argv[0]), argv[2]);
1188 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
1190 IOC_PACK(argv[0], data);
1191 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf);
1193 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1194 strerror(rc = errno));
1199 int jt_obd_destroy(int argc, char **argv)
1201 struct obd_ioctl_data data;
1202 struct timeval next_time;
1203 __u64 count = 1, next_count;
1210 if (argc < 2 || argc > 4)
1213 id = strtoull(argv[1], &end, 0);
1215 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1216 cmdname(argv[0]), argv[1]);
1220 count = strtoull(argv[2], &end, 0);
1223 "error: %s: invalid iteration count '%s'\n",
1224 cmdname(argv[0]), argv[2]);
1230 verbose = get_verbose(argv[0], argv[3]);
1231 if (verbose == BAD_VERBOSE)
1235 printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
1236 gettimeofday(&next_time, NULL);
1237 next_time.tv_sec -= verbose;
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;
1244 IOC_PACK(argv[0], data);
1245 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf);
1246 IOC_UNPACK(argv[0], data);
1249 fprintf(stderr, "error: %s: objid "LPX64": %s\n",
1250 cmdname(argv[0]), id, strerror(rc = errno));
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);
1262 int jt_obd_getattr(int argc, char **argv)
1264 struct obd_ioctl_data data;
1272 data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
1274 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1275 cmdname(argv[0]), argv[1]);
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);
1283 IOC_PACK(argv[0], data);
1284 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf);
1285 IOC_UNPACK(argv[0], data);
1287 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1288 strerror(rc = errno));
1290 printf("%s: object id "LPX64", mode %o\n", cmdname(argv[0]),
1291 data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
1296 int jt_obd_test_getattr(int argc, char **argv)
1298 struct obd_ioctl_data data;
1299 struct timeval start, next_time;
1300 __u64 i, count, next_count;
1306 if (argc < 2 && argc > 4)
1310 count = strtoull(argv[1], &end, 0);
1312 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
1313 cmdname(argv[0]), argv[1]);
1318 verbose = get_verbose(argv[0], argv[2]);
1319 if (verbose == BAD_VERBOSE)
1324 if (argv[3][0] == 't') {
1325 objid = strtoull(argv[3] + 1, &end, 0);
1327 objid += thread - 1;
1329 objid = strtoull(argv[3], &end, 0);
1331 fprintf(stderr, "error: %s: invalid objid '%s'\n",
1332 cmdname(argv[0]), argv[3]);
1337 gettimeofday(&start, NULL);
1338 next_time.tv_sec = start.tv_sec - verbose;
1339 next_time.tv_usec = start.tv_usec;
1341 printf("%s: getting "LPD64" attrs (objid "LPX64"): %s",
1342 cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
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);
1352 fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n",
1353 cmdname(argv[0]), i, errno, strerror(rc = errno));
1357 (verbose, &next_time, i, &next_count, count))
1358 printf("%s: got attr #"LPD64"\n",
1359 cmdname(argv[0]), i);
1367 gettimeofday(&end, NULL);
1369 diff = difftime(&end, &start);
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));
1380 int jt_obd_test_brw(int argc, char **argv)
1382 struct obd_ioctl_data data;
1383 struct timeval start, next_time;
1385 __u64 count, next_count;
1387 int verbose = 1, write = 0, rw;
1394 if (argc < 2 || argc > 6) {
1395 fprintf(stderr, "error: %s: bad number of arguments: %d\n",
1396 cmdname(argv[0]), argc);
1400 /* make each thread write to a different offset */
1401 if (argv[1][0] == 't') {
1402 count = strtoull(argv[1] + 1, &end, 0);
1404 thr_offset = thread - 1;
1406 count = strtoull(argv[1], &end, 0);
1409 fprintf(stderr, "error: %s: bad iteration count '%s'\n",
1410 cmdname(argv[0]), argv[1]);
1415 if (argv[2][0] == 'w' || argv[2][0] == '1')
1417 else if (argv[2][0] == 'r' || argv[2][0] == '0')
1422 verbose = get_verbose(argv[0], argv[3]);
1423 if (verbose == BAD_VERBOSE)
1428 pages = strtoul(argv[4], &end, 0);
1430 fprintf(stderr, "error: %s: bad page count '%s'\n",
1431 cmdname(argv[0]), argv[4]);
1436 if (argv[5][0] == 't') {
1437 objid = strtoull(argv[5] + 1, &end, 0);
1439 objid += thread - 1;
1441 objid = strtoull(argv[5], &end, 0);
1443 fprintf(stderr, "error: %s: bad objid '%s'\n",
1444 cmdname(argv[0]), argv[5]);
1449 len = pages * PAGE_SIZE;
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;
1458 gettimeofday(&start, NULL);
1459 next_time.tv_sec = start.tv_sec - verbose;
1460 next_time.tv_usec = start.tv_usec;
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));
1467 IOC_PACK(argv[0], data);
1468 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_OPEN, buf);
1469 IOC_UNPACK(argv[0], data);
1471 fprintf(stderr, "error: brw_open: %s\n", strerror(rc = errno));
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);
1480 fprintf(stderr, "error: %s: #%d - %s on %s\n",
1481 cmdname(argv[0]), i, strerror(rc = errno),
1482 write ? "write" : "read");
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);
1488 data.ioc_offset += len;
1495 gettimeofday(&end, NULL);
1497 diff = difftime(&end, &start);
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));
1506 rw = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE, buf);
1508 fprintf(stderr, "error: brw_close: %s\n", strerror(rw = errno));
1516 int jt_obd_lov_setconfig(int argc, char **argv)
1518 struct obd_ioctl_data data;
1519 struct lov_desc desc;
1520 struct obd_uuid *uuidarray, *ptr;
1529 if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
1531 "error: %s: LOV uuid '%s' longer than "LPSZ" chars\n",
1532 cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
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);
1541 fprintf(stderr, "error: %s: bad default stripe count '%s'\n",
1542 cmdname(argv[0]), argv[2]);
1545 if (desc.ld_default_stripe_count > desc.ld_tgt_count) {
1547 "error: %s: default stripe count %u > OST count %u\n",
1548 cmdname(argv[0]), desc.ld_default_stripe_count,
1553 desc.ld_default_stripe_size = strtoull(argv[3], &end, 0);
1555 fprintf(stderr, "error: %s: bad default stripe size '%s'\n",
1556 cmdname(argv[0]), argv[3]);
1559 if (desc.ld_default_stripe_size < 4096) {
1561 "error: %s: default stripe size "LPU64" too small\n",
1562 cmdname(argv[0]), desc.ld_default_stripe_size);
1564 } else if ((long)desc.ld_default_stripe_size <
1565 desc.ld_default_stripe_size) {
1567 "error: %s: default stripe size "LPU64" too large\n",
1568 cmdname(argv[0]), desc.ld_default_stripe_size);
1571 desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0);
1573 fprintf(stderr, "error: %s: bad default stripe offset '%s'\n",
1574 cmdname(argv[0]), argv[4]);
1577 desc.ld_pattern = strtoul(argv[5], &end, 0);
1579 fprintf(stderr, "error: %s: bad stripe pattern '%s'\n",
1580 cmdname(argv[0]), argv[5]);
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.
1590 uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
1592 fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
1593 cmdname(argv[0]), desc.ld_tgt_count);
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]);
1604 strcpy((char *)ptr, argv[i]);
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;
1612 if (obd_ioctl_pack(&data, &buf, max)) {
1613 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1617 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LOV_SET_CONFIG, buf);
1619 fprintf(stderr, "error: %s: ioctl error: %s\n",
1620 cmdname(argv[0]), strerror(rc = errno));
1626 #define DEF_UUID_ARRAY_LEN (8192 / 40)
1628 int jt_obd_lov_getconfig(int argc, char **argv)
1630 struct obd_ioctl_data data;
1631 struct lov_desc desc;
1632 struct obd_uuid *uuidarray;
1642 fd = open(path, O_RDONLY);
1644 fprintf(stderr, "open \"%s\" failed: %s\n", path,
1649 memset(&desc, 0, sizeof(desc));
1650 obd_str2uuid(&desc.ld_uuid, argv[1]);
1651 desc.ld_tgt_count = DEF_UUID_ARRAY_LEN;
1653 uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
1655 fprintf(stderr, "error: %s: no memory for %d uuid's\n",
1656 cmdname(argv[0]), desc.ld_tgt_count);
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;
1666 if (obd_ioctl_pack(&data, &buf, max)) {
1667 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
1671 rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
1672 if (rc == -ENOSPC) {
1676 fprintf(stderr, "error: %s: ioctl error: %s\n",
1677 cmdname(argv[0]), strerror(rc = errno));
1679 struct obd_uuid *ptr;
1682 if (obd_ioctl_unpack(&data, buf, max)) {
1683 fprintf(stderr, "error: %s: invalid reply\n",
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);
1705 int jt_obd_test_ldlm(int argc, char **argv)
1707 struct obd_ioctl_data data;
1714 IOC_PACK(argv[0], data);
1715 rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf);
1717 fprintf(stderr, "error: %s: test failed: %s\n",
1718 cmdname(argv[0]), strerror(rc = errno));
1722 int jt_obd_dump_ldlm(int argc, char **argv)
1724 struct obd_ioctl_data data;
1731 IOC_PACK(argv[0], data);
1732 rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf);
1734 fprintf(stderr, "error: %s failed: %s\n",
1735 cmdname(argv[0]), strerror(rc = errno));
1739 int jt_obd_ldlm_regress_start(int argc, char **argv)
1742 struct obd_ioctl_data data;
1743 char argstring[200];
1744 int i, count = sizeof(argstring) - 1;
1750 argstring[0] = '\0';
1751 for (i = 1; i < argc; i++) {
1752 strncat(argstring, " ", count);
1754 strncat(argstring, argv[i], count);
1755 count -= strlen(argv[i]);
1758 if (strlen(argstring)) {
1759 data.ioc_inlbuf1 = argstring;
1760 data.ioc_inllen1 = strlen(argstring) + 1;
1763 IOC_PACK(argv[0], data);
1764 rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
1766 fprintf(stderr, "error: %s: test failed: %s\n",
1767 cmdname(argv[0]), strerror(rc = errno));
1772 int jt_obd_ldlm_regress_stop(int argc, char **argv)
1775 struct obd_ioctl_data data;
1781 IOC_PACK(argv[0], data);
1782 rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
1785 fprintf(stderr, "error: %s: test failed: %s\n",
1786 cmdname(argv[0]), strerror(rc = errno));
1790 int jt_obd_lov_set_osc_active(int argc, char **argv)
1792 struct obd_ioctl_data data;
1799 data.ioc_inlbuf1 = argv[1];
1800 data.ioc_inllen1 = strlen(argv[1]) + 1;
1802 /* reuse offset for 'active' */
1803 data.ioc_offset = atoi(argv[2]);
1805 IOC_PACK(argv[0], data);
1806 rc = l_ioctl(OBD_DEV_ID, IOC_LOV_SET_OSC_ACTIVE, buf);
1808 fprintf(stderr, "error: %s: failed: %s\n",
1809 cmdname(argv[0]), strerror(rc = errno));
1814 int jt_obd_newconn(int argc, char **argv)
1817 struct obd_ioctl_data data;
1820 if (argc < 2 || argc > 3)
1823 data.ioc_inllen1 = strlen(argv[1]) + 1;
1824 data.ioc_inlbuf1 = argv[1];
1827 data.ioc_inllen2 = strlen(argv[2]) + 1;
1828 data.ioc_inlbuf2 = argv[2];
1831 IOC_PACK(argv[0], data);
1832 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECOVD_NEWCONN, buf);
1834 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1835 strerror(rc = errno));
1840 int jt_obd_failconn(int argc, char **argv)
1843 struct obd_ioctl_data data;
1849 data.ioc_inllen1 = strlen(argv[1]) + 1;
1850 data.ioc_inlbuf1 = argv[1];
1852 IOC_PACK(argv[0], data);
1853 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECOVD_FAILCONN, buf);
1855 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
1856 strerror(rc = errno));
1861 int jt_obd_mdc_lookup(int argc, char **argv)
1863 struct obd_ioctl_data data;
1864 char *parent, *child;
1865 int rc, fd, verbose = 1;
1867 if (argc < 3 || argc > 4)
1873 verbose = get_verbose(argv[0], argv[3]);
1877 data.ioc_inllen1 = strlen(child) + 1;
1878 data.ioc_inlbuf1 = child;
1880 IOC_PACK(argv[0], data);
1882 fd = open(parent, O_RDONLY);
1884 fprintf(stderr, "open \"%s\" failed: %s\n", parent,
1889 rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
1891 fprintf(stderr, "error: %s: ioctl error: %s\n",
1892 cmdname(argv[0]), strerror(rc = errno));
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);
1907 int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal)
1911 struct obd_ioctl_data data;
1915 data.ioc_inllen1 = strlen(uuid) + 1;
1916 data.ioc_inlbuf1 = uuid;
1919 IOC_PACK(func, data);
1920 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ADD_UUID, buf);
1922 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
1927 printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid));
1931 int jt_obd_add_uuid(int argc, char **argv)
1940 if (ptl_parse_nid (&nid, argv[2]) != 0) {
1941 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
1945 nal = ptl_name2nal(argv[3]);
1948 fprintf (stderr, "Can't parse NAL %s\n", argv[3]);
1952 return do_add_uuid(argv[0], argv[1], nid, nal);
1955 int jt_obd_close_uuid(int argc, char **argv)
1958 struct obd_ioctl_data data;
1961 fprintf(stderr, "usage: %s <uuid> <net-type>\n", argv[0]);
1965 nal = ptl_name2nal(argv[2]);
1968 fprintf (stderr, "Can't parse NAL %s\n", argv[2]);
1973 data.ioc_inllen1 = strlen(argv[1]) + 1;
1974 data.ioc_inlbuf1 = argv[1];
1977 IOC_PACK(argv[0], data);
1978 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf);
1980 fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n",
1988 int jt_obd_del_uuid(int argc, char **argv)
1991 struct obd_ioctl_data data;
1994 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
2000 if (strcmp (argv[1], "_all_"))
2002 data.ioc_inllen1 = strlen(argv[1]) + 1;
2003 data.ioc_inlbuf1 = argv[1];
2006 IOC_PACK(argv[0], data);
2007 rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DEL_UUID, buf);
2009 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
2016 static void signal_server(int sig)
2018 if (sig == SIGINT) {
2019 do_disconnect("sigint", 1);
2022 fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig);
2025 int obd_initialize(int argc, char **argv)
2028 register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH);
2034 void obd_cleanup(int argc, char **argv)
2036 struct sigaction sigact;
2038 sigact.sa_handler = signal_server;
2039 sigfillset(&sigact.sa_mask);
2040 sigact.sa_flags = SA_RESTART;
2041 sigaction(SIGINT, &sigact, NULL);
2043 do_disconnect(argv[0], 1);