-#include <stdio.h>
-
-int fd = -1;
-int connid = -1;
-char rawbuf[8192];
-char *buf = rawbuf;
-int max = 8192;
-int thread;
-
-#define IOCINIT(data) \
-do { \
- memset(&data, 0, sizeof(data)); \
- data.ioc_version = OBD_IOCTL_VERSION; \
- data.ioc_conn1 = connid; \
- data.ioc_len = sizeof(data); \
- if (fd < 0) { \
- fprintf(stderr, "No device open, use device\n"); \
- return 1; \
- } \
-} while (0)
-
-/*
- pack "LL LL LL LL LL LL LL L L L L L L L L L a60 a60 L L L",
- $obdo->{id}, 0,
- $obdo->{gr}, 0,
- $obdo->{atime}, 0,
- $obdo->{mtime}, 0 ,
- $obdo->{ctime}, 0,
- $obdo->{size}, 0,
- $obdo->{blocks}, 0,
- $obdo->{blksize},
- $obdo->{mode},
- $obdo->{uid},
- $obdo->{gid},
- $obdo->{flags},
- $obdo->{obdflags},
- $obdo->{nlink},
- $obdo->{generation},
- $obdo->{valid},
- $obdo->{inline},
- $obdo->{obdmd},
- 0, 0, # struct list_head
- 0; # struct obd_ops
-}
-
-*/
-
-char * obdo_print(struct obdo *obd)
-{
- char buf[1024];
-
- sprintf(buf, "id: %Ld\ngrp: %Ld\natime: %Ld\nmtime: %Ld\nctime: %Ld\n"
- "size: %Ld\nblocks: %Ld\nblksize: %d\nmode: %o\nuid: %d\n"
- "gid: %d\nflags: %x\nobdflags: %x\nnlink: %d,\nvalid %x\n",
- obd->o_id,
- obd->o_gr,
- obd->o_atime,
- obd->o_mtime,
- obd->o_ctime,
- obd->o_size,
- obd->o_blocks,
- obd->o_blksize,
- obd->o_mode,
- obd->o_uid,
- obd->o_gid,
- obd->o_flags,
- obd->o_obdflags,
- obd->o_nlink,
- obd->o_valid);
- return strdup(buf);
-}
-
-int getfd()
-{
- if (fd == -1)
- fd = open("/dev/obd", O_RDWR);
- if (fd == -1) {
- fprintf(stderr, "error: opening /dev/obd: %s\n",
- strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static char *cmdname(char *func)
-{
- static char buf[512];
-
- if (thread) {
- sprintf(buf, "%s-%d", func, thread);
- return buf;
- }
-
- return func;
-}
-
-#define difftime(a, b) \
- ((double)(a)->tv_sec - (b)->tv_sec + \
- ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
-
-static int be_verbose(int verbose, struct timeval *next_time,
- int num, int *next_num, int num_total)
-{
- struct timeval now;
-
- if (!verbose)
- return 0;
-
- if (next_time != NULL)
- gettimeofday(&now, NULL);
-
- /* A positive verbosity means to print every X iterations */
- if (verbose > 0 &&
- (next_num == NULL || num >= *next_num || num >= num_total)) {
- *next_num += verbose;
- if (next_time) {
- next_time->tv_sec = now.tv_sec - verbose;
- next_time->tv_usec = now.tv_usec;
- }
- return 1;
- }
-
- /* A negative verbosity means to print at most each X seconds */
- if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){
- next_time->tv_sec = now.tv_sec - verbose;
- next_time->tv_usec = now.tv_usec;
- if (next_num)
- *next_num = num;
- return 1;
- }
-
- return 0;
-}
-
-static int get_verbose(const char *arg)
-{
- int verbose;
-
- if (!arg || arg[0] == 'v')
- verbose = 1;
- else if (arg[0] == 's' || arg[0] == 'q')
- verbose = 0;
- else
- verbose = strtoul(arg, NULL, 0);
-
- return verbose;
-}
-
-static int do_disconnect(char *func, int verbose)
-{
- struct obd_ioctl_data data;
- int rc;
-
- if (connid == -1)
- return 0;
-
- IOCINIT(data);
-
- rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
- if (rc < 0) {
- fprintf(stderr, "error: %s: %x %s\n", cmdname(func),
- OBD_IOC_DISCONNECT, strerror(errno));
- } else {
- if (verbose)
- printf("%s: disconnected connid %d\n", cmdname(func),
- connid);
- connid = -1;
- }
-
- return rc;
-}
-
-extern command_t cmdlist[];
-
-static int jt_device(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- do_disconnect(argv[0], 1);
-
- memset(&data, 0, sizeof(data));
- if ( argc != 2 ) {
- fprintf(stderr, "usage: %s devno\n", cmdname(argv[0]));
- return -1;
- }
-
- data.ioc_dev = strtoul(argv[1], NULL, 0);
-
- if (obd_ioctl_pack(&data, &buf, max)) {
- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
- return -2;
- }
-
- if (fd == -1)
- fd = open("/dev/obd", O_RDWR);
- if (fd == -1) {
- fprintf(stderr, "error: %s: opening /dev/obd: %s\n",
- cmdname(argv[0]), strerror(errno));
- return errno;
- }
-
- rc = ioctl(fd, OBD_IOC_DEVICE , buf);
- if (rc < 0)
- fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
- OBD_IOC_DEVICE, strerror(rc = errno));
-
- return rc;
-}
-
-static int jt_connect(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
- do_disconnect(argv[0], 1);
-
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
- return -1;
- }
-
- rc = ioctl(fd, OBD_IOC_CONNECT , &data);
- if (rc < 0)
- fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
- OBD_IOC_CONNECT, strerror(rc = errno));
- else
- connid = data.ioc_conn1;
-
- return rc;
-}
-
-static int jt_disconnect(int argc, char **argv)
-{
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
- return -1;
- }
-
- return do_disconnect(argv[0], 0);
-}
-
-static int jt__device(int argc, char **argv)
-{
- char *arg2[3];
- int rc, ret;
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s devno <command [args ...]>\n",
- cmdname(argv[0]));
- return -1;
- }
-
- arg2[0] = "device";
- arg2[1] = argv[1];
- arg2[2] = NULL;
- rc = jt_device(2, arg2);
-
- if (!rc) {
- arg2[0] = "connect";
- arg2[1] = NULL;
- rc = jt_connect(1, arg2);
- }
-
- if (!rc)
- rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
-
- ret = do_disconnect(argv[0], 0);
- if (!rc)
- rc = ret;
-
- return rc;
-}
-
-static int jt__threads(int argc, char **argv)
-{
- int threads, next_thread;
- int verbose;
- int i, j;
- int rc;
-
- if (argc < 5) {
- fprintf(stderr,
- "usage: %s numthreads verbose devno <cmd [args ...]>\n",
- argv[0]);
- return -1;
- }
-
- threads = strtoul(argv[1], NULL, 0);
-
- verbose = get_verbose(argv[2]);
-
- printf("%s: starting %d threads on device %s running %s\n",
- argv[0], threads, argv[3], argv[4]);
-
- for (i = 1, next_thread = verbose; i <= threads; i++) {
- rc = fork();
- if (rc < 0) {
- fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
- strerror(rc = errno));
- break;
- } else if (rc == 0) {
- thread = i;
- argv[2] = "--device";
- return jt__device(argc - 2, argv + 2);
- } else if (be_verbose(verbose, NULL, i, &next_thread, threads))
- printf("%s: thread #%d (PID %d) started\n",
- argv[0], i, rc);
- rc = 0;
- }
-
- if (!thread) { /* parent process */
- if (!verbose)
- printf("%s: started %d threads\n\n", argv[0], i - 1);
- else
- printf("\n");
-
- for (j = 1; j < i; j++) {
- int status;
- int ret = wait(&status);
-
- if (ret < 0) {
- fprintf(stderr, "error: %s: wait - %s\n",
- argv[0], strerror(errno));
- if (!rc)
- rc = errno;
- } else {
- /*
- * This is a hack. We _should_ be able to use
- * WIFEXITED(status) to see if there was an
- * error, but it appears to be broken and it
- * always returns 1 (OK). See wait(2).
- */
- int err = WEXITSTATUS(status);
- if (err)
- fprintf(stderr,
- "%s: PID %d had rc=%d\n",
- argv[0], ret, err);
- if (!rc)
- rc = err;
- }
- }
- }
-
- return rc;
-}
-
-static int jt_detach(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
- return -1;
- }
-
- if (obd_ioctl_pack(&data, &buf, max)) {
- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
- return -2;
- }
-
- rc = ioctl(fd, OBD_IOC_DETACH , buf);
- if (rc < 0)
- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
- strerror(rc=errno));
-
- return rc;
-}
-
-static int jt_cleanup(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
- return -1;
- }
-
- rc = ioctl(fd, OBD_IOC_CLEANUP , &data);
- if (rc < 0)
- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
- strerror(rc=errno));
-
- return rc;
-}
-
-static int jt_newdev(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- if (getfd())
- return -1;
-
- IOCINIT(data);
-
- if (argc != 1) {
- fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
- return -1;
- }
-
- rc = ioctl(fd, OBD_IOC_NEWDEV , &data);
- if (rc < 0)
- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
- strerror(rc=errno));
- else {
- printf("Current device set to %d\n", data.ioc_dev);
- }
-
- return rc;
-}
-
-static int jt_attach(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
- if (argc != 2 && argc != 3) {
- fprintf(stderr, "usage: %s type [name [uuid]]\n", cmdname(argv[0]));
- return -1;
- }
-
- data.ioc_inllen1 = strlen(argv[1]) + 1;
- data.ioc_inlbuf1 = argv[1];
- if (argc == 3) {
- data.ioc_inllen2 = strlen(argv[2]) + 1;
- data.ioc_inlbuf2 = argv[2];
- }
-
- if (obd_ioctl_pack(&data, &buf, max)) {
- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
- return -2;
- }
-
- rc = ioctl(fd, OBD_IOC_ATTACH , buf);
- if (rc < 0)
- fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
- OBD_IOC_ATTACH, strerror(rc = errno));
- else if (argc == 3) {
- char name[1024];
- if (strlen(argv[2]) > 128) {
- printf("Name too long to set environment\n");
- return -EINVAL;
- }
- snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
- rc = setenv(name, argv[1], 1);
- if (rc) {
- printf("error setting env variable %s\n", name);
- }
- }
-
- return rc;
-}
-
-static int jt_name2dev(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- if (getfd())
- return -1;
-
- IOCINIT(data);
-
- if (argc != 2) {
- fprintf(stderr, "usage: %s name\n", cmdname(argv[0]));
- return -1;
- }
-
- data.ioc_inllen1 = strlen(argv[1]) + 1;
- data.ioc_inlbuf1 = argv[1];
-
-
- if (obd_ioctl_pack(&data, &buf, max)) {
- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
- return -2;
- }
- rc = ioctl(fd, OBD_IOC_NAME2DEV , buf);
- if (rc < 0)
- fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
- OBD_IOC_NAME2DEV, strerror(rc = errno));
- memcpy((char *)(&data), buf, sizeof(data));
- printf("%d\n", data.ioc_dev);
- return rc;
-}
-
-static int jt_setup(int argc, char **argv)
-{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
- if ( argc > 3) {
- fprintf(stderr, "usage: %s [device] [fstype]\n",
- cmdname(argv[0]));
- return -1;
- }
-
- if (argc > 1) {
- data.ioc_inllen1 = strlen(argv[1]) + 1;
- data.ioc_inlbuf1 = argv[1];
- data.ioc_dev = strtoul(argv[1], NULL, 0);
- } else {
- data.ioc_dev = -1;
- }
- if ( argc == 3 ) {
- data.ioc_inllen2 = strlen(argv[2]) + 1;
- data.ioc_inlbuf2 = argv[2];
- }
-
- if (obd_ioctl_pack(&data, &buf, max)) {
- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
- return -2;
- }
- rc = ioctl(fd, OBD_IOC_SETUP , buf);
- if (rc < 0)
- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
- strerror(rc = errno));
-
- return rc;
-}