X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fobd.c;h=6e2a9b01cc83fb6e3ea1697190f4805a47607333;hp=03864ca61c3f1f0871444533caec350d3995b31c;hb=5c5d70dc828ac4e3b348939a108f20395cb900ba;hpb=fbb7ead129258897f5a5d5c9ce28d31fbbe5bca2 diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 03864ca..6e2a9b0 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -1,29 +1,45 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Author: Peter J. Braam - * Author: Phil Schwan - * Author: Andreas Dilger - * Author: Robert Read + * GPL HEADER START * - * This file is part of Lustre, http://www.lustre.org. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/utils/obd.c + * + * Author: Peter J. Braam + * Author: Phil Schwan + * Author: Andreas Dilger + * Author: Robert Read */ - #include #include @@ -36,12 +52,12 @@ #include #include #include -#include -#include +#include + #include "obdctl.h" -#include /* for struct lov_stripe_md */ -#include +#include /* for struct lov_stripe_md */ +#include #include #include @@ -50,50 +66,53 @@ #include #include -#ifdef HAVE_ASM_PAGE_H -#include /* needed for PAGE_SIZE - rread */ -#endif - -#include -#include -#include "parser.h" +#include +#include +#include #include +#include + +#define MAX_STRING_SIZE 128 +#define DEVICES_LIST "/proc/fs/lustre/devices" +#if HAVE_LIBPTHREAD #include #include #include - -#define MAX_STRING_SIZE 128 -#define DEVICES_LIST "/proc/fs/lustre/devices" - #define MAX_THREADS 1024 + struct shared_data { __u64 counters[MAX_THREADS]; __u64 offsets[MAX_THREADS]; int running; int barrier; - pthread_mutex_t mutex; - pthread_cond_t cond; + int stop; + l_mutex_t mutex; + l_cond_t cond; }; + static struct shared_data *shared_data; static __u64 counter_snapshot[2][MAX_THREADS]; static int prev_valid; -struct timeval prev_time; - -static int jt_recording; -static char rawbuf[8192]; -static char *buf = rawbuf; -static int max = sizeof(rawbuf); - +static struct timeval prev_time; static int thread; static int nthreads; +#else +const int thread = 0; +const int nthreads = 1; +#endif + +#define MAX_IOC_BUFLEN 8192 -static uint32_t cur_device = MAX_OBD_DEVICES; +static int cur_device = -1; -union lsm_buffer { - char space [4096]; +#define MAX_STRIPES 170 +struct lov_oinfo lov_oinfos[MAX_STRIPES]; + +struct lsm_buffer { struct lov_stripe_md lsm; + struct lov_oinfo *ptrs[MAX_STRIPES]; } lsm_buffer; static int l2_ioctl(int dev_id, int opc, void *buf) @@ -101,75 +120,82 @@ static int l2_ioctl(int dev_id, int opc, void *buf) return l_ioctl(dev_id, opc, buf); } -#define IOC_INIT(data) \ -do { \ - memset(&data, 0, sizeof(data)); \ - data.ioc_dev = cur_device; \ -} while (0) - -#define IOC_PACK(func, data) \ -do { \ - memset(buf, 0, sizeof(rawbuf)); \ - if (obd_ioctl_pack(&data, &buf, max)) { \ - fprintf(stderr, "error: %s: invalid ioctl\n", \ - jt_cmdname(func)); \ - return -2; \ - } \ -} while (0) - -#define IOC_UNPACK(func, data) \ -do { \ - if (obd_ioctl_unpack(&data, buf, max)) { \ - fprintf(stderr, "error: %s: invalid reply\n", \ - jt_cmdname(func)); \ - return -2; \ - } \ -} while (0) - -int obd_record(enum cfg_record_type type, int len, void *ptr) +int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; + + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; + data.ioc_type = LUSTRE_CFG_TYPE; + data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, + lcfg->lcfg_buflens); + data.ioc_pbuf1 = (void *)lcfg; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(func)); + return rc; + } - IOC_INIT(data); - data.ioc_type = type; - data.ioc_plen1 = len; - data.ioc_pbuf1 = ptr; - IOC_PACK("obd_record", data); + rc = l_ioctl(dev_id, OBD_IOC_PROCESS_CFG, buf); - return l_ioctl(OBD_DEV_ID, OBD_IOC_DORECORD, &data); + return rc; } -int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg) +static int do_device(char *func, char *devname); + +static int get_mgs_device() +{ + char mgs[] = "$MGS"; + static int mgs_device = -1; + + if (mgs_device == -1) { + int rc; + do_disconnect(NULL, 1); + rc = do_device("mgsioc", mgs); + if (rc) { + fprintf(stderr, + "This command must be run on the MGS.\n"); + errno = ENODEV; + return -1; + } + mgs_device = cur_device; + } + return mgs_device; +} + +/* Returns -1 on error with errno set */ +int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg) { - int opc; - char lcfg_rawbuf[8192]; - char * lcfg_buf= lcfg_rawbuf; struct obd_ioctl_data data; - int len; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - memset(lcfg_buf, 0, sizeof(lcfg_rawbuf)); - if (lustre_cfg_pack(lcfg, &lcfg_buf, sizeof(lcfg_rawbuf), &len)) { + memset(&data, 0x00, sizeof(data)); + rc = data.ioc_dev = get_mgs_device(); + if (rc < 0) + goto out; + data.ioc_type = LUSTRE_CFG_TYPE; + data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, + lcfg->lcfg_buflens); + data.ioc_pbuf1 = (void *)lcfg; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { fprintf(stderr, "error: %s: invalid ioctl\n", jt_cmdname(func)); - return -2; + return rc; } - IOC_INIT(data); - data.ioc_type = LUSTRE_CFG_TYPE; - data.ioc_plen1 = len; - data.ioc_pbuf1 = lcfg_buf; - IOC_PACK(func, data); - - if (jt_recording) - opc = OBD_IOC_DORECORD; - else - opc = OBD_IOC_PROCESS_CFG; - - rc = l_ioctl(dev_id, opc, buf); - if (rc == 0) - rc = lustre_cfg_unpack(lcfg, lcfg_buf, sizeof(lcfg_rawbuf)); - + rc = l_ioctl(dev_id, OBD_IOC_PARAM, buf); +out: + if (rc) { + if (errno == ENOSYS) + fprintf(stderr, "Make sure cfg_device is set first.\n"); + } return rc; } @@ -196,18 +222,30 @@ char *obdo_print(struct obdo *obd) static int do_name2dev(char *func, char *name) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); - + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(name) + 1; data.ioc_inlbuf1 = name; - IOC_PACK(func, data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(func)); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf); if (rc < 0) return errno; - IOC_UNPACK(func, data); + rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid reply\n", + jt_cmdname(func)); + return rc; + } return data.ioc_dev + N2D_OFF; } @@ -223,75 +261,33 @@ int parse_devname(char *func, char *name) if (!name) return ret; - if (name[0] == '$' || name[0] == '%') { - name++; + if (isdigit(name[0])) { + ret = strtoul(name, NULL, 0); + } else { + if (name[0] == '$' || name[0] == '%') + name++; rc = do_name2dev(func, name); if (rc >= N2D_OFF) { ret = rc - N2D_OFF; - printf("Name %s is device %d\n", name, ret); + // printf("Name %s is device %d\n", name, ret); } else { - printf("No device found for name %s: %s\n", - name, strerror(rc)); + fprintf(stderr, "No device found for name %s: %s\n", + name, strerror(rc)); } - } else { - /* Assume it's a number. This means that bogus strings become - * 0. I might care about that some day. */ - ret = strtoul(name, NULL, 0); - //printf("Selected device %d\n", ret); } - return ret; } -static char * -lsm_string (struct lov_stripe_md *lsm) -{ - static char buffer[4096]; - char *p = buffer; - int space = sizeof (buffer); - int i; - int nob; - - *p = 0; - space--; - - nob = snprintf(p, space, LPX64, lsm->lsm_object_id); - p += nob; - space -= nob; - - if (lsm->lsm_stripe_count != 0) { - nob = snprintf (p, space, "=%u#%u", - lsm->lsm_stripe_size, - lsm->lsm_stripe_count); - p += nob; - space -= nob; - - for (i = 0; i < lsm->lsm_stripe_count; i++) { - nob = snprintf (p, space, "@%u:"LPX64, - lsm->lsm_oinfo[i].loi_ost_idx, - lsm->lsm_oinfo[i].loi_id); - p += nob; - space -= nob; - } - } - - if (space == 0) { /* probable overflow */ - fprintf (stderr, "lsm_string() overflowed buffer\n"); - abort (); - } - - return (buffer); -} - static void -reset_lsmb (union lsm_buffer *lsmb) +reset_lsmb (struct lsm_buffer *lsmb) { - memset (lsmb->space, 0, sizeof (lsmb->space)); + memset (&lsmb->lsm, 0, sizeof (lsmb->lsm)); + memset(lov_oinfos, 0, sizeof(lov_oinfos)); lsmb->lsm.lsm_magic = LOV_MAGIC; } static int -parse_lsm (union lsm_buffer *lsmb, char *string) +parse_lsm (struct lsm_buffer *lsmb, char *string) { struct lov_stripe_md *lsm = &lsmb->lsm; char *end; @@ -336,11 +332,11 @@ parse_lsm (union lsm_buffer *lsmb, char *string) if (*string != '@') return (-1); string++; - lsm->lsm_oinfo[i].loi_ost_idx = strtoul(string, &end, 0); + lsm->lsm_oinfo[i]->loi_ost_idx = strtoul(string, &end, 0); if (*end != ':') return (-1); string = end + 1; - lsm->lsm_oinfo[i].loi_id = strtoull(string, &end, 0); + lsm->lsm_oinfo[i]->loi_id = strtoull(string, &end, 0); string = end; } @@ -378,8 +374,7 @@ static int be_verbose(int verbose, struct timeval *next_time, gettimeofday(&now, NULL); /* A positive verbosity means to print every X iterations */ - if (verbose > 0 && - (next_num == NULL || num >= *next_num || num >= num_total)) { + if (verbose > 0 && (num >= *next_num || num >= num_total)) { *next_num += verbose; if (next_time) { next_time->tv_sec = now.tv_sec - verbose; @@ -393,8 +388,7 @@ static int be_verbose(int verbose, struct timeval *next_time, difftime(&now, next_time) >= 0.0){ next_time->tv_sec = now.tv_sec - verbose; next_time->tv_usec = now.tv_usec; - if (next_num) - *next_num = num; + *next_num = num; return 1; } @@ -431,10 +425,12 @@ static int get_verbose(char *func, const char *arg) int do_disconnect(char *func, int verbose) { - cur_device = MAX_OBD_DEVICES; + lcfg_set_devname(NULL); + cur_device = -1; return 0; } +#ifdef MAX_THREADS static void shmem_setup(void) { /* Create new segment */ @@ -448,7 +444,7 @@ static void shmem_setup(void) /* Attatch to new segment */ shared_data = (struct shared_data *)shmat(shmid, NULL, 0); - + if (shared_data == (struct shared_data *)(-1)) { fprintf(stderr, "Can't attach shared data: %s\n", strerror(errno)); @@ -465,15 +461,24 @@ static void shmem_setup(void) } } +static inline void shmem_lock(void) +{ + l_mutex_lock(&shared_data->mutex); +} + +static inline void shmem_unlock(void) +{ + l_mutex_unlock(&shared_data->mutex); +} + static inline void shmem_reset(int total_threads) { if (shared_data == NULL) return; memset(shared_data, 0, sizeof(*shared_data)); - pthread_mutex_init(&shared_data->mutex, NULL); - pthread_cond_init(&shared_data->cond, NULL); - + l_mutex_init(&shared_data->mutex); + l_cond_init(&shared_data->cond); memset(counter_snapshot, 0, sizeof(counter_snapshot)); prev_valid = 0; shared_data->barrier = total_threads; @@ -485,11 +490,12 @@ static inline void shmem_bump(void) if (shared_data == NULL || thread <= 0 || thread > MAX_THREADS) return; - pthread_mutex_lock(&shared_data->mutex); + + shmem_lock(); shared_data->counters[thread - 1]++; if (!bumped_running) shared_data->running++; - pthread_mutex_unlock(&shared_data->mutex); + shmem_unlock(); bumped_running = 1; } @@ -504,12 +510,12 @@ static void shmem_snap(int total_threads, int live_threads) if (shared_data == NULL || total_threads > MAX_THREADS) return; - - pthread_mutex_lock(&shared_data->mutex); + + shmem_lock(); memcpy(counter_snapshot[0], shared_data->counters, total_threads * sizeof(counter_snapshot[0][0])); running = shared_data->running; - pthread_mutex_unlock(&shared_data->mutex); + shmem_unlock(); gettimeofday(&this_time, NULL); @@ -524,13 +530,13 @@ static void shmem_snap(int total_threads, int live_threads) } secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) - - (prev_time.tv_sec + prev_time.tv_usec / 1000000.0); + (prev_time.tv_sec + prev_time.tv_usec / 1000000.0); if (prev_valid && live_threads == total_threads && secs > 0.0) /* someone screwed with the time? */ printf("%d/%d Total: %f/second\n", non_zero, total_threads, total / secs); - + memcpy(counter_snapshot[1], counter_snapshot[0], total_threads * sizeof(counter_snapshot[0][0])); prev_time = this_time; @@ -539,46 +545,84 @@ static void shmem_snap(int total_threads, int live_threads) prev_valid = 1; } +static void shmem_stop(void) +{ + if (shared_data == NULL) + return; + + shared_data->stop = 1; +} + +static int shmem_running(void) +{ + return (shared_data == NULL || + !shared_data->stop); +} +#else +static void shmem_setup(void) +{ +} + +static inline void shmem_reset(int total_threads) +{ +} + +static inline void shmem_bump(void) +{ +} + +static void shmem_lock() +{ +} + +static void shmem_unlock() +{ +} + +static void shmem_stop(void) +{ +} + +static int shmem_running(void) +{ + return 1; +} +#endif + extern command_t cmdlist[]; static int do_device(char *func, char *devname) { - struct obd_ioctl_data data; int dev; - memset(&data, 0, sizeof(data)); - dev = parse_devname(func, devname); if (dev < 0) return -1; + lcfg_set_devname(devname); cur_device = dev; return 0; } -int jt_obd_device(int argc, char **argv) +int jt_obd_get_device() { - int rc; - do_disconnect(argv[0], 1); - - if (argc != 2) - return CMD_HELP; - - rc = do_device(argv[0], argv[1]); - return rc; + return cur_device; } -int jt_obd_connect(int argc, char **argv) +int jt_obd_device(int argc, char **argv) { - return 0; -} + int rc; -int jt_obd_disconnect(int argc, char **argv) -{ - if (argc != 1) + if (argc > 2) return CMD_HELP; - return do_disconnect(argv[0], 0); + if (argc == 1) { + printf("current device is %d - %s\n", + cur_device, lcfg_get_devname() ? : "not set"); + return 0; + } + rc = do_device("device", argv[1]); + return rc; } int jt_opt_device(int argc, char **argv) @@ -601,6 +645,7 @@ int jt_opt_device(int argc, char **argv) return rc; } +#ifdef MAX_THREADS static void parent_sighandler (int sig) { return; @@ -608,21 +653,28 @@ static void parent_sighandler (int sig) int jt_opt_threads(int argc, char **argv) { + static char cmdstr[128]; sigset_t saveset; sigset_t sigset; struct sigaction sigact; struct sigaction saveact1; struct sigaction saveact2; - __u64 threads, next_thread; + unsigned long threads; + __u64 next_thread; int verbose; int rc = 0; + int report_count = -1; char *end; int i; if (argc < 5) return CMD_HELP; - threads = strtoull(argv[1], &end, 0); + threads = strtoul(argv[1], &end, 0); + + if (*end == '.') + report_count = strtoul(end + 1, &end, 0); + if (*end || threads > MAX_THREADS) { fprintf(stderr, "error: %s: invalid thread count '%s'\n", jt_cmdname(argv[0]), argv[1]); @@ -633,9 +685,15 @@ int jt_opt_threads(int argc, char **argv) if (verbose == BAD_VERBOSE) return CMD_HELP; - if (verbose != 0) - printf("%s: starting "LPD64" threads on device %s running %s\n", - argv[0], threads, argv[3], argv[4]); + if (verbose != 0) { + snprintf(cmdstr, sizeof(cmdstr), "%s", argv[4]); + for (i = 5; i < argc; i++) + snprintf(cmdstr + strlen(cmdstr), sizeof(cmdstr), + " %s", argv[i]); + + printf("%s: starting %ld threads on device %s running %s\n", + argv[0], threads, argv[3], cmdstr); + } shmem_reset(threads); @@ -646,7 +704,6 @@ int jt_opt_threads(int argc, char **argv) nthreads = threads; - for (i = 1, next_thread = verbose; i <= threads; i++) { rc = fork(); if (rc < 0) { @@ -655,6 +712,7 @@ int jt_opt_threads(int argc, char **argv) break; } else if (rc == 0) { sigprocmask(SIG_SETMASK, &saveset, NULL); + thread = i; argv[2] = "--device"; return jt_opt_device(argc - 2, argv + 2); @@ -711,19 +769,34 @@ int jt_opt_threads(int argc, char **argv) argv[0], ret, err); if (!rc) rc = err; + live_threads--; } } + /* Show stats while all threads running */ - if (verbose < 0) + if (verbose < 0) { shmem_snap(threads, live_threads); + if (report_count > 0 && --report_count == 0) + shmem_stop(); + } } sigaction(SIGCHLD, &saveact2, NULL); sigaction(SIGALRM, &saveact1, NULL); } + sigprocmask(SIG_SETMASK, &saveset, NULL); + return rc; } +#else +int jt_opt_threads(int argc, char **argv) +{ + fprintf(stderr, "%s not-supported in a single-threaded runtime\n", + jt_cmdname(argv[0])); + return CMD_HELP; +} +#endif int jt_opt_net(int argc, char **argv) { @@ -747,14 +820,22 @@ int jt_opt_net(int argc, char **argv) int jt_obd_no_transno(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 1) return CMD_HELP; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -766,14 +847,22 @@ int jt_obd_no_transno(int argc, char **argv) int jt_obd_set_readonly(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 1) return CMD_HELP; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -785,148 +874,26 @@ int jt_obd_set_readonly(int argc, char **argv) int jt_obd_abort_recovery(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 1) return CMD_HELP; - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), - strerror(rc = errno)); - - return rc; -} -static int is_number(char *str) -{ - int i, len; - - if (*str == '-' || *str == '+') - str++; - - if (!strncmp(str, "0x", 2)) - str += 2; - - len = strlen(str); - if (!len) - return 0; - - for (i = 0; i < len; i++) - if (!isdigit(str[i])) - return 0; - return 1; -} - -static int str2ugid(char *str, uint32_t *uid, uint32_t *gid) -{ - struct passwd *pwd; - struct group *grp; - char *p; - - p = strchr(str, ':'); - if (!p) - return -1; - *p++ = 0; - - pwd = getpwnam(str); - if (pwd) - *uid = pwd->pw_uid; - else { - if (!is_number(str)) - return -1; - *uid = atoi(str); - } - - grp = getgrnam(p); - if (grp) - *gid = grp->gr_gid; - else { - if (!is_number(p)) - return -1; - *gid = atoi(p); - } - return 0; -} - -static void ugid2str(char *uidname, char *gidname, uint32_t uid, uint32_t gid) -{ - struct passwd *pwd; - struct group *grp; - - pwd = getpwuid(uid); - if (pwd) - snprintf(uidname, 128, "%s", pwd->pw_name); - else - snprintf(uidname, 128, "%d", uid); - - grp = getgrgid(gid); - if (grp) - snprintf(gidname, 128, "%s", grp->gr_name); - else - snprintf(uidname, 128, "%d", gid); -} - -#define SQUASH_IOC_SIZE (4 * 4 + sizeof(ptl_nid_t)) -int jt_obd_root_squash(int argc, char **argv) -{ - struct obd_ioctl_data data; - char mybuf[SQUASH_IOC_SIZE]; - uint32_t *dir, *uid, *gid; - ptl_nid_t *nid; - int rc; - - IOC_INIT(data); - - if (argc > 3) - return CMD_HELP; - - memset(mybuf, 0, sizeof(mybuf)); - dir = (uint32_t *) mybuf; - uid = dir + 2; - gid = dir + 3; - nid = (ptl_nid_t *) (dir + 4); - - if (argc == 1) { - *dir = 0; - } else { - *dir = 1; - if (str2ugid(argv[1], uid, gid)) { - fprintf(stderr, "error: %s: can't parse ugid %s\n", - jt_cmdname(argv[0]), argv[1]); - return -1; - } - if (argc == 3) { - if (ptl_parse_nid(nid, argv[2])) { - fprintf(stderr, - "error: %s: can't parse nid %s\n", - jt_cmdname(argv[0]), argv[2]); - return -1; - } - } else - *nid = 0; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; } - - data.ioc_inllen1= SQUASH_IOC_SIZE; - data.ioc_inlbuf1 = mybuf; - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ROOT_SQUASH, buf); - IOC_UNPACK(argv[0], data); + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); - else if (argc == 1) { - char uidname[128], gidname[128]; - char nidstr[256] = {0, }; - - ugid2str(uidname, gidname, *uid, *gid); - ptl_nid2str(nidstr, *nid); - printf("squash (root:root) => (%s:%s), except nid %s\n", - uidname, gidname, nidstr); - } return rc; } @@ -934,15 +901,16 @@ int jt_obd_root_squash(int argc, char **argv) int jt_get_version(int argc, char **argv) { int rc; - char buf[8192]; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; if (argc != 1) return CMD_HELP; - memset(buf, 0, sizeof(buf)); + memset(buf, 0, sizeof(rawbuf)); data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); + data->ioc_inllen1 = sizeof(rawbuf) - cfs_size_round(sizeof(*data)); + data->ioc_inlbuf1 = buf + cfs_size_round(sizeof(*data)); data->ioc_len = obd_ioctl_packlen(data); rc = l2_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf); @@ -957,158 +925,125 @@ int jt_get_version(int argc, char **argv) return rc; } -int jt_obd_list(int argc, char **argv) +/* + * Print an obd device line with the ost_conn_uuid inserted, if the obd + * is an osc. + */ +static void print_obd_line(char *s) { - int rc; char buf[MAX_STRING_SIZE]; - FILE *fp = fopen(DEVICES_LIST, "r"); - - if (fp == NULL) { - fprintf(stderr, "error: %s: %s could not open file " - DEVICES_LIST " .\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - return rc; + char obd_name[MAX_OBD_NAME]; + FILE *fp = NULL; + char *ptr; + + if (sscanf(s, " %*d %*s osc %s %*s %*d ", obd_name) == 0) + goto try_mdc; + snprintf(buf, sizeof(buf), + "/proc/fs/lustre/osc/%s/ost_conn_uuid", obd_name); + if ((fp = fopen(buf, "r")) == NULL) + goto try_mdc; + goto got_one; + +try_mdc: + if (sscanf(s, " %*d %*s mdc %s %*s %*d ", obd_name) == 0) + goto fail; + snprintf(buf, sizeof(buf), + "/proc/fs/lustre/mdc/%s/mds_conn_uuid", obd_name); + if ((fp = fopen(buf, "r")) == NULL) + goto fail; + +got_one: + /* should not ignore fgets(3)'s return value */ + if (!fgets(buf, sizeof(buf), fp)) { + fprintf(stderr, "reading from %s: %s", buf, strerror(errno)); + fclose(fp); + return; } + fclose(fp); - if (argc != 1) - return CMD_HELP; + /* trim trailing newlines */ + ptr = strrchr(buf, '\n'); + if (ptr) *ptr = '\0'; + ptr = strrchr(s, '\n'); + if (ptr) *ptr = '\0'; - while (fgets(buf, sizeof(buf), fp) != NULL) - printf("%s", buf); + printf("%s %s\n", s, buf); + return; - fclose(fp); - - return 0; +fail: + printf("%s", s); + return; } -/* Get echo client's stripe meta-data for the given object - */ -int jt_obd_get_stripe (int argc, char **argv) +/* get device list by ioctl */ +int jt_obd_list_ioctl(int argc, char **argv) { - struct obd_ioctl_data data; - __u64 id; - int rc; - char *end; + int rc, index; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - if (argc != 2) - return (CMD_HELP); + if (argc > 2) + return CMD_HELP; + /* Just ignore a -t option. Only supported with /proc. */ + else if (argc == 2 && strcmp(argv[1], "-t") != 0) + return CMD_HELP; - id = strtoull (argv[1], &end, 0); - if (*end) { - fprintf (stderr, "Error: %s: invalid object id '%s'\n", - jt_cmdname (argv[0]), argv[1]); - return (CMD_HELP); + for (index = 0;; index++) { + memset(buf, 0, sizeof(rawbuf)); + data->ioc_version = OBD_IOCTL_VERSION; + data->ioc_inllen1 = + sizeof(rawbuf) - cfs_size_round(sizeof(*data)); + data->ioc_inlbuf1 = buf + cfs_size_round(sizeof(*data)); + data->ioc_len = obd_ioctl_packlen(data); + data->ioc_count = index; + + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETDEVICE, buf); + if (rc != 0) + break; + printf("%s\n", (char *)data->ioc_bulk); } - - memset (&lsm_buffer, 0, sizeof (lsm_buffer)); - - IOC_INIT (data); - data.ioc_obdo1.o_id = id; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - data.ioc_pbuf1 = (char *)&lsm_buffer; - data.ioc_plen1 = sizeof (lsm_buffer); - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf); - IOC_UNPACK(argv[0], data); - if (rc != 0) { - fprintf (stderr, "Error: %s: rc %d(%s)\n", - jt_cmdname (argv[0]), rc, strerror (errno)); - return (rc); + if (errno == ENOENT) + /* no device or the last device */ + rc = 0; + else + fprintf(stderr, "Error getting device list: %s: " + "check dmesg.\n", strerror(errno)); } - - printf ("%s\n", lsm_string (&lsm_buffer.lsm)); - - return (rc); + return rc; } -/* Set stripe meta-data for 1 or more objects. Object must be new to - * this echo client instance. - */ -int jt_obd_set_stripe (int argc, char **argv) +int jt_obd_list(int argc, char **argv) { - struct obd_ioctl_data data; - char *end; - int count = 1; - int i; int rc; + char buf[MAX_STRING_SIZE]; + FILE *fp = NULL; + int print_obd = 0; - if (argc < 2 || argc > 3) - return CMD_HELP; - - rc = parse_lsm (&lsm_buffer, argv[1]); - if (rc != 0) { - fprintf (stderr, "error: %s: invalid object '%s'\n", - jt_cmdname (argv[0]), argv[1]); + if (argc > 2) return CMD_HELP; - } - - if (argc > 2) { - count = strtol (argv[2], &end, 0); - if (*end != 0) { - fprintf (stderr, "error: %s: invalid count '%s'\n", - jt_cmdname (argv[0]), argv[1]); + else if (argc == 2) { + if (strcmp(argv[1], "-t") == 0) + print_obd = 1; + else return CMD_HELP; - } - } - - for (i = 0; i < count; i++) { - IOC_INIT (data); - data.ioc_obdo1.o_id = lsm_buffer.lsm.lsm_object_id + i; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - data.ioc_pbuf1 = (char *)&lsm_buffer; - data.ioc_plen1 = sizeof (lsm_buffer); - - IOC_PACK (argv[0], data); - rc = l2_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf); - IOC_UNPACK (argv[0], data); - - if (rc != 0) { - fprintf (stderr, "Error: %s: rc %d(%s)\n", - jt_cmdname (argv[0]), rc, strerror (errno)); - return (rc); - } } - return (0); -} - -/* Clear stripe meta-data info for an object on this echo-client instance - */ -int jt_obd_unset_stripe (int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - obd_id id; - int rc; - - if (argc != 2) - return CMD_HELP; - - id = strtoull (argv[1], &end, 0); - if (*end != 0) { - fprintf (stderr, "error: %s: invalid object id '%s'\n", - jt_cmdname (argv[0]), argv[1]); - return CMD_HELP; + fp = fopen(DEVICES_LIST, "r"); + if (fp == NULL) { + fprintf(stderr, "error: %s: %s opening "DEVICES_LIST"\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + return jt_obd_list_ioctl(argc, argv); } - IOC_INIT (data); - data.ioc_obdo1.o_id = id; - data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - - IOC_PACK (argv[0], data); - rc = l2_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf); - IOC_UNPACK (argv[0], data); - - if (rc != 0) - fprintf (stderr, "Error: %s: rc %d(%s)\n", - jt_cmdname (argv[0]), rc, strerror (errno)); + while (fgets(buf, sizeof(buf), fp) != NULL) + if (print_obd) + print_obd_line(buf); + else + printf("%s", buf); - return (0); + fclose(fp); + return 0; } /* Create one or more objects, arg[4] may describe stripe meta-data. If @@ -1116,15 +1051,18 @@ int jt_obd_unset_stripe (int argc, char **argv) * object ids. Use get_stripe on this node to print full lsm and * set_stripe on another node to cut/paste between nodes. */ +/* create [] [q|v|# verbosity] [striping] */ int jt_obd_create(int argc, char **argv) { + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; struct obd_ioctl_data data; struct timeval next_time; __u64 count = 1, next_count, base_id = 0; int verbose = 1, mode = 0100644, rc = 0, i, valid_lsm = 0; char *end; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc < 2 || argc > 5) return CMD_HELP; @@ -1169,7 +1107,7 @@ int jt_obd_create(int argc, char **argv) gettimeofday(&next_time, NULL); next_time.tv_sec -= verbose; - for (i = 1, next_count = verbose; i <= count; i++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { data.ioc_obdo1.o_mode = mode; data.ioc_obdo1.o_id = base_id; data.ioc_obdo1.o_uid = 0; @@ -1182,9 +1120,15 @@ int jt_obd_create(int argc, char **argv) data.ioc_pbuf1 = (char *)&lsm_buffer; } - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf); - IOC_UNPACK(argv[0], data); + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); shmem_bump(); if (rc < 0) { fprintf(stderr, "error: %s: #%d - %s\n", @@ -1192,7 +1136,7 @@ int jt_obd_create(int argc, char **argv) break; } if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) { - fprintf(stderr, "error: %s: objid not valid #%d:"LPX64"\n", + fprintf(stderr,"error: %s: oid not valid #%d:"LPX64"\n", jt_cmdname(argv[0]), i, data.ioc_obdo1.o_valid); rc = EINVAL; break; @@ -1208,10 +1152,12 @@ int jt_obd_create(int argc, char **argv) int jt_obd_setattr(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char *end; int rc; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 2) return CMD_HELP; @@ -1229,7 +1175,13 @@ int jt_obd_setattr(int argc, char **argv) } data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -1243,6 +1195,7 @@ int jt_obd_test_setattr(int argc, char **argv) struct obd_ioctl_data data; struct timeval start, next_time; __u64 i, count, next_count; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int verbose = 1; obd_id objid = 3; char *end; @@ -1251,7 +1204,8 @@ int jt_obd_test_setattr(int argc, char **argv) if (argc < 2 || argc > 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; count = strtoull(argv[1], &end, 0); if (*end) { fprintf(stderr, "error: %s: invalid iteration count '%s'\n", @@ -1286,11 +1240,17 @@ int jt_obd_test_setattr(int argc, char **argv) printf("%s: setting "LPD64" attrs (objid "LPX64"): %s", jt_cmdname(argv[0]), count, objid, ctime(&start.tv_sec)); - for (i = 1, next_count = verbose; i <= count; i++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { data.ioc_obdo1.o_id = objid; data.ioc_obdo1.o_mode = S_IFREG; data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - IOC_PACK(argv[0], data); + memset(buf, 0x00, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, &data); shmem_bump(); if (rc < 0) { @@ -1322,23 +1282,24 @@ int jt_obd_test_setattr(int argc, char **argv) return rc; } - int jt_obd_destroy(int argc, char **argv) { struct obd_ioctl_data data; struct timeval next_time; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; __u64 count = 1, next_count; int verbose = 1; __u64 id; char *end; int rc = 0, i; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc < 2 || argc > 4) return CMD_HELP; id = strtoull(argv[1], &end, 0); - if (*end) { + if (*end || id == 0 || errno != 0) { fprintf(stderr, "error: %s: invalid objid '%s'\n", jt_cmdname(argv[0]), argv[1]); return CMD_HELP; @@ -1363,14 +1324,20 @@ int jt_obd_destroy(int argc, char **argv) gettimeofday(&next_time, NULL); next_time.tv_sec -= verbose; - for (i = 1, next_count = verbose; i <= count; i++, id++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++, id++) { data.ioc_obdo1.o_id = id; data.ioc_obdo1.o_mode = S_IFREG | 0644; data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf); - IOC_UNPACK(argv[0], data); + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); shmem_bump(); if (rc < 0) { fprintf(stderr, "error: %s: objid "LPX64": %s\n", @@ -1389,13 +1356,15 @@ int jt_obd_destroy(int argc, char **argv) int jt_obd_getattr(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char *end; int rc; if (argc != 2) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); if (*end) { fprintf(stderr, "error: %s: invalid objid '%s'\n", @@ -1404,12 +1373,18 @@ int jt_obd_getattr(int argc, char **argv) } /* to help obd filter */ data.ioc_obdo1.o_mode = 0100644; - data.ioc_obdo1.o_valid = (obd_valid)~0ULL; + data.ioc_obdo1.o_valid = 0xffffffff; printf("%s: object id "LPX64"\n", jt_cmdname(argv[0]),data.ioc_obdo1.o_id); - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf); - IOC_UNPACK(argv[0], data); + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -1424,6 +1399,7 @@ int jt_obd_test_getattr(int argc, char **argv) { struct obd_ioctl_data data; struct timeval start, next_time; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; __u64 i, count, next_count; int verbose = 1; obd_id objid = 3; @@ -1433,7 +1409,8 @@ int jt_obd_test_getattr(int argc, char **argv) if (argc < 2 || argc > 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; count = strtoull(argv[1], &end, 0); if (*end) { fprintf(stderr, "error: %s: invalid iteration count '%s'\n", @@ -1468,11 +1445,17 @@ int jt_obd_test_getattr(int argc, char **argv) printf("%s: getting "LPD64" attrs (objid "LPX64"): %s", jt_cmdname(argv[0]), count, objid, ctime(&start.tv_sec)); - for (i = 1, next_count = verbose; i <= count; i++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { data.ioc_obdo1.o_id = objid; data.ioc_obdo1.o_mode = S_IFREG; - data.ioc_obdo1.o_valid = (obd_valid)~0ULL; - IOC_PACK(argv[0], data); + data.ioc_obdo1.o_valid = 0xffffffff; + memset(buf, 0x00, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data); shmem_bump(); if (rc < 0) { @@ -1504,12 +1487,20 @@ int jt_obd_test_getattr(int argc, char **argv) return rc; } +/* test_brw count + mode + verbosity + blocksize + <[[]t(inc obj by thread#)]obj> object + [p|g] batch */ int jt_obd_test_brw(int argc, char **argv) { struct obd_ioctl_data data; struct timeval start, next_time; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; __u64 count, next_count, len, stride, thr_offset = 0, objid = 3; int write = 0, verbose = 1, cmd, i, rc = 0, pages = 1; + int offset_pages = 0; long n; int repeat_offset = 0; unsigned long long ull; @@ -1524,9 +1515,7 @@ int jt_obd_test_brw(int argc, char **argv) return CMD_HELP; } - /* make each thread write to a different offset */ count = strtoull(argv[1], &end, 0); - if (*end) { fprintf(stderr, "error: %s: bad iteration count '%s'\n", jt_cmdname(argv[0]), argv[1]); @@ -1537,6 +1526,7 @@ int jt_obd_test_brw(int argc, char **argv) if (argv[2][0] == 'w' || argv[2][0] == '1') write = 1; /* else it's a read */ + if (argv[2][0] != 0) for (i = 1; argv[2][i] != 0; i++) switch (argv[2][i]) { @@ -1563,12 +1553,18 @@ int jt_obd_test_brw(int argc, char **argv) if (argc >= 5) { pages = strtoul(argv[4], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: bad page count '%s'\n", + + if (*end == '+') + offset_pages = strtoul(end + 1, &end, 0); + + if (*end != 0 || + offset_pages < 0 || offset_pages >= pages) { + fprintf(stderr, "error: %s: bad npages[+offset] parameter '%s'\n", jt_cmdname(argv[0]), argv[4]); return CMD_HELP; } } + if (argc >= 6) { if (thread && (n = strtol(argv[5], &end, 0)) > 0 && @@ -1592,7 +1588,8 @@ int jt_obd_test_brw(int argc, char **argv) } } - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; /* communicate the 'type' of brw test and batching to echo_client. * don't start. we'd love to refactor this lctl->echo_client @@ -1624,43 +1621,44 @@ int jt_obd_test_brw(int argc, char **argv) jt_cmdname(argv[0]), argv[6]); return CMD_HELP; } - data.ioc_plen1 *= PAGE_SIZE; + data.ioc_plen1 *= getpagesize(); } - len = pages * PAGE_SIZE; + len = pages * getpagesize(); + thr_offset = offset_pages * getpagesize(); stride = len; +#ifdef MAX_THREADS if (thread) { - pthread_mutex_lock (&shared_data->mutex); + shmem_lock (); if (nthr_per_obj != 0) { /* threads interleave */ obj_idx = (thread - 1)/nthr_per_obj; objid += obj_idx; stride *= nthr_per_obj; - thr_offset = ((thread - 1) % nthr_per_obj) * len; - if (thr_offset == 0) - shared_data->offsets[obj_idx] = stride; + if (thread == 1) + shared_data->offsets[obj_idx] = stride + thr_offset; + thr_offset += ((thread - 1) % nthr_per_obj) * len; } else { /* threads disjoint */ - thr_offset = (thread - 1) * len; + thr_offset += (thread - 1) * len; } shared_data->barrier--; if (shared_data->barrier == 0) - pthread_cond_broadcast(&shared_data->cond); + l_cond_broadcast(&shared_data->cond); else - pthread_cond_wait(&shared_data->cond, - &shared_data->mutex); + l_cond_wait(&shared_data->cond, + &shared_data->mutex); - pthread_mutex_unlock (&shared_data->mutex); + shmem_unlock (); } - +#endif data.ioc_obdo1.o_id = objid; data.ioc_obdo1.o_mode = S_IFREG; data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLFLAGS; data.ioc_obdo1.o_flags = (verify ? OBD_FL_DEBUG_CHECK : 0); - data.ioc_count = len; data.ioc_offset = (repeat_offset ? 0 : thr_offset); @@ -1674,9 +1672,15 @@ int jt_obd_test_brw(int argc, char **argv) pages, objid, data.ioc_offset, ctime(&start.tv_sec)); cmd = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ; - for (i = 1, next_count = verbose; i <= count; i++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { data.ioc_obdo1.o_valid &= ~(OBD_MD_FLBLOCKS|OBD_MD_FLGRANT); - IOC_PACK(argv[0], data); + memset(buf, 0x00, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, cmd, buf); shmem_bump(); if (rc) { @@ -1684,23 +1688,30 @@ int jt_obd_test_brw(int argc, char **argv) jt_cmdname(argv[0]), i, strerror(rc = errno), write ? "write" : "read"); break; - } else if (be_verbose(verbose, &next_time,i, &next_count,count)) + } else if (be_verbose(verbose, &next_time,i, &next_count,count)) { + shmem_lock (); printf("%s: %s number %d @ "LPD64":"LPU64" for %d\n", jt_cmdname(argv[0]), write ? "write" : "read", i, data.ioc_obdo1.o_id, data.ioc_offset, - (int)(pages * PAGE_SIZE)); + (int)(pages * getpagesize())); + shmem_unlock (); + } if (!repeat_offset) { +#ifdef MAX_THREADS if (stride == len) { data.ioc_offset += stride; } else if (i < count) { - pthread_mutex_lock (&shared_data->mutex); + shmem_lock (); data.ioc_offset = shared_data->offsets[obj_idx]; shared_data->offsets[obj_idx] += len; - pthread_mutex_unlock (&shared_data->mutex); + shmem_unlock (); } +#else + data.ioc_offset += len; + obj_idx = 0; /* avoids an unused var warning */ +#endif } - } if (!rc) { @@ -1729,11 +1740,13 @@ int jt_obd_lov_getconfig(int argc, char **argv) struct obd_ioctl_data data; struct lov_desc desc; struct obd_uuid *uuidarray; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; __u32 *obdgens; char *path; int rc, fd; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 2) return CMD_HELP; @@ -1767,6 +1780,7 @@ repeat: goto out_uuidarray; } + memset(buf, 0x00, sizeof(rawbuf)); data.ioc_inllen1 = sizeof(desc); data.ioc_inlbuf1 = (char *)&desc; data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); @@ -1774,7 +1788,7 @@ repeat: data.ioc_inllen3 = desc.ld_tgt_count * sizeof(*obdgens); data.ioc_inlbuf3 = (char *)obdgens; - if (obd_ioctl_pack(&data, &buf, max)) { + if (obd_ioctl_pack(&data, &buf, sizeof(rawbuf))) { fprintf(stderr, "error: %s: invalid ioctl\n", jt_cmdname(argv[0])); rc = -EINVAL; @@ -1793,14 +1807,17 @@ repeat: __u32 *genp; int i; - if (obd_ioctl_unpack(&data, buf, max)) { + if (obd_ioctl_unpack(&data, buf, sizeof(rawbuf))) { fprintf(stderr, "error: %s: invalid reply\n", jt_cmdname(argv[0])); rc = -EINVAL; goto out; } - printf("default_stripe_count: %u\n", - desc.ld_default_stripe_count); + if (desc.ld_default_stripe_count == (__u32)-1) + printf("default_stripe_count: %d\n", -1); + else + printf("default_stripe_count: %u\n", + desc.ld_default_stripe_count); printf("default_stripe_size: "LPU64"\n", desc.ld_default_stripe_size); printf("default_stripe_offset: "LPU64"\n", @@ -1822,48 +1839,16 @@ out: return rc; } -int jt_obd_test_ldlm(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf); - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - -int jt_obd_dump_ldlm(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf); - if (rc) - fprintf(stderr, "error: %s failed: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - int jt_obd_ldlm_regress_start(int argc, char **argv) { int rc; struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char argstring[200]; int i, count = sizeof(argstring) - 1; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc > 5) return CMD_HELP; @@ -1880,7 +1865,13 @@ int jt_obd_ldlm_regress_start(int argc, char **argv) data.ioc_inllen1 = strlen(argstring) + 1; } - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf); if (rc) fprintf(stderr, "error: %s: test failed: %s\n", @@ -1892,13 +1883,22 @@ int jt_obd_ldlm_regress_start(int argc, char **argv) int jt_obd_ldlm_regress_stop(int argc, char **argv) { int rc; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; struct obd_ioctl_data data; - IOC_INIT(data); + + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 1) return CMD_HELP; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf); if (rc) @@ -1910,16 +1910,24 @@ int jt_obd_ldlm_regress_stop(int argc, char **argv) static int do_activate(int argc, char **argv, int flag) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 1) return CMD_HELP; /* reuse offset for 'active' */ data.ioc_offset = flag; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, IOC_OSC_SET_ACTIVE, buf); if (rc) fprintf(stderr, "error: %s: failed: %s\n", @@ -1941,9 +1949,11 @@ int jt_obd_activate(int argc, char **argv) int jt_obd_recover(int argc, char **argv) { int rc; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; struct obd_ioctl_data data; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; if (argc > 2) return CMD_HELP; @@ -1952,7 +1962,13 @@ int jt_obd_recover(int argc, char **argv) data.ioc_inlbuf1 = argv[1]; } - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CLIENT_RECOVER, buf); if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -1965,6 +1981,7 @@ int jt_obd_recover(int argc, char **argv) int jt_obd_mdc_lookup(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char *parent, *child; int rc, fd, verbose = 1; @@ -1976,12 +1993,19 @@ int jt_obd_mdc_lookup(int argc, char **argv) if (argc == 4) verbose = get_verbose(argv[0], argv[3]); - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(child) + 1; data.ioc_inlbuf1 = child; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } fd = open(parent, O_RDONLY); if (fd < 0) { @@ -1998,7 +2022,12 @@ int jt_obd_mdc_lookup(int argc, char **argv) close(fd); if (verbose) { - IOC_UNPACK(argv[0], data); + rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid reply\n", + jt_cmdname(argv[0])); + return rc; + } printf("%s: mode %o uid %d gid %d\n", child, data.ioc_obdo1.o_mode, data.ioc_obdo1.o_uid, data.ioc_obdo1.o_gid); @@ -2007,287 +2036,168 @@ int jt_obd_mdc_lookup(int argc, char **argv) return rc; } -int jt_obd_close_uuid(int argc, char **argv) +int jt_cfg_dump_log(int argc, char **argv) { - int rc, nal; struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - if (argc != 3) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 0; - } - - nal = ptl_name2nal(argv[2]); - - if (nal <= 0) { - fprintf (stderr, "Can't parse NAL %s\n", argv[2]); - return -1; - } + if (argc != 2) + return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; - data.ioc_nal = nal; - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { - fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n", - strerror(errno)); - return -1; + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; } - return 0; + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DUMP_LOG, buf); + if (rc < 0) + fprintf(stderr, "OBD_IOC_DUMP_LOG failed: %s\n", + strerror(errno)); + + return rc; } -int jt_obd_start(int argc, char **argv) +int jt_llog_catlist(int argc, char **argv) { - int rc; struct obd_ioctl_data data; - - if (argc != 2) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 0; - } - - IOC_INIT(data); - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_START, buf); + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; + + if (argc != 1) + return CMD_HELP; + + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; + data.ioc_inllen1 = sizeof(rawbuf) - cfs_size_round(sizeof(data)); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { - fprintf(stderr, "error: %s: ioctl error: %s\n", - jt_cmdname(argv[0]), strerror(errno)); - return -1; + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; } - return 0; + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf); + if (rc == 0) + fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); + else + fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", + strerror(errno)); + + return rc; } -int jt_cfg_record(int argc, char **argv) +int jt_llog_info(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); - if (argc != 2) return CMD_HELP; + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; + data.ioc_inllen2 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) - + cfs_size_round(data.ioc_inllen1); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECORD, buf); - if (rc == 0) { - jt_recording = 1; - ptl_set_cfg_record_cb(obd_record); - } else { - fprintf(stderr, "OBD_IOC_RECORD failed: %s\n", + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf); + if (rc == 0) + fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); + else + fprintf(stderr, "OBD_IOC_LLOG_INFO failed: %s\n", strerror(errno)); - } return rc; } -int jt_cfg_parse(int argc, char **argv) +int jt_llog_print(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); - - if (argc != 2) + if (argc != 2 && argc != 4) return CMD_HELP; + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; + if (argc == 4) { + data.ioc_inllen2 = strlen(argv[2]) + 1; + data.ioc_inlbuf2 = argv[2]; + data.ioc_inllen3 = strlen(argv[3]) + 1; + data.ioc_inlbuf3 = argv[3]; + } else { + char from[2] = "1", to[3] = "-1"; + data.ioc_inllen2 = strlen(from) + 1; + data.ioc_inlbuf2 = from; + data.ioc_inllen3 = strlen(to) + 1; + data.ioc_inlbuf3 = to; + } + data.ioc_inllen4 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) - + cfs_size_round(data.ioc_inllen1) - + cfs_size_round(data.ioc_inllen2) - + cfs_size_round(data.ioc_inllen3); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_PARSE, buf); - if (rc < 0) - fprintf(stderr, "OBD_IOC_PARSE failed: %s\n", + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_PRINT, buf); + if (rc == 0) + fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); + else + fprintf(stderr, "OBD_IOC_LLOG_PRINT failed: %s\n", strerror(errno)); return rc; } - -int jt_cfg_dump_log(int argc, char **argv) +int jt_llog_cancel(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); - - if (argc != 2) - return CMD_HELP; + if (argc != 4) + return CMD_HELP; - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DUMP_LOG, buf); - if (rc < 0) - fprintf(stderr, "OBD_IOC_DUMP_LOG failed: %s\n", - strerror(errno)); - - return rc; -} - -int jt_cfg_clear_log(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - - if (argc != 2) - return CMD_HELP; - - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEAR_LOG, buf); - if (rc < 0) - fprintf(stderr, "OBD_IOC_CLEAR_LOG failed: %s\n", - strerror(errno)); - - return rc; -} - - - -int jt_cfg_endrecord(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - if (!jt_recording) { - fprintf(stderr, "Not recording, so endrecord doesn't make " - "sense.\n"); - return 0; - } - - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ENDRECORD, buf); - if (rc == 0) { - jt_recording = 0; - ptl_set_cfg_record_cb(NULL); - } else { - fprintf(stderr, "OBD_IOC_ENDRECORD failed: %s\n", - strerror(errno)); - } - return rc; -} - -int jt_llog_catlist(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - if (argc != 1) - return CMD_HELP; - - IOC_INIT(data); - data.ioc_inllen1 = max - size_round(sizeof(data)); - IOC_PACK(argv[0], data); - - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf); - if (rc == 0) - fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); - else - fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", - strerror(errno)); - - return rc; -} - -int jt_llog_info(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - if (argc != 2) - return CMD_HELP; - - IOC_INIT(data); - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - data.ioc_inllen2 = max - size_round(sizeof(data)) - - size_round(data.ioc_inllen1); - IOC_PACK(argv[0], data); - - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf); - if (rc == 0) - fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); - else - fprintf(stderr, "OBD_IOC_LLOG_INFO failed: %s\n", - strerror(errno)); - - return rc; -} - -int jt_llog_print(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - if (argc != 2 && argc != 4) - return CMD_HELP; - - IOC_INIT(data); - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - if (argc == 4) { - data.ioc_inllen2 = strlen(argv[2]) + 1; - data.ioc_inlbuf2 = argv[2]; - data.ioc_inllen3 = strlen(argv[3]) + 1; - data.ioc_inlbuf3 = argv[3]; - } else { - char from[2] = "1", to[3] = "-1"; - data.ioc_inllen2 = strlen(from) + 1; - data.ioc_inlbuf2 = from; - data.ioc_inllen3 = strlen(to) + 1; - data.ioc_inlbuf3 = to; - } - data.ioc_inllen4 = max - size_round(sizeof(data)) - - size_round(data.ioc_inllen1) - - size_round(data.ioc_inllen2) - - size_round(data.ioc_inllen3); - IOC_PACK(argv[0], data); - - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_PRINT, buf); - if (rc == 0) - fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); - else - fprintf(stderr, "OBD_IOC_LLOG_PRINT failed: %s\n", - strerror(errno)); - - return rc; -} - -int jt_llog_cancel(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - if (argc != 4) - return CMD_HELP; - - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; data.ioc_inllen2 = strlen(argv[2]) + 1; data.ioc_inlbuf2 = argv[2]; data.ioc_inllen3 = strlen(argv[3]) + 1; data.ioc_inlbuf3 = argv[3]; - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CANCEL, buf); if (rc == 0) @@ -2302,12 +2212,14 @@ int jt_llog_cancel(int argc, char **argv) int jt_llog_check(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; if (argc != 2 && argc != 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; if (argc == 4) { @@ -2322,11 +2234,17 @@ int jt_llog_check(int argc, char **argv) data.ioc_inllen3 = strlen(to) + 1; data.ioc_inlbuf3 = to; } - data.ioc_inllen4 = max - size_round(sizeof(data)) - - size_round(data.ioc_inllen1) - - size_round(data.ioc_inllen2) - - size_round(data.ioc_inllen3); - IOC_PACK(argv[0], data); + data.ioc_inllen4 = sizeof(rawbuf) - cfs_size_round(sizeof(data)) - + cfs_size_round(data.ioc_inllen1) - + cfs_size_round(data.ioc_inllen2) - + cfs_size_round(data.ioc_inllen3); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CHECK, buf); if (rc == 0) @@ -2340,19 +2258,27 @@ int jt_llog_check(int argc, char **argv) int jt_llog_remove(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; if (argc != 3 && argc != 2) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; 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]; } - IOC_PACK(argv[0], data); + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_REMOVE, buf); if (rc == 0) { @@ -2366,108 +2292,229 @@ int jt_llog_remove(int argc, char **argv) return rc; } -int jt_obd_reint_sync(int argc, char **argv) + +/* attach a regular file to virtual block device. + * return vaule: + * -1: fatal error + * 1: error, it always means the command run failed + * 0: success + */ +static int jt_blockdev_run_process(const char *file, char *argv[]) { - struct obd_ioctl_data data; - int rc = 0; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CMOBD_SYNC, buf); - - if (rc) { - fprintf(stderr, "OBD_IOC_CMOBD_SYNC failed: %s\n", - strerror(errno)); + pid_t pid; + int rc; + + pid = vfork(); + if (pid == 0) { /* child process */ + /* don't print error messages */ + close(1), close(2); + (void)execvp(file, argv); + exit(-1); + } else if (pid > 0) { + int status; + + rc = waitpid(pid, &status, 0); + if (rc < 0 || !WIFEXITED(status)) + return -1; + + return WEXITSTATUS(status); } - return rc; - + + return -1; } -int jt_obd_cache_on(int argc, char **argv) +static int jt_blockdev_find_module(const char *module) { - struct obd_ioctl_data data; - int rc = 0; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_COBD_CON, buf); - - if (rc) { - fprintf(stderr, "OBD_IOC_COBD_CON failed: %s\n", - strerror(errno)); + FILE *fp; + int found = 0; + char buf[1024]; + + fp = fopen("/proc/modules", "r"); + if (fp == NULL) + return -1; + + while (fgets(buf, 1024, fp) != NULL) { + *strchr(buf, ' ') = 0; + if (strcmp(module, buf) == 0) { + found = 1; + break; + } } - return rc; - + fclose(fp); + + return found; } -int jt_obd_cache_off(int argc, char **argv) + +static int jt_blockdev_probe_module(const char *module) { - struct obd_ioctl_data data; - int rc = 0; - - IOC_INIT(data); - if (argc != 1) - return CMD_HELP; - IOC_PACK(argv[0], data); - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_COBD_COFF, buf); - if (rc) { - fprintf(stderr, "OBD_IOC_COBD_COFF failed: %s\n", - strerror(errno)); - } - return rc; + char buf[1024]; + char *argv[10]; + int c, rc; + + if (jt_blockdev_find_module(module) == 1) + return 0; + + /* run modprobe first */ + c = 0; + argv[c++] = "/sbin/modprobe"; + argv[c++] = "-q"; + argv[c++] = (char *)module; + argv[c++] = NULL; + rc = jt_blockdev_run_process("modprobe", argv); + if (rc != 1) + return rc; + + /* cannot find the module in default directory ... */ + sprintf(buf, "../llite/%s.ko", module); + c = 0; + argv[c++] = "/sbin/insmod"; + argv[c++] = buf; + argv[c++] = NULL; + rc = jt_blockdev_run_process("insmod", argv); + return rc ? -1 : 0; } -int jt_obd_snap_add(int argc, char **argv) + +int jt_blockdev_attach(int argc, char **argv) { - struct obd_ioctl_data data; - int rc = 0; - + int rc, fd; + struct stat st; + char *filename, *devname; + unsigned long dev; + if (argc != 3) - return CMD_HELP; + return CMD_HELP; - shmem_setup(); - register_ioc_dev(SMFS_DEV_ID, SMFS_DEV_PATH); - - IOC_INIT(data); - - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - data.ioc_inllen2 = strlen(argv[2]) + 2; - data.ioc_inlbuf2 = argv[2]; + if (jt_blockdev_probe_module("llite_lloop") < 0) { + fprintf(stderr, "error: cannot find module llite_lloop.(k)o\n"); + return ENOENT; + } + + filename = argv[1]; + devname = argv[2]; + + fd = open(filename, O_RDWR); + if (fd < 0) { + fprintf(stderr, "file %s can't be opened(%s)\n\n", + filename, strerror(errno)); + return CMD_HELP; + } + + rc = ioctl(fd, LL_IOC_LLOOP_ATTACH, &dev); + if (rc < 0) { + rc = errno; + fprintf(stderr, "attach error(%s)\n", strerror(rc)); + goto out; + } + + rc = stat(devname, &st); + if (rc == 0 && (!S_ISBLK(st.st_mode) || st.st_rdev != dev)) { + rc = EEXIST; + } else if (rc < 0) { + if (errno == ENOENT && + !mknod(devname, S_IFBLK|S_IRUSR|S_IWUSR, dev)) + rc = 0; + else + rc = errno; + } - IOC_PACK(argv[0], data); - - rc = l_ioctl(SMFS_DEV_ID, OBD_IOC_SMFS_SNAP_ADD, buf); - - unregister_ioc_dev(SMFS_DEV_ID); if (rc) { - fprintf(stderr, "OBD_IOC_SNAP_ADD failed: rc=%s\n", - strerror(errno)); + fprintf(stderr, "error: the file %s could be attached to block " + "device %X but creating %s failed: %s\n" + "now detaching the block device..", + filename, (int)dev, devname, strerror(rc)); + + (void)ioctl(fd, LL_IOC_LLOOP_DETACH_BYDEV, dev); + fprintf(stderr, "%s\n", strerror(errno)); } - - return rc; +out: + close(fd); + return -rc; +} + +int jt_blockdev_detach(int argc, char **argv) +{ + char *filename; + int rc, fd; + + if (argc != 2) + return CMD_HELP; + + filename = argv[1]; + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "cannot open file %s error %s\n", + filename, strerror(errno)); + return CMD_HELP; + } + + rc = ioctl(fd, LL_IOC_LLOOP_DETACH, 0); + if (rc < 0) { + rc = errno; + fprintf(stderr, "detach error(%s)\n", strerror(rc)); + } else { + (void)unlink(filename); + } + + close(fd); + return -rc; +} + +int jt_blockdev_info(int argc, char **argv) +{ + char *filename; + int rc, fd; + __u64 ino; + + if (argc != 2) + return CMD_HELP; + + filename = argv[1]; + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "cannot open file %s error: %s\n", + filename, strerror(errno)); + return CMD_HELP; + } + + rc = ioctl(fd, LL_IOC_LLOOP_INFO, &ino); + if (rc < 0) { + rc = errno; + fprintf(stderr, "error: %s\n", strerror(errno)); + goto out; + } + fprintf(stdout, "lloop device info: "); + if (ino == 0ULL) + fprintf(stdout, "Not attached\n"); + else + fprintf(stdout, "attached to inode "LPU64"\n", ino); +out: + close(fd); + return -rc; } + static void signal_server(int sig) { if (sig == SIGINT) { do_disconnect("sigint", 1); exit(1); } else - fprintf(stderr, "%s: got signal %d\n", - jt_cmdname("sigint"), sig); + fprintf(stderr, "%s: got signal %d\n", jt_cmdname("sigint"), sig); } int obd_initialize(int argc, char **argv) { + int i; + + for (i = 0; i < MAX_STRIPES; i++) + lsm_buffer.lsm.lsm_oinfo[i] = lov_oinfos + i; + shmem_setup(); - register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH); + register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH, + OBD_DEV_MAJOR, OBD_DEV_MINOR); return 0; } - void obd_finalize(int argc, char **argv) { struct sigaction sigact; @@ -2477,10 +2524,709 @@ void obd_finalize(int argc, char **argv) sigact.sa_flags = SA_RESTART; sigaction(SIGINT, &sigact, NULL); - if (jt_recording) { - printf("END RECORD\n"); - jt_cfg_endrecord(argc, argv); + shmem_stop(); + do_disconnect(argv[0], 1); +} + +static int check_pool_cmd(enum lcfg_command_type cmd, + char *fsname, char *poolname, + char *ostname) +{ + int rc; + + rc = llapi_search_ost(fsname, poolname, ostname); + if (rc < 0 && (cmd != LCFG_POOL_NEW)) { + fprintf(stderr, "Pool %s.%s not found\n", + fsname, poolname); + return rc; } - do_disconnect(argv[0], 1); + switch (cmd) { + case LCFG_POOL_NEW: { + LASSERT(ostname == NULL); + if (rc >= 0) { + fprintf(stderr, "Pool %s.%s already exists\n", + fsname, poolname); + return -EEXIST; + } + return 0; + } + case LCFG_POOL_DEL: { + LASSERT(ostname == NULL); + if (rc == 1) { + fprintf(stderr, "Pool %s.%s not empty, " + "please remove all members\n", + fsname, poolname); + return -ENOTEMPTY; + } + return 0; + } + case LCFG_POOL_ADD: { + if (rc == 1) { + fprintf(stderr, "OST %s is already in pool %s.%s\n", + ostname, fsname, poolname); + return -EEXIST; + } + rc = llapi_search_ost(fsname, NULL, ostname); + if (rc == 0) { + fprintf(stderr, "OST %s is not part of the '%s' fs.\n", + ostname, fsname); + return -ENOENT; + } + return 0; + } + case LCFG_POOL_REM: { + if (rc == 0) { + fprintf(stderr, "OST %s not found in pool %s.%s\n", + ostname, fsname, poolname); + return -ENOENT; + } + return 0; + } + default: + break; + } /* switch */ + return -EINVAL; +} + +/* This check only verifies that the changes have been "pushed out" to + the client successfully. This involves waiting for a config update, + and so may fail because of problems in that code or post-command + network loss. So reporting a warning is appropriate, but not a failure. +*/ +static int check_pool_cmd_result(enum lcfg_command_type cmd, + char *fsname, char *poolname, + char *ostname) +{ + int cpt = 10; + int rc = 0; + + switch (cmd) { + case LCFG_POOL_NEW: { + do { + rc = llapi_search_ost(fsname, poolname, NULL); + if (rc == -ENODEV) + return rc; + if (rc < 0) + sleep(2); + cpt--; + } while ((rc < 0) && (cpt > 0)); + if (rc >= 0) { + fprintf(stderr, "Pool %s.%s created\n", + fsname, poolname); + return 0; + } else { + fprintf(stderr, "Warning, pool %s.%s not found\n", + fsname, poolname); + return -ENOENT; + } + } + case LCFG_POOL_DEL: { + do { + rc = llapi_search_ost(fsname, poolname, NULL); + if (rc == -ENODEV) + return rc; + if (rc >= 0) + sleep(2); + cpt--; + } while ((rc >= 0) && (cpt > 0)); + if (rc < 0) { + fprintf(stderr, "Pool %s.%s destroyed\n", + fsname, poolname); + return 0; + } else { + fprintf(stderr, "Warning, pool %s.%s still found\n", + fsname, poolname); + return -EEXIST; + } + } + case LCFG_POOL_ADD: { + do { + rc = llapi_search_ost(fsname, poolname, ostname); + if (rc == -ENODEV) + return rc; + if (rc != 1) + sleep(2); + cpt--; + } while ((rc != 1) && (cpt > 0)); + if (rc == 1) { + fprintf(stderr, "OST %s added to pool %s.%s\n", + ostname, fsname, poolname); + return 0; + } else { + fprintf(stderr, "Warning, OST %s not found in pool %s.%s\n", + ostname, fsname, poolname); + return -ENOENT; + } + } + case LCFG_POOL_REM: { + do { + rc = llapi_search_ost(fsname, poolname, ostname); + if (rc == -ENODEV) + return rc; + if (rc == 1) + sleep(2); + cpt--; + } while ((rc == 1) && (cpt > 0)); + if (rc != 1) { + fprintf(stderr, "OST %s removed from pool %s.%s\n", + ostname, fsname, poolname); + return 0; + } else { + fprintf(stderr, "Warning, OST %s still found in pool %s.%s\n", + ostname, fsname, poolname); + return -EEXIST; + } + } + default: + break; + } + return -EINVAL; } + +static int check_and_complete_ostname(char *fsname, char *ostname) +{ + char *ptr; + char real_ostname[MAX_OBD_NAME + 1]; + char i; + + /* if OST name does not start with fsname, we add it */ + /* if not check if the fsname is the right one */ + ptr = strchr(ostname, '-'); + if (ptr == NULL) { + sprintf(real_ostname, "%s-%s", fsname, ostname); + } else if (strncmp(ostname, fsname, strlen(fsname)) != 0) { + fprintf(stderr, "%s does not start with fsname %s\n", + ostname, fsname); + return -EINVAL; + } else { + strcpy(real_ostname, ostname); + } + /* real_ostname is fsname-????? */ + ptr = real_ostname + strlen(fsname) + 1; + if (strncmp(ptr, "OST", 3) != 0) { + fprintf(stderr, "%s does not start by %s-OST nor OST\n", + ostname, fsname); + return -EINVAL; + } + /* real_ostname is fsname-OST????? */ + ptr += 3; + for (i = 0; i < 4; i++) { + if (!isxdigit(*ptr)) { + fprintf(stderr, + "ost's index in %s is not an hexa number\n", + ostname); + return -EINVAL; + } + ptr++; + } + /* real_ostname is fsname-OSTXXXX????? */ + /* if OST name does not end with _UUID, we add it */ + if (*ptr == '\0') { + strcat(real_ostname, "_UUID"); + } else if (strcmp(ptr, "_UUID") != 0) { + fprintf(stderr, + "ostname %s does not end with _UUID\n", ostname); + return -EINVAL; + } + /* real_ostname is fsname-OSTXXXX_UUID */ + strcpy(ostname, real_ostname); + return 0; +} + +/* returns 0 or -errno */ +static int pool_cmd(enum lcfg_command_type cmd, + char *cmdname, char *fullpoolname, + char *fsname, char *poolname, char *ostname) +{ + int rc = 0; + struct obd_ioctl_data data; + struct lustre_cfg_bufs bufs; + struct lustre_cfg *lcfg; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + + rc = check_pool_cmd(cmd, fsname, poolname, ostname); + if (rc == -ENODEV) + fprintf(stderr, "Can't verify pool command since there " + "is no local MDT or client, proceeding anyhow...\n"); + else if (rc) + return rc; + + lustre_cfg_bufs_reset(&bufs, NULL); + lustre_cfg_bufs_set_string(&bufs, 0, cmdname); + lustre_cfg_bufs_set_string(&bufs, 1, fullpoolname); + if (ostname != NULL) + lustre_cfg_bufs_set_string(&bufs, 2, ostname); + + lcfg = lustre_cfg_new(cmd, &bufs); + if (IS_ERR(lcfg)) { + rc = PTR_ERR(lcfg); + return rc; + } + + memset(&data, 0x00, sizeof(data)); + rc = data.ioc_dev = get_mgs_device(); + if (rc < 0) + goto out; + + data.ioc_type = LUSTRE_CFG_TYPE; + data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, + lcfg->lcfg_buflens); + data.ioc_pbuf1 = (void *)lcfg; + + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(cmdname)); + return rc; + } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_POOL, buf); +out: + if (rc) + rc = -errno; + lustre_cfg_free(lcfg); + return rc; +} + +/* + * this function tranforms a rule [start-end/step] into an array + * of matching numbers + * supported forms are: + * [start] : just this number + * [start-end] : all numbers from start to end + * [start-end/step] : numbers from start to end with increment of step + * on return, format contains a printf format string which can be used + * to generate all the strings + */ +static int get_array_idx(char *rule, char *format, int **array) +{ + char *start, *end, *ptr; + unsigned int lo, hi, step; + int array_sz = 0; + int i, array_idx; + int rc; + + start = strchr(rule, '['); + end = strchr(rule, ']'); + if ((start == NULL) || (end == NULL)) { + *array = malloc(sizeof(int)); + if (*array == NULL) + return 0; + strcpy(format, rule); + array_sz = 1; + return array_sz; + } + *start = '\0'; + *end = '\0'; + end++; + start++; + /* put in format the printf format (the rule without the range) */ + sprintf(format, "%s%%.4x%s", rule, end); + + array_idx = 0; + array_sz = 0; + *array = NULL; + /* loop on , separator */ + do { + /* extract the 3 fields */ + rc = sscanf(start, "%x-%x/%u", &lo, &hi, &step); + switch (rc) { + case 0: { + return 0; + } + case 1: { + array_sz++; + *array = realloc(*array, array_sz * sizeof(int)); + if (*array == NULL) + return 0; + (*array)[array_idx] = lo; + array_idx++; + break; + } + case 2: { + step = 1; + /* do not break to share code with case 3: */ + } + case 3: { + if ((hi < lo) || (step == 0)) + return 0; + array_sz += (hi - lo) / step + 1; + *array = realloc(*array, sizeof(int) * array_sz); + if (*array == NULL) + return 0; + for (i = lo; i <= hi; i+=step, array_idx++) + (*array)[array_idx] = i; + break; + } + } + ptr = strchr(start, ','); + if (ptr != NULL) + start = ptr + 1; + + } while (ptr != NULL); + return array_sz; +} + +static int extract_fsname_poolname(char *arg, char *fsname, char *poolname) +{ + char *ptr; + int len; + int rc; + + strcpy(fsname, arg); + ptr = strchr(fsname, '.'); + if (ptr == NULL) { + fprintf(stderr, ". is missing in %s\n", fsname); + rc = -EINVAL; + goto err; + } + + len = ptr - fsname; + if (len == 0) { + fprintf(stderr, "fsname is empty\n"); + rc = -EINVAL; + goto err; + } + + len = strlen(ptr + 1); + if (len == 0) { + fprintf(stderr, "poolname is empty\n"); + rc = -EINVAL; + goto err; + } + if (len > LOV_MAXPOOLNAME) { + fprintf(stderr, + "poolname %s is too long (length is %d max is %d)\n", + ptr + 1, len, LOV_MAXPOOLNAME); + rc = -ENAMETOOLONG; + goto err; + } + strncpy(poolname, ptr + 1, LOV_MAXPOOLNAME); + poolname[LOV_MAXPOOLNAME] = '\0'; + *ptr = '\0'; + return 0; + +err: + fprintf(stderr, "argument %s must be .\n", arg); + return rc; +} + +int jt_pool_cmd(int argc, char **argv) +{ + enum lcfg_command_type cmd; + char fsname[PATH_MAX + 1]; + char poolname[LOV_MAXPOOLNAME + 1]; + char *ostnames_buf = NULL; + int i, rc; + int *array = NULL, array_sz; + struct { + int rc; + char *ostname; + } *cmds = NULL; + + switch (argc) { + case 0: + case 1: return CMD_HELP; + case 2: { + if (strcmp("pool_new", argv[0]) == 0) + cmd = LCFG_POOL_NEW; + else if (strcmp("pool_destroy", argv[0]) == 0) + cmd = LCFG_POOL_DEL; + else if (strcmp("pool_list", argv[0]) == 0) + return llapi_poollist(argv[1]); + else return CMD_HELP; + + rc = extract_fsname_poolname(argv[1], fsname, poolname); + if (rc) + break; + + rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); + if (rc) + break; + + check_pool_cmd_result(cmd, fsname, poolname, NULL); + break; + } + default: { + char format[2*MAX_OBD_NAME]; + + if (strcmp("pool_remove", argv[0]) == 0) { + cmd = LCFG_POOL_REM; + } else if (strcmp("pool_add", argv[0]) == 0) { + cmd = LCFG_POOL_ADD; + } else { + return CMD_HELP; + } + + rc = extract_fsname_poolname(argv[1], fsname, poolname); + if (rc) + break; + + for (i = 2; i < argc; i++) { + int j; + + array_sz = get_array_idx(argv[i], format, &array); + if (array_sz == 0) + return CMD_HELP; + + cmds = malloc(array_sz * sizeof(cmds[0])); + if (cmds != NULL) { + ostnames_buf = malloc(array_sz * + (MAX_OBD_NAME + 1)); + } else { + free(array); + rc = -ENOMEM; + goto out; + } + + for (j = 0; j < array_sz; j++) { + char ostname[MAX_OBD_NAME + 1]; + + snprintf(ostname, MAX_OBD_NAME, format, + array[j]); + ostname[MAX_OBD_NAME] = '\0'; + + rc = check_and_complete_ostname(fsname,ostname); + if (rc) { + free(array); + free(cmds); + if (ostnames_buf) + free(ostnames_buf); + goto out; + } + if (ostnames_buf != NULL) { + cmds[j].ostname = + &ostnames_buf[(MAX_OBD_NAME + 1) * j]; + strcpy(cmds[j].ostname, ostname); + } else { + cmds[j].ostname = NULL; + } + cmds[j].rc = pool_cmd(cmd, argv[0], argv[1], + fsname, poolname, + ostname); + /* Return an err if any of the add/dels fail */ + if (!rc) + rc = cmds[j].rc; + } + for (j = 0; j < array_sz; j++) { + if (!cmds[j].rc) { + char ostname[MAX_OBD_NAME + 1]; + + if (!cmds[j].ostname) { + snprintf(ostname, MAX_OBD_NAME, + format, array[j]); + ostname[MAX_OBD_NAME] = '\0'; + check_and_complete_ostname( + fsname, ostname); + } else { + strcpy(ostname, + cmds[j].ostname); + } + check_pool_cmd_result(cmd, fsname, + poolname,ostname); + } + } + if (array_sz > 0) + free(array); + if (cmds) + free(cmds); + if (ostnames_buf); + free(ostnames_buf); + } + /* fall through */ + } + } /* switch */ + +out: + if (rc != 0) { + errno = -rc; + perror(argv[0]); + } + + return rc; +} + +int jt_get_obj_version(int argc, char **argv) +{ + struct lu_fid fid; + struct obd_ioctl_data data; + __u64 version; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf, *fidstr; + int rc; + + if (argc != 2) + return CMD_HELP; + + fidstr = argv[1]; + while (*fidstr == '[') + fidstr++; + sscanf(fidstr, SFID, RFID(&fid)); + if (!fid_is_sane(&fid)) { + fprintf(stderr, "bad FID format [%s], should be "DFID"\n", + fidstr, (__u64)1, 2, 0); + return -EINVAL; + } + + memset(&data, 0, sizeof data); + data.ioc_dev = cur_device; + data.ioc_inlbuf1 = (char *) &fid; + data.ioc_inllen1 = sizeof fid; + data.ioc_inlbuf2 = (char *) &version; + data.ioc_inllen2 = sizeof version; + + memset(buf, 0, sizeof *buf); + rc = obd_ioctl_pack(&data, &buf, sizeof rawbuf); + if (rc) { + fprintf(stderr, "error: %s: packing ioctl arguments: %s\n", + jt_cmdname(argv[0]), strerror(-rc)); + return rc; + } + + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GET_OBJ_VERSION, buf); + if (rc == -1) { + fprintf(stderr, "error: %s: ioctl: %s\n", + jt_cmdname(argv[0]), strerror(errno)); + return -errno; + } + + obd_ioctl_unpack(&data, buf, sizeof rawbuf); + printf(LPX64"\n", version); + return 0; +} + +void llapi_ping_target(char *obd_type, char *obd_name, + char *obd_uuid, void *args) +{ + int rc; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + + memset(&data, 0, sizeof(data)); + data.ioc_inlbuf4 = obd_name; + data.ioc_inllen4 = strlen(obd_name) + 1; + data.ioc_dev = OBD_DEV_BY_DEVNAME; + memset(buf, 0, sizeof(rawbuf)); + if (obd_ioctl_pack(&data, &buf, sizeof(rawbuf))) { + fprintf(stderr, "error: invalid ioctl\n"); + return; + } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_PING_TARGET, buf); + if (rc) + rc = errno; + if (rc == ENOTCONN || rc == ESHUTDOWN) { + printf("%s inactive.\n", obd_name); + } else if (rc) { + fprintf(stderr, "error: check '%s' %s\n", + obd_name, strerror(errno)); + } else { + printf("%s active.\n", obd_name); + } +} + +int jt_changelog_register(int argc, char **argv) +{ + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data data; + char devname[30]; + int rc; + + if (argc > 2) + return CMD_HELP; + else if (argc == 2 && strcmp(argv[1], "-n") != 0) + return CMD_HELP; + if (cur_device < 0) + return CMD_HELP; + + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } + + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_REG, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); + return rc; + } + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + + if (data.ioc_u32_1 == 0) { + fprintf(stderr, "received invalid userid!\n"); + return EPROTO; + } + + if (lcfg_get_devname() != NULL) + strcpy(devname, lcfg_get_devname()); + else + sprintf(devname, "dev %d", cur_device); + + if (argc == 2) + /* -n means bare name */ + printf(CHANGELOG_USER_PREFIX"%u\n", data.ioc_u32_1); + else + printf("%s: Registered changelog userid '"CHANGELOG_USER_PREFIX + "%u'\n", devname, data.ioc_u32_1); + return 0; +} + +int jt_changelog_deregister(int argc, char **argv) +{ + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data data; + char devname[30]; + int id, rc; + + if (argc != 2 || cur_device < 0) + return CMD_HELP; + + id = strtol(argv[1] + strlen(CHANGELOG_USER_PREFIX), NULL, 10); + if ((id == 0) || (strncmp(argv[1], CHANGELOG_USER_PREFIX, + strlen(CHANGELOG_USER_PREFIX)) != 0)) { + fprintf(stderr, "expecting id of the form '" + CHANGELOG_USER_PREFIX"'; got '%s'\n", argv[1]); + return CMD_HELP; + } + + memset(&data, 0x00, sizeof(data)); + data.ioc_dev = cur_device; + data.ioc_u32_1 = id; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } + + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_DEREG, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); + return rc; + } + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + + if (data.ioc_u32_1 != id) { + fprintf(stderr, "No changelog user '%s'. Blocking user" + " is '"CHANGELOG_USER_PREFIX"%d'.\n", argv[1], + data.ioc_u32_1); + return ENOENT; + } + + if (lcfg_get_devname() != NULL) + strcpy(devname, lcfg_get_devname()); + else + sprintf(devname, "dev %d", cur_device); + + printf("%s: Deregistered changelog user '"CHANGELOG_USER_PREFIX"%d'\n", + devname, data.ioc_u32_1); + return 0; +} + +