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: Brian Behlendorf <behlendorf1@llnl.gov>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <sys/ioctl.h>
29 #include <sys/socket.h>
30 #include <sys/types.h>
39 #include <linux/lustre_lib.h>
40 #include <linux/lustre_idl.h>
41 #include <linux/lustre_dlm.h>
47 #include <netinet/in.h>
50 #include <asm/page.h> /* needed for PAGE_SIZE - rread*/
56 #include <linux/list.h>
60 static uint64_t conn_addr = -1;
61 static uint64_t conn_cookie;
62 static char rawbuf[8192];
63 static char *buf = rawbuf;
64 static int max = 8192;
70 int device_setup(int argc, char **argv) {
74 /* Misc support functions */
75 static int do_name2dev(char *func, char *name) {
76 struct obd_ioctl_data data;
82 data.ioc_inllen1 = strlen(name) + 1;
83 data.ioc_inlbuf1 = name;
85 if (obd_ioctl_pack(&data, &buf, max)) {
86 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(func));
89 rc = ioctl(fd, OBD_IOC_NAME2DEV , buf);
91 fprintf(stderr, "error: %s: %s - %s\n", cmdname(func),
92 name, strerror(rc = errno));
96 memcpy((char *)(&data), buf, sizeof(data));
98 return data.ioc_dev + N2D_OFF;
102 * resolve a device name to a device number.
103 * supports a number or name.
104 * FIXME: support UUID
106 static int parse_devname(char * func, char *name)
113 if (name[0] == '$') {
114 rc = do_name2dev(func, name + 1);
117 printf("%s is device %d\n", name,
120 fprintf(stderr, "error: %s: %s: %s\n", cmdname(func),
121 name, "device not found");
125 ret = strtoul(name, NULL, 0);
131 /* pack "LL LL LL LL LL LL LL L L L L L L L L L a60 a60 L L L" */
132 static char * obdo_print(struct obdo *obd)
136 sprintf(buf, "id: %Ld\ngrp: %Ld\natime: %Ld\nmtime: %Ld\nctime: %Ld\n"
137 "size: %Ld\nblocks: %Ld\nblksize: %d\nmode: %o\nuid: %d\n"
138 "gid: %d\nflags: %x\nobdflags: %x\nnlink: %d,\nvalid %x\n",
158 /* Device selection commands */
159 int jt_dev_newdev(int argc, char **argv)
162 struct obd_ioctl_data data;
164 LUSTRE_CONNECT(argv[0]);
170 rc = ioctl(fd, OBD_IOC_NEWDEV , &data);
172 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
175 printf("Current device set to %d\n", data.ioc_dev);
181 static int do_device(char *func, int dev) {
182 struct obd_ioctl_data data;
184 memset(&data, 0, sizeof(data));
186 LUSTRE_CONNECT(func);
188 if (obd_ioctl_pack(&data, &buf, max)) {
189 CERROR("error: %s: invalid ioctl\n", cmdname(func));
193 return ioctl(fd, OBD_IOC_DEVICE , buf);
196 int jt_dev_device(int argc, char **argv)
199 do_disconnect(argv[0], 1);
203 dev = parse_devname(argv[0], argv[1]);
207 rc = do_device(argv[0], dev);
209 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
210 strerror(rc = errno));
215 static int do_uuid2dev(char *func, char *name) {
219 int jt_dev_uuid2dev(int argc, char **argv)
221 do_uuid2dev(NULL, NULL);
225 int jt_dev_name2dev(int argc, char **argv)
231 rc = do_name2dev(argv[0], argv[1]);
233 int dev = rc - N2D_OFF;
234 rc = do_device(argv[0], dev);
241 int jt_dev_list(int argc, char **argv)
245 struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
247 LUSTRE_CONNECT(argv[0]);
248 memset(buf, 0, sizeof(buf));
249 data->ioc_version = OBD_IOCTL_VERSION;
250 data->ioc_addr = conn_addr;
251 data->ioc_cookie = conn_addr;
252 data->ioc_len = sizeof(buf);
253 data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
258 rc = ioctl(fd, OBD_IOC_LIST , data);
260 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
263 printf("%s", data->ioc_bulk);
269 /* Device configuration commands */
270 int do_disconnect(char *func, int verbose)
273 struct obd_ioctl_data data;
280 rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
282 fprintf(stderr, "error: %s: %x %s\n", cmdname(func),
283 OBD_IOC_DISCONNECT, strerror(errno));
286 printf("%s: disconnected conn %Lx\n", cmdname(func),
295 static int jt_dev_newconn(int argc, char **argv)
298 struct obd_ioctl_data data;
302 fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
306 rc = ioctl(fd, OBD_IOC_RECOVD_NEWCONN , &data);
308 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
309 strerror(rc = errno));
315 int jt_dev_probe(int argc, char **argv)
318 struct obd_ioctl_data data;
321 do_disconnect(argv[0], 1);
326 rc = ioctl(fd, OBD_IOC_CONNECT , &data);
328 fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
329 OBD_IOC_CONNECT, strerror(rc = errno));
331 conn_addr = data.ioc_addr;
332 conn_cookie = data.ioc_cookie;
336 int jt_dev_close(int argc, char **argv)
344 return do_disconnect(argv[0], 0);
347 int jt_opt_device(int argc, char **argv)
354 fprintf(stderr, "usage: %s devno <command [args ...]>\n",
359 rc = do_device("device", parse_devname(argv[0], argv[1]));
364 rc = jt_dev_probe(1, arg2);
368 rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
369 ret = do_disconnect(argv[0], 0);
377 int jt_dev_attach(int argc, char **argv)
380 struct obd_ioctl_data data;
383 if (argc != 2 && argc != 3 && argc != 4)
386 data.ioc_inllen1 = strlen(argv[1]) + 1;
387 data.ioc_inlbuf1 = argv[1];
389 data.ioc_inllen2 = strlen(argv[2]) + 1;
390 data.ioc_inlbuf2 = argv[2];
394 data.ioc_inllen3 = strlen(argv[3]) + 1;
395 data.ioc_inlbuf3 = argv[3];
398 if (obd_ioctl_pack(&data, &buf, max)) {
399 fprintf(stderr, "error: %s: invalid ioctl\n",cmdname(argv[0]));
403 rc = ioctl(fd, OBD_IOC_ATTACH , buf);
405 fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
406 OBD_IOC_ATTACH, strerror(rc = errno));
407 else if (argc == 3) {
409 if (strlen(argv[2]) > 128) {
410 printf("Name too long to set environment\n");
413 snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
414 rc = setenv(name, argv[1], 1);
416 printf("error setting env variable %s\n", name);
423 int jt_dev_setup(int argc, char **argv)
426 struct obd_ioctl_data data;
434 data.ioc_dev = parse_devname(argv[0], argv[1]);
435 if (data.ioc_dev < 0)
438 data.ioc_inllen1 = strlen(argv[1]) + 1;
439 data.ioc_inlbuf1 = argv[1];
442 data.ioc_inllen2 = strlen(argv[2]) + 1;
443 data.ioc_inlbuf2 = argv[2];
446 if (obd_ioctl_pack(&data, &buf, max)) {
447 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
450 rc = ioctl(fd, OBD_IOC_SETUP , buf);
452 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
453 strerror(rc = errno));
458 int jt_dev_detach(int argc, char **argv)
461 struct obd_ioctl_data data;
467 if (obd_ioctl_pack(&data, &buf, max)) {
468 fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
472 rc = ioctl(fd, OBD_IOC_DETACH , buf);
474 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
480 int jt_dev_cleanup(int argc, char **argv)
483 struct obd_ioctl_data data;
489 rc = ioctl(fd, OBD_IOC_CLEANUP , &data);
491 CERROR("error: %s: %s\n", cmdname(argv[0]),
496 int jt_dev_lov_config(int argc, char **argv)
498 struct obd_ioctl_data data;
499 struct lov_desc desc;
507 if (strlen(argv[1]) > sizeof(uuid_t) - 1) {
508 fprintf(stderr, "lov_config: no %dB memory for uuid's\n",
513 memset(&desc, 0, sizeof(desc));
514 strcpy(desc.ld_uuid, argv[1]);
515 desc.ld_default_stripecount = strtoul(argv[2], NULL, 0);
516 desc.ld_default_stripesize = strtoul(argv[3], NULL, 0);
517 desc.ld_pattern = strtoul(argv[4], NULL, 0);
518 desc.ld_tgt_count = argc - 5;
521 size = sizeof(uuid_t) * desc.ld_tgt_count;
522 uuidarray = malloc(size);
524 fprintf(stderr, "lov_config: no %dB memory for uuid's\n",
528 memset(uuidarray, 0, size);
529 for (i=5 ; i < argc ; i++) {
530 char *buf = (char *) (uuidarray + i -5 );
531 if (strlen(argv[i]) >= sizeof(uuid_t)) {
532 fprintf(stderr, "lov_config: arg %d (%s) too long\n",
537 strcpy(buf, argv[i]);
540 data.ioc_inllen1 = sizeof(desc);
541 data.ioc_inlbuf1 = (char *)&desc;
542 data.ioc_inllen2 = size;
543 data.ioc_inlbuf2 = (char *)uuidarray;
545 if (obd_ioctl_pack(&data, &buf, max)) {
546 fprintf(stderr, "error: %s: invalid ioctl\n",cmdname(argv[0]));
550 rc = ioctl(fd, OBD_IOC_LOV_CONFIG , buf);
552 fprintf(stderr, "lov_config: error: %s: %s\n",
553 cmdname(argv[0]),strerror(rc = errno));
559 int jt_dev_create(int argc, char **argv) {
560 struct obd_ioctl_data data;
561 struct timeval next_time;
562 int count = 1, next_count;
567 if (argc < 2 || argc > 4)
570 count = strtoul(argv[1], NULL, 0);
573 data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
575 data.ioc_obdo1.o_mode = 0100644;
576 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
578 verbose = get_verbose(argv[3]);
580 printf("%s: %d obdos\n", cmdname(argv[0]), count);
581 gettimeofday(&next_time, NULL);
582 next_time.tv_sec -= verbose;
584 for (i = 1, next_count = verbose; i <= count ; i++) {
585 rc = ioctl(fd, OBD_IOC_CREATE , &data);
587 fprintf(stderr, "error: %s: #%d - %s\n",
588 cmdname(argv[0]), i, strerror(rc = errno));
591 if (be_verbose(verbose, &next_time, i, &next_count, count))
592 printf("%s: #%d is object id %Ld\n", cmdname(argv[0]),
593 i, data.ioc_obdo1.o_id);
598 int jt_dev_destroy(int argc, char **argv) {
599 struct obd_ioctl_data data;
603 fprintf(stderr, "usage: %s id\n", cmdname(argv[0]));
607 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
608 data.ioc_obdo1.o_mode = S_IFREG|0644;
610 rc = ioctl(fd, OBD_IOC_DESTROY , &data);
612 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
613 strerror(rc = errno));
619 /* Device configuration commands */
620 int jt_dev_setattr(int argc, char **argv)
623 struct obd_ioctl_data data;
629 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
630 data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], NULL, 0);
631 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
633 rc = ioctl(fd, OBD_IOC_SETATTR , &data);
635 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
636 strerror(rc = errno));
641 int jt_dev_getattr(int argc, char **argv)
644 struct obd_ioctl_data data;
650 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
651 /* to help obd filter */
652 data.ioc_obdo1.o_mode = 0100644;
653 data.ioc_obdo1.o_valid = 0xffffffff;
654 printf("%s: object id %Ld\n", cmdname(argv[0]), data.ioc_obdo1.o_id);
656 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
658 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
661 printf("%s: object id %Ld, mode %o\n", cmdname(argv[0]),
662 data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
667 int jt_dev_test_getattr(int argc, char **argv)
670 struct obd_ioctl_data data;
671 struct timeval start, next_time;
672 int i, count, next_count;
675 if (argc != 2 && argc != 3)
679 count = strtoul(argv[1], NULL, 0);
682 verbose = get_verbose(argv[2]);
686 data.ioc_obdo1.o_valid = 0xffffffff;
687 data.ioc_obdo1.o_id = 2;
688 gettimeofday(&start, NULL);
689 next_time.tv_sec = start.tv_sec - verbose;
690 next_time.tv_usec = start.tv_usec;
691 printf("%s: getting %d attrs (testing only): %s", cmdname(argv[0]),
692 count, ctime(&start.tv_sec));
694 for (i = 1, next_count = verbose; i <= count; i++) {
695 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
697 fprintf(stderr, "error: %s: #%d - %s\n",
698 cmdname(argv[0]), i, strerror(rc = errno));
701 if (be_verbose(verbose, &next_time, i,&next_count,count))
702 printf("%s: got attr #%d\n", cmdname(argv[0]), i);
710 gettimeofday(&end, NULL);
712 diff = difftime(&end, &start);
715 printf("%s: %d attrs in %.4gs (%.4g attr/s): %s",
716 cmdname(argv[0]), i, diff, (double)i / diff,
722 int jt_dev_test_brw(int argc, char **argv)
725 struct obd_ioctl_data data;
726 struct timeval start, next_time;
728 int pages = 1, obdos = 1, count, next_count;
729 int verbose = 1, write = 0, rw;
733 if (argc < 2 || argc > 6)
736 count = strtoul(argv[1], NULL, 0);
739 if (argv[2][0] == 'w' || argv[2][0] == '1')
741 else if (argv[2][0] == 'r' || argv[2][0] == '0')
744 verbose = get_verbose(argv[3]);
748 pages = strtoul(argv[4], NULL, 0);
750 obdos = strtoul(argv[5], NULL, 0);
752 if (obdos != 1 && obdos != 2) {
753 fprintf(stderr, "error: %s: only 1 or 2 obdos supported\n",
758 len = pages * PAGE_SIZE;
760 bulk = calloc(obdos, len);
762 fprintf(stderr,"error: %s: no memory allocating %dx%d pages\n",
763 cmdname(argv[0]), obdos, pages);
767 data.ioc_obdo1.o_id = 2;
768 data.ioc_count = len;
770 data.ioc_plen1 = len;
771 data.ioc_pbuf1 = bulk;
773 data.ioc_obdo2.o_id = 3;
774 data.ioc_plen2 = len;
775 data.ioc_pbuf2 = bulk + len;
778 gettimeofday(&start, NULL);
779 next_time.tv_sec = start.tv_sec - verbose;
780 next_time.tv_usec = start.tv_usec;
782 printf("%s: %s %d (%dx%d pages) (testing only): %s",
783 cmdname(argv[0]), write ? "writing" : "reading",
784 count, obdos, pages, ctime(&start.tv_sec));
787 * We will put in the start time (and loop count inside the loop)
788 * at the beginning of each page so that we will be able to validate
789 * (at some later time) whether the data actually made it or not.
791 * XXX we do not currently use any of this memory in OBD_IOC_BRW_*
792 * just to avoid the overhead of the copy_{to,from}_user. It
793 * can be fixed if we ever need to send real data around.
795 for (o = 0, b = bulk; o < obdos; o++)
796 for (p = 0; p < pages; p++, b += PAGE_SIZE)
797 memcpy(b, &start, sizeof(start));
799 rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
800 for (i = 1, next_count = verbose; i <= count; i++) {
802 b = bulk + sizeof(struct timeval);
803 for (o = 0; o < obdos; o++)
804 for (p = 0; p < pages; p++, b += PAGE_SIZE)
805 memcpy(b, &count, sizeof(count));
808 rc = ioctl(fd, rw, &data);
810 fprintf(stderr, "error: %s: #%d - %s on %s\n",
811 cmdname(argv[0]), i, strerror(rc = errno),
812 write ? "write" : "read");
814 } else if (be_verbose(verbose,&next_time,i,&next_count,count))
815 printf("%s: %s number %d\n", cmdname(argv[0]),
816 write ? "write" : "read", i);
825 gettimeofday(&end, NULL);
827 diff = difftime(&end, &start);
830 printf("%s: %s %dx%dx%d pages in %.4gs (%.4g pg/s): %s",
831 cmdname(argv[0]), write ? "wrote" : "read", obdos,
832 pages, i, diff, (double)obdos * i * pages / diff,
838 int jt_dev_test_ldlm(int argc, char **argv)
841 struct obd_ioctl_data data;
847 rc = ioctl(fd, IOC_LDLM_TEST, &data);
849 fprintf(stderr, "error: %s: test failed: %s\n",
850 cmdname(argv[0]), strerror(rc = errno));