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_stripe_count = strtoul(argv[2], NULL, 0);
516 desc.ld_default_stripe_size = (__u64) strtoul(argv[3], NULL, 0);
517 desc.ld_default_stripe_offset = (__u64) strtoul(argv[3], NULL, 0);
518 desc.ld_pattern = strtoul(argv[5], NULL, 0);
519 desc.ld_tgt_count = argc - 6;
522 size = sizeof(uuid_t) * desc.ld_tgt_count;
523 uuidarray = malloc(size);
525 fprintf(stderr, "lov_config: no %dB memory for uuid's\n",
529 memset(uuidarray, 0, size);
530 for (i=6 ; i < argc ; i++) {
531 char *buf = (char *) (uuidarray + i -6 );
532 if (strlen(argv[i]) >= sizeof(uuid_t)) {
533 fprintf(stderr, "lov_config: arg %d (%s) too long\n",
538 strcpy(buf, argv[i]);
541 data.ioc_inllen1 = sizeof(desc);
542 data.ioc_inlbuf1 = (char *)&desc;
543 data.ioc_inllen2 = size;
544 data.ioc_inlbuf2 = (char *)uuidarray;
546 if (obd_ioctl_pack(&data, &buf, max)) {
547 fprintf(stderr, "error: %s: invalid ioctl\n",cmdname(argv[0]));
551 rc = ioctl(fd, OBD_IOC_LOV_CONFIG , buf);
553 fprintf(stderr, "lov_config: error: %s: %s\n",
554 cmdname(argv[0]),strerror(rc = errno));
560 int jt_dev_create(int argc, char **argv) {
561 struct obd_ioctl_data data;
562 struct timeval next_time;
563 int count = 1, next_count;
568 if (argc < 2 || argc > 4)
571 count = strtoul(argv[1], NULL, 0);
574 data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
576 data.ioc_obdo1.o_mode = 0100644;
577 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
579 verbose = get_verbose(argv[3]);
581 printf("%s: %d obdos\n", cmdname(argv[0]), count);
582 gettimeofday(&next_time, NULL);
583 next_time.tv_sec -= verbose;
585 for (i = 1, next_count = verbose; i <= count ; i++) {
586 rc = ioctl(fd, OBD_IOC_CREATE , &data);
588 fprintf(stderr, "error: %s: #%d - %s\n",
589 cmdname(argv[0]), i, strerror(rc = errno));
592 if (be_verbose(verbose, &next_time, i, &next_count, count))
593 printf("%s: #%d is object id %Ld\n", cmdname(argv[0]),
594 i, data.ioc_obdo1.o_id);
599 int jt_dev_destroy(int argc, char **argv) {
600 struct obd_ioctl_data data;
604 fprintf(stderr, "usage: %s id\n", cmdname(argv[0]));
608 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
609 data.ioc_obdo1.o_mode = S_IFREG|0644;
611 rc = ioctl(fd, OBD_IOC_DESTROY , &data);
613 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
614 strerror(rc = errno));
620 /* Device configuration commands */
621 int jt_dev_setattr(int argc, char **argv)
624 struct obd_ioctl_data data;
630 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
631 data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], NULL, 0);
632 data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
634 rc = ioctl(fd, OBD_IOC_SETATTR , &data);
636 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
637 strerror(rc = errno));
642 int jt_dev_getattr(int argc, char **argv)
645 struct obd_ioctl_data data;
651 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
652 /* to help obd filter */
653 data.ioc_obdo1.o_mode = 0100644;
654 data.ioc_obdo1.o_valid = 0xffffffff;
655 printf("%s: object id %Ld\n", cmdname(argv[0]), data.ioc_obdo1.o_id);
657 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
659 fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
662 printf("%s: object id %Ld, mode %o\n", cmdname(argv[0]),
663 data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
668 int jt_dev_test_getattr(int argc, char **argv)
671 struct obd_ioctl_data data;
672 struct timeval start, next_time;
673 int i, count, next_count;
676 if (argc != 2 && argc != 3)
680 count = strtoul(argv[1], NULL, 0);
683 verbose = get_verbose(argv[2]);
687 data.ioc_obdo1.o_valid = 0xffffffff;
688 data.ioc_obdo1.o_id = 2;
689 gettimeofday(&start, NULL);
690 next_time.tv_sec = start.tv_sec - verbose;
691 next_time.tv_usec = start.tv_usec;
692 printf("%s: getting %d attrs (testing only): %s", cmdname(argv[0]),
693 count, ctime(&start.tv_sec));
695 for (i = 1, next_count = verbose; i <= count; i++) {
696 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
698 fprintf(stderr, "error: %s: #%d - %s\n",
699 cmdname(argv[0]), i, strerror(rc = errno));
702 if (be_verbose(verbose, &next_time, i,&next_count,count))
703 printf("%s: got attr #%d\n", cmdname(argv[0]), i);
711 gettimeofday(&end, NULL);
713 diff = difftime(&end, &start);
716 printf("%s: %d attrs in %.4gs (%.4g attr/s): %s",
717 cmdname(argv[0]), i, diff, (double)i / diff,
723 int jt_dev_test_brw(int argc, char **argv)
726 struct obd_ioctl_data data;
727 struct timeval start, next_time;
729 int pages = 1, obdos = 1, count, next_count;
730 int verbose = 1, write = 0, rw;
734 if (argc < 2 || argc > 6)
737 count = strtoul(argv[1], NULL, 0);
740 if (argv[2][0] == 'w' || argv[2][0] == '1')
742 else if (argv[2][0] == 'r' || argv[2][0] == '0')
745 verbose = get_verbose(argv[3]);
749 pages = strtoul(argv[4], NULL, 0);
751 obdos = strtoul(argv[5], NULL, 0);
753 if (obdos != 1 && obdos != 2) {
754 fprintf(stderr, "error: %s: only 1 or 2 obdos supported\n",
759 len = pages * PAGE_SIZE;
761 bulk = calloc(obdos, len);
763 fprintf(stderr,"error: %s: no memory allocating %dx%d pages\n",
764 cmdname(argv[0]), obdos, pages);
768 data.ioc_obdo1.o_id = 2;
769 data.ioc_count = len;
771 data.ioc_plen1 = len;
772 data.ioc_pbuf1 = bulk;
774 data.ioc_obdo2.o_id = 3;
775 data.ioc_plen2 = len;
776 data.ioc_pbuf2 = bulk + len;
779 gettimeofday(&start, NULL);
780 next_time.tv_sec = start.tv_sec - verbose;
781 next_time.tv_usec = start.tv_usec;
783 printf("%s: %s %d (%dx%d pages) (testing only): %s",
784 cmdname(argv[0]), write ? "writing" : "reading",
785 count, obdos, pages, ctime(&start.tv_sec));
788 * We will put in the start time (and loop count inside the loop)
789 * at the beginning of each page so that we will be able to validate
790 * (at some later time) whether the data actually made it or not.
792 * XXX we do not currently use any of this memory in OBD_IOC_BRW_*
793 * just to avoid the overhead of the copy_{to,from}_user. It
794 * can be fixed if we ever need to send real data around.
796 for (o = 0, b = bulk; o < obdos; o++)
797 for (p = 0; p < pages; p++, b += PAGE_SIZE)
798 memcpy(b, &start, sizeof(start));
800 rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
801 for (i = 1, next_count = verbose; i <= count; i++) {
803 b = bulk + sizeof(struct timeval);
804 for (o = 0; o < obdos; o++)
805 for (p = 0; p < pages; p++, b += PAGE_SIZE)
806 memcpy(b, &count, sizeof(count));
809 rc = ioctl(fd, rw, &data);
811 fprintf(stderr, "error: %s: #%d - %s on %s\n",
812 cmdname(argv[0]), i, strerror(rc = errno),
813 write ? "write" : "read");
815 } else if (be_verbose(verbose,&next_time,i,&next_count,count))
816 printf("%s: %s number %d\n", cmdname(argv[0]),
817 write ? "write" : "read", i);
826 gettimeofday(&end, NULL);
828 diff = difftime(&end, &start);
831 printf("%s: %s %dx%dx%d pages in %.4gs (%.4g pg/s): %s",
832 cmdname(argv[0]), write ? "wrote" : "read", obdos,
833 pages, i, diff, (double)obdos * i * pages / diff,
839 int jt_dev_test_ldlm(int argc, char **argv)
842 struct obd_ioctl_data data;
848 rc = ioctl(fd, IOC_LDLM_TEST, &data);
850 fprintf(stderr, "error: %s: test failed: %s\n",
851 cmdname(argv[0]), strerror(rc = errno));