X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fobd.c;h=20ec5f4fd8e1185215809eb0015a73bb52e2e027;hp=5a5bde337db4be4511e4489bac6c931b7d0f579b;hb=2d15edc7be83555a7fa17a666d99b6af4922ab82;hpb=665e36b780faa2144cecccd29a0d8a8196a76903 diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 5a5bde3..20ec5f4 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011, 2013, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -41,36 +41,39 @@ * Author: Robert Read */ -#include #include -#include #include +#include +#include #include +#include #include -#include -#include -#include -#include + #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "obdctl.h" - -#include /* for struct lov_stripe_md */ +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include - -#include #include #include -#include -#include +#include #define MAX_STRING_SIZE 128 #define DEVICES_LIST "/proc/fs/lustre/devices" @@ -80,16 +83,22 @@ #include #include -#define MAX_THREADS 1024 - +#define MAX_THREADS 4096 +#define MAX_BASE_ID 0xffffffff +#define NIDSTRING_LENGTH 64 struct shared_data { - __u64 counters[MAX_THREADS]; - __u64 offsets[MAX_THREADS]; - int running; - int barrier; - int stop; l_mutex_t mutex; l_cond_t cond; + int stopping; + struct { + __u64 counters[MAX_THREADS]; + __u64 offsets[MAX_THREADS]; + int thr_running; + int start_barrier; + int stop_barrier; + struct timeval start_time; + struct timeval end_time; + } body; }; static struct shared_data *shared_data; @@ -103,61 +112,32 @@ const int thread = 0; const int nthreads = 1; #endif -static char rawbuf[8192]; -static char *buf = rawbuf; -static int max = sizeof(rawbuf); - static int cur_device = -1; -#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) { 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 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; - IOC_INIT(data); + memset(&data, 0, 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; - 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 = l_ioctl(dev_id, OBD_IOC_PROCESS_CFG, buf); @@ -190,9 +170,10 @@ static int get_mgs_device() int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); rc = data.ioc_dev = get_mgs_device(); if (rc < 0) goto out; @@ -200,33 +181,37 @@ int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg) data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens); data.ioc_pbuf1 = (void *)lcfg; - 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 = l_ioctl(dev_id, OBD_IOC_PARAM, buf); out: if (rc) { if (errno == ENOSYS) fprintf(stderr, "Make sure cfg_device is set first.\n"); - if (errno == EINVAL) - fprintf(stderr, "cfg_device should be of the form " - "'lustre-MDT0000'\n"); } return rc; } char *obdo_print(struct obdo *obd) { - char buf[1024]; - - sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64 - "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64 - "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n" - "misc: %x\nnlink: %d,\nvalid "LPX64"\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_misc, - obd->o_nlink, obd->o_valid); - return strdup(buf); + char buf[1024]; + + sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64 + "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64 + "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n" + "misc: %x\nnlink: %d,\nvalid "LPX64"\n", + ostid_id(&obd->o_oi), ostid_seq(&obd->o_oi), 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_misc, + obd->o_nlink, obd->o_valid); + return strdup(buf); } @@ -237,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, 0, 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 < 0) { + 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; } @@ -275,80 +272,12 @@ int parse_devname(char *func, char *name) // printf("Name %s is device %d\n", name, ret); } else { fprintf(stderr, "No device found for name %s: %s\n", - name, strerror(rc)); + name, strerror(rc)); } } return ret; } -static void -reset_lsmb (struct lsm_buffer *lsmb) -{ - memset (&lsmb->lsm, 0, sizeof (lsmb->lsm)); - memset(lov_oinfos, 0, sizeof(lov_oinfos)); - lsmb->lsm.lsm_magic = LOV_MAGIC; -} - -static int -parse_lsm (struct lsm_buffer *lsmb, char *string) -{ - struct lov_stripe_md *lsm = &lsmb->lsm; - char *end; - int i; - - /* - * object_id[=size#count[@offset:id]*] - */ - - reset_lsmb (lsmb); - - lsm->lsm_object_id = strtoull (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string == 0) - return (0); - - if (*string != '=') - return (-1); - string++; - - lsm->lsm_stripe_size = strtoul (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string != '#') - return (-1); - string++; - - lsm->lsm_stripe_count = strtoul (string, &end, 0); - if (end == string) - return (-1); - string = end; - - if (*string == 0) /* don't have to specify obj ids */ - return (0); - - for (i = 0; i < lsm->lsm_stripe_count; i++) { - if (*string != '@') - return (-1); - string++; - 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); - string = end; - } - - if (*string != 0) - return (-1); - - return (0); -} - char *jt_cmdname(char *func) { static char buf[512]; @@ -434,15 +363,19 @@ int do_disconnect(char *func, int verbose) } #ifdef MAX_THREADS -static void shmem_setup(void) +static int shmem_setup(void) { - /* Create new segment */ - int shmid = shmget(IPC_PRIVATE, sizeof(*shared_data), 0600); + pthread_mutexattr_t mattr; + pthread_condattr_t cattr; + int rc; + int shmid; + /* Create new segment */ + shmid = shmget(IPC_PRIVATE, sizeof(*shared_data), 0600); if (shmid == -1) { fprintf(stderr, "Can't create shared data: %s\n", strerror(errno)); - return; + return errno; } /* Attatch to new segment */ @@ -452,7 +385,7 @@ static void shmem_setup(void) fprintf(stderr, "Can't attach shared data: %s\n", strerror(errno)); shared_data = NULL; - return; + return errno; } /* Mark segment as destroyed, so it will disappear when we exit. @@ -461,7 +394,31 @@ static void shmem_setup(void) if (shmctl(shmid, IPC_RMID, NULL) == -1) { fprintf(stderr, "Can't destroy shared data: %s\n", strerror(errno)); + return errno; } + + pthread_mutexattr_init(&mattr); + pthread_condattr_init(&cattr); + + rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + if (rc != 0) { + fprintf(stderr, "Can't set shared mutex attr\n"); + goto out; + } + + rc = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); + if (rc != 0) { + fprintf(stderr, "Can't set shared cond attr\n"); + goto out; + } + + pthread_mutex_init(&shared_data->mutex, &mattr); + pthread_cond_init(&shared_data->cond, &cattr); +out: + pthread_mutexattr_destroy(&mattr); + pthread_condattr_destroy(&cattr); + + return rc; } static inline void shmem_lock(void) @@ -474,32 +431,66 @@ static inline void shmem_unlock(void) l_mutex_unlock(&shared_data->mutex); } +static inline void shmem_wait(void) +{ + l_cond_wait(&shared_data->cond, &shared_data->mutex); +} + +static inline void shmem_wakeup_all(void) +{ + l_cond_broadcast(&shared_data->cond); +} + static inline void shmem_reset(int total_threads) { if (shared_data == NULL) return; - memset(shared_data, 0, sizeof(*shared_data)); - l_mutex_init(&shared_data->mutex); - l_cond_init(&shared_data->cond); + memset(&shared_data->body, 0, sizeof(shared_data->body)); memset(counter_snapshot, 0, sizeof(counter_snapshot)); prev_valid = 0; - shared_data->barrier = total_threads; + shared_data->stopping = 0; + shared_data->body.start_barrier = total_threads; + shared_data->body.stop_barrier = total_threads; } -static inline void shmem_bump(void) +static inline void shmem_bump(__u32 counter) { - static int bumped_running; + static bool running_not_bumped = true; if (shared_data == NULL || thread <= 0 || thread > MAX_THREADS) return; shmem_lock(); - shared_data->counters[thread - 1]++; - if (!bumped_running) - shared_data->running++; + shared_data->body.counters[thread - 1] += counter; + if (running_not_bumped) { + shared_data->body.thr_running++; + running_not_bumped = false; + } + shmem_unlock(); +} + +static void shmem_total(int total_threads) +{ + __u64 total = 0; + double secs; + int i; + + if (shared_data == NULL || total_threads > MAX_THREADS) + return; + + shmem_lock(); + for (i = 0; i < total_threads; i++) + total += shared_data->body.counters[i]; + + secs = difftime(&shared_data->body.end_time, + &shared_data->body.start_time); shmem_unlock(); - bumped_running = 1; + + printf("Total: total "LPU64" threads %d sec %f %f/second\n", + total, total_threads, secs, total / secs); + + return; } static void shmem_snap(int total_threads, int live_threads) @@ -515,9 +506,9 @@ static void shmem_snap(int total_threads, int live_threads) return; shmem_lock(); - memcpy(counter_snapshot[0], shared_data->counters, + memcpy(counter_snapshot[0], shared_data->body.counters, total_threads * sizeof(counter_snapshot[0][0])); - running = shared_data->running; + running = shared_data->body.thr_running; shmem_unlock(); gettimeofday(&this_time, NULL); @@ -532,13 +523,10 @@ 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); - - 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); + secs = difftime(&this_time, &prev_time); + if (prev_valid && secs > 1.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])); @@ -553,24 +541,54 @@ static void shmem_stop(void) if (shared_data == NULL) return; - shared_data->stop = 1; + shared_data->stopping = 1; +} + +static void shmem_cleanup(void) +{ + if (shared_data == NULL) + return; + + shmem_stop(); + + pthread_mutex_destroy(&shared_data->mutex); + pthread_cond_destroy(&shared_data->cond); } static int shmem_running(void) { - return (shared_data == NULL || - !shared_data->stop); + return (shared_data == NULL || !shared_data->stopping); +} + +static void shmem_end_time_locked(void) +{ + shared_data->body.stop_barrier--; + if (shared_data->body.stop_barrier == 0) + gettimeofday(&shared_data->body.end_time, NULL); +} + +static void shmem_start_time_locked(void) +{ + shared_data->body.start_barrier--; + if (shared_data->body.start_barrier == 0) { + shmem_wakeup_all(); + gettimeofday(&shared_data->body.start_time, NULL); + } else { + shmem_wait(); + } } + #else -static void shmem_setup(void) +static int shmem_setup(void) { + return 0; } static inline void shmem_reset(int total_threads) { } -static inline void shmem_bump(void) +static inline void shmem_bump(__u32 counters) { } @@ -582,7 +600,7 @@ static void shmem_unlock() { } -static void shmem_stop(void) +static void shmem_cleanup(void) { } @@ -718,7 +736,7 @@ int jt_opt_threads(int argc, char **argv) thread = i; argv[2] = "--device"; - return jt_opt_device(argc - 2, argv + 2); + exit(jt_opt_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); @@ -788,6 +806,7 @@ int jt_opt_threads(int argc, char **argv) sigaction(SIGALRM, &saveact1, NULL); } + shmem_total(threads); sigprocmask(SIG_SETMASK, &saveset, NULL); return rc; @@ -823,14 +842,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, 0, 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]), @@ -842,14 +869,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, 0, 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]), @@ -861,14 +896,22 @@ 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, 0, 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_ABORT_RECOVERY, buf); if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -880,34 +923,22 @@ int jt_obd_abort_recovery(int argc, char **argv) int jt_get_version(int argc, char **argv) { int rc; - char buf[8192]; - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; + char rawbuf[MAX_IOC_BUFLEN]; + char *version; if (argc != 1) return CMD_HELP; - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - data->ioc_inlbuf1 = buf + size_round(sizeof(*data)); - data->ioc_len = obd_ioctl_packlen(data); - - rc = l2_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf); - if (rc < 0) + rc = llapi_get_version(rawbuf, MAX_IOC_BUFLEN, &version); + if (rc) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), - strerror(rc = errno)); - else { - printf("Lustre version: %s\n", data->ioc_bulk); - } + strerror(-rc)); + else + printf("Lustre version: %s\n", version); - printf("lctl version: %s\n", BUILD_VERSION); - return rc; + return rc; } -/* - * Print an obd device line with the ost_conn_uuid inserted, if the obd - * is an osc. - */ static void print_obd_line(char *s) { char buf[MAX_STRING_SIZE]; @@ -915,7 +946,9 @@ static void print_obd_line(char *s) FILE *fp = NULL; char *ptr; - if (sscanf(s, " %*d %*s osc %s %*s %*d ", obd_name) == 0) + snprintf(buf, sizeof(buf), " %%*d %%*s osc %%%zus %%*s %%*d ", + sizeof(obd_name) - 1); + if (sscanf(s, buf, obd_name) == 0) goto try_mdc; snprintf(buf, sizeof(buf), "/proc/fs/lustre/osc/%s/ost_conn_uuid", obd_name); @@ -924,7 +957,9 @@ static void print_obd_line(char *s) goto got_one; try_mdc: - if (sscanf(s, " %*d %*s mdc %s %*s %*d ", obd_name) == 0) + snprintf(buf, sizeof(buf), " %%*d %%*s mdc %%%zus %%*s %%*d ", + sizeof(obd_name) - 1); + if (sscanf(s, buf, obd_name) == 0) goto fail; snprintf(buf, sizeof(buf), "/proc/fs/lustre/mdc/%s/mds_conn_uuid", obd_name); @@ -932,7 +967,12 @@ try_mdc: goto fail; got_one: - fgets(buf, sizeof(buf), fp); + /* 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); /* trim trailing newlines */ @@ -953,7 +993,7 @@ fail: int jt_obd_list_ioctl(int argc, char **argv) { int rc, index; - char buf[8192]; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; if (argc > 2) @@ -963,10 +1003,11 @@ int jt_obd_list_ioctl(int argc, char **argv) return CMD_HELP; for (index = 0;; index++) { - 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_inlbuf1 = 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); data->ioc_count = index; @@ -981,8 +1022,7 @@ int jt_obd_list_ioctl(int argc, char **argv) rc = 0; else fprintf(stderr, "Error getting device list: %s: " - "check dmesg.\n", - strerror(errno)); + "check dmesg.\n", strerror(errno)); } return rc; } @@ -1020,116 +1060,485 @@ int jt_obd_list(int argc, char **argv) return 0; } +struct jt_fid_space { + obd_seq jt_seq; + obd_id jt_id; + int jt_width; +}; +int jt_obd_alloc_fids(struct jt_fid_space *space, struct lu_fid *fid, + __u64 *count) +{ + int rc; + if (space->jt_seq == 0 || space->jt_id == space->jt_width) { + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN]; + char *buf = rawbuf; + __u64 seqnr; + int max_count; -/* Create one or more objects, arg[4] may describe stripe meta-data. If - * not, defaults assumed. This echo-client instance stashes the stripe - * 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) -{ - 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; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - IOC_INIT(data); - if (argc < 2 || argc > 5) - return CMD_HELP; + data.ioc_pbuf1 = (char *)&seqnr; + data.ioc_plen1 = sizeof(seqnr); - count = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid iteration count '%s'\n", - jt_cmdname(argv[0]), argv[1]); - return CMD_HELP; - } + data.ioc_pbuf2 = (char *)&max_count; + data.ioc_plen2 = sizeof(max_count); - if (argc > 2) { - mode = strtoul(argv[2], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid mode '%s'\n", - jt_cmdname(argv[0]), argv[2]); - return CMD_HELP; + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: invalid ioctl rc = %d\n", rc); + return rc; } - if (!(mode & S_IFMT)) - mode |= S_IFREG; - } - - if (argc > 3) { - verbose = get_verbose(argv[0], argv[3]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } - if (argc < 5) - reset_lsmb (&lsm_buffer); /* will set default */ - else { - rc = parse_lsm (&lsm_buffer, argv[4]); - if (rc != 0) { - fprintf(stderr, "error: %s: invalid lsm '%s'\n", - jt_cmdname(argv[0]), argv[4]); - return CMD_HELP; + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_ALLOC_SEQ, buf); + if (rc) { + fprintf(stderr, "ioctl error: rc = %d\n", rc); + return rc; } - base_id = lsm_buffer.lsm.lsm_object_id; - valid_lsm = 1; + + space->jt_seq = *(__u64 *)data.ioc_pbuf1; + space->jt_width = *(int *)data.ioc_pbuf2; + space->jt_id = 1; } + fid->f_seq = space->jt_seq; + fid->f_oid = space->jt_id; + fid->f_ver = 0; - printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count); - gettimeofday(&next_time, NULL); - next_time.tv_sec -= verbose; + space->jt_id = min(space->jt_id + *count, space->jt_width); - 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; - data.ioc_obdo1.o_gid = 0; - data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID; - - if (valid_lsm) { - data.ioc_plen1 = sizeof lsm_buffer; - data.ioc_pbuf1 = (char *)&lsm_buffer; - } + *count = space->jt_id - fid->f_oid; + return 0; +} - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf); - IOC_UNPACK(argv[0], data); - shmem_bump(); - if (rc < 0) { - fprintf(stderr, "error: %s: #%d - %s\n", - jt_cmdname(argv[0]), i, strerror(rc = errno)); +#define MD_STEP_COUNT 1000 +int jt_obd_md_common(int argc, char **argv, int cmd) +{ + struct obd_ioctl_data data; + struct timeval start; + struct timeval end_time; + char rawbuf[MAX_IOC_BUFLEN]; + char *buf = rawbuf; + int mode = 0000644; + int create_mode; + int rc = 0; + char *parent_basedir = NULL; + char dirname[4096]; + int parent_base_id = 0; + int parent_count = 1; + __u64 child_base_id = -1; + int stripe_count = 0; + int stripe_index = -1; + int count = 0; + char *end; + __u64 seconds = 0; + double diff; + int c; + __u64 total_count = 0; + char *name = NULL; + struct jt_fid_space fid_space = {0}; + int version = 0; + struct option long_opts[] = { + {"child_base_id", required_argument, 0, 'b'}, + {"stripe_count", required_argument, 0, 'c'}, + {"parent_basedir", required_argument, 0, 'd'}, + {"parent_dircount", required_argument, 0, 'D'}, + {"stripe_index", required_argument, 0, 'i'}, + {"mode", required_argument, 0, 'm'}, + {"count", required_argument, 0, 'n'}, + {"time", required_argument, 0, 't'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + + optind = 0; + while ((c = getopt_long(argc, argv, "b:c:d:D:m:n:t:v", + long_opts, NULL)) >= 0) { + switch (c) { + case 'b': + child_base_id = strtoull(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: bad child_base_id" + " '%s'\n", jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } break; - } - if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) { - fprintf(stderr,"error: %s: oid not valid #%d:"LPX64"\n", - jt_cmdname(argv[0]), i, data.ioc_obdo1.o_valid); - rc = EINVAL; + case 'c': + stripe_count = strtoul(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: bad stripe count" + " '%s'\n", jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } + break; + case 'd': + parent_basedir = optarg; + break; + case 'D': + parent_count = strtoul(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: bad parent count" + " '%s'\n", jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } + break; + case 'i': + stripe_index = strtoul(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: bad stripe index" + " '%s'\n", jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } + break; + case 'm': + mode = strtoul(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: bad mode '%s'\n", + jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } + break; + case 'n': + total_count = strtoul(optarg, &end, 0); + if (*end || total_count == 0) { + fprintf(stderr, "%s: bad child count '%s'\n", + jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } break; + case 't': + seconds = strtoull(optarg, &end, 0); + if (*end) { + fprintf(stderr, "error: %s: seconds '%s'\n", + jt_cmdname(argv[0]), optarg); + return CMD_HELP; + } + break; + case 'v': + version = 1; + break; + default: + fprintf(stderr, "error: %s: option '%s' " + "unrecognized\n", argv[0], argv[optind - 1]); + return CMD_HELP; } + } - if (be_verbose(verbose, &next_time, i, &next_count, count)) - printf("%s: #%d is object id "LPX64"\n", - jt_cmdname(argv[0]), i, data.ioc_obdo1.o_id); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (child_base_id == -1) { + if (optind >= argc) + return CMD_HELP; + name = argv[optind]; + total_count = 1; + } else { + if (optind < argc) { + fprintf(stderr, "child_base_id and name can not" + " specified at the same time\n"); + return CMD_HELP; + } } - return rc; -} -int jt_obd_setattr(int argc, char **argv) -{ - struct obd_ioctl_data data; - char *end; - int rc; + if (stripe_count == 0 && stripe_index != -1) { + fprintf(stderr, "If stripe_count is 0, stripe_index can not" + "be specified\n"); + return CMD_HELP; + } - IOC_INIT(data); - if (argc != 2) + if (total_count == 0 && seconds == 0) { + fprintf(stderr, "count or seconds needs to be indicated\n"); return CMD_HELP; + } - data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); - if (*end) { + if (parent_count <= 0) { + fprintf(stderr, "parent count must < 0\n"); + return CMD_HELP; + } + +#ifdef MAX_THREADS + if (thread) { + shmem_lock(); + /* threads interleave */ + if (parent_base_id != -1) + parent_base_id += (thread - 1) % parent_count; + + if (child_base_id != -1) + child_base_id += (thread - 1) * \ + (MAX_BASE_ID / nthreads); + + shmem_start_time_locked(); + shmem_unlock(); + } +#endif + /* If parent directory is not specified, try to get the directory + * from name */ + if (parent_basedir == NULL) { + char *last_lash; + if (name == NULL) { + fprintf(stderr, "parent_basedir or name must be" + "indicated!\n"); + return CMD_HELP; + } + /*Get directory and name from name*/ + last_lash = strrchr(name, '/'); + if (last_lash == NULL || name[0] != '/') { + fprintf(stderr, "Can not locate %s\n", name); + return CMD_HELP; + } + + if (last_lash == name) { + sprintf(dirname, "%s", "/"); + name++; + } else { + int namelen = (unsigned long)last_lash - + (unsigned long)name + 1; + snprintf(dirname, namelen, "%s", name); + name = last_lash + 1; + } + + data.ioc_pbuf1 = dirname; + data.ioc_plen1 = strlen(dirname); + + data.ioc_pbuf2 = name; + data.ioc_plen2 = strlen(name); + } else { + if (name != NULL) { + data.ioc_pbuf2 = name; + data.ioc_plen2 = strlen(name); + } + if (parent_base_id > 0) + sprintf(dirname, "%s%d", parent_basedir, + parent_base_id); + else + sprintf(dirname, "%s", parent_basedir); + data.ioc_pbuf1 = dirname; + data.ioc_plen1 = strlen(dirname); + } + + if (cmd == ECHO_MD_MKDIR || cmd == ECHO_MD_RMDIR) + create_mode = S_IFDIR; + else + create_mode = S_IFREG; + + data.ioc_obdo1.o_mode = mode | S_IFDIR; + data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | + OBD_MD_FLFLAGS | OBD_MD_FLGROUP; + data.ioc_command = cmd; + + gettimeofday(&start, NULL); + while (shmem_running()) { + struct lu_fid fid = { 0 }; + + if (child_base_id != -1) + data.ioc_obdo2.o_oi.oi.oi_id = child_base_id; + data.ioc_obdo2.o_mode = mode | create_mode; + data.ioc_obdo2.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | + OBD_MD_FLMODE | OBD_MD_FLFLAGS | + OBD_MD_FLGROUP; + data.ioc_obdo2.o_misc = stripe_count; + data.ioc_obdo2.o_stripe_idx = stripe_index; + + if (total_count > 0) { + if ((total_count - count) > MD_STEP_COUNT) + data.ioc_count = MD_STEP_COUNT; + else + data.ioc_count = total_count - count; + } else { + data.ioc_count = MD_STEP_COUNT; + } + + if (cmd == ECHO_MD_CREATE || cmd == ECHO_MD_MKDIR) { + /*Allocate fids for the create */ + rc = jt_obd_alloc_fids(&fid_space, &fid, + &data.ioc_count); + if (rc) { + fprintf(stderr, "Allocate fids error %d.\n",rc); + return rc; + } + fid_to_ostid(&fid, &data.ioc_obdo1.o_oi); + } + + child_base_id += data.ioc_count; + count += data.ioc_count; + + memset(buf, 0, sizeof(rawbuf)); + rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl %d\n", + jt_cmdname(argv[0]), rc); + return rc; + } + + rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_MD, buf); + if (rc) { + fprintf(stderr, "error: %s: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + return rc; + } + shmem_bump(data.ioc_count); + + gettimeofday(&end_time, NULL); + diff = difftime(&end_time, &start); + if (seconds > 0 && (__u64)diff > seconds) + break; + + if (count >= total_count && total_count > 0) + break; + } + + if (count > 0 && version) { + gettimeofday(&end_time, NULL); + diff = difftime(&end_time, &start); + printf("%s: %d in %.3fs (%.3f /s): %s", + jt_cmdname(argv[0]), count, diff, + (double)count/diff, ctime(&end_time.tv_sec)); + } + +#ifdef MAX_THREADS + if (thread) { + shmem_lock(); + shmem_end_time_locked(); + shmem_unlock(); + } +#endif + return rc; +} + +int jt_obd_test_create(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_CREATE); +} + +int jt_obd_test_mkdir(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_MKDIR); +} + +int jt_obd_test_destroy(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_DESTROY); +} + +int jt_obd_test_rmdir(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_RMDIR); +} + +int jt_obd_test_lookup(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_LOOKUP); +} + +int jt_obd_test_setxattr(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_SETATTR); +} + +int jt_obd_test_md_getattr(int argc, char **argv) +{ + return jt_obd_md_common(argc, argv, ECHO_MD_GETATTR); +} + +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 = 1; + int verbose = 1, mode = 0100644, rc = 0, i; + char *end; + + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (argc < 2 || argc > 4) + return CMD_HELP; + + count = strtoull(argv[1], &end, 0); + if (*end) { + fprintf(stderr, "error: %s: invalid iteration count '%s'\n", + jt_cmdname(argv[0]), argv[1]); + return CMD_HELP; + } + + if (argc > 2) { + mode = strtoul(argv[2], &end, 0); + if (*end) { + fprintf(stderr, "error: %s: invalid mode '%s'\n", + jt_cmdname(argv[0]), argv[2]); + return CMD_HELP; + } + if (!(mode & S_IFMT)) + mode |= S_IFREG; + } + + if (argc > 3) { + verbose = get_verbose(argv[0], argv[3]); + if (verbose == BAD_VERBOSE) + return CMD_HELP; + } + + printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count); + gettimeofday(&next_time, NULL); + next_time.tv_sec -= verbose; + + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { + data.ioc_obdo1.o_mode = mode; + ostid_set_id(&data.ioc_obdo1.o_oi, base_id); + data.ioc_obdo1.o_uid = 0; + data.ioc_obdo1.o_gid = 0; + data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | + OBD_MD_FLID | OBD_MD_FLUID | + OBD_MD_FLGID | OBD_MD_FLGROUP; + + 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); + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + shmem_bump(1); + if (rc < 0) { + fprintf(stderr, "error: %s: #%d - %s\n", + jt_cmdname(argv[0]), i, strerror(rc = errno)); + break; + } + if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) { + fprintf(stderr,"error: %s: oid not valid #%d:"LPX64"\n", + jt_cmdname(argv[0]), i, data.ioc_obdo1.o_valid); + rc = EINVAL; + break; + } + + if (be_verbose(verbose, &next_time, i, &next_count, count)) + printf("%s: #%d is object id "LPX64"\n", + jt_cmdname(argv[0]), i, + ostid_id(&data.ioc_obdo1.o_oi)); + } + return rc; +} + +int jt_obd_setattr(int argc, char **argv) +{ + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + char *end; + int rc; + + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (argc != 2) + return CMD_HELP; + + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); + ostid_set_id(&data.ioc_obdo1.o_oi, strtoull(argv[1], &end, 0)); + if (*end) { fprintf(stderr, "error: %s: invalid objid '%s'\n", jt_cmdname(argv[0]), argv[1]); return CMD_HELP; @@ -1142,7 +1551,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]), @@ -1156,6 +1571,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; @@ -1164,7 +1580,8 @@ int jt_obd_test_setattr(int argc, char **argv) if (argc < 2 || argc > 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; count = strtoull(argv[1], &end, 0); if (*end) { fprintf(stderr, "error: %s: invalid iteration count '%s'\n", @@ -1199,13 +1616,20 @@ 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)); + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { - data.ioc_obdo1.o_id = objid; + ostid_set_id(&data.ioc_obdo1.o_oi, 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, 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, &data); - shmem_bump(); + shmem_bump(1); if (rc < 0) { fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n", jt_cmdname(argv[0]), i, errno, strerror(rc = errno)); @@ -1239,13 +1663,15 @@ 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, 0, sizeof(data)); + data.ioc_dev = cur_device; if (argc < 2 || argc > 4) return CMD_HELP; @@ -1275,15 +1701,22 @@ int jt_obd_destroy(int argc, char **argv) gettimeofday(&next_time, NULL); next_time.tv_sec -= verbose; + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); 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; + ostid_set_id(&data.ioc_obdo1.o_oi, 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); - shmem_bump(); + obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + shmem_bump(1); if (rc < 0) { fprintf(stderr, "error: %s: objid "LPX64": %s\n", jt_cmdname(argv[0]), id, strerror(rc = errno)); @@ -1301,33 +1734,43 @@ 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); - data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - jt_cmdname(argv[0]), argv[1]); - return CMD_HELP; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); + ostid_set_id(&data.ioc_obdo1.o_oi, strtoull(argv[1], &end, 0)); + if (*end) { + fprintf(stderr, "error: %s: invalid objid '%s'\n", + jt_cmdname(argv[0]), argv[1]); + return CMD_HELP; + } + /* to help obd filter */ + data.ioc_obdo1.o_mode = 0100644; + data.ioc_obdo1.o_valid = 0xffffffff; + printf("%s: object id "LPX64"\n", jt_cmdname(argv[0]), + ostid_id(&data.ioc_obdo1.o_oi)); + + 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; } - /* to help obd filter */ - data.ioc_obdo1.o_mode = 0100644; - 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); 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)); } else { - printf("%s: object id "LPX64", mode %o\n", jt_cmdname(argv[0]), - data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode); + printf("%s: object id "LPU64", mode %o\n", jt_cmdname(argv[0]), + ostid_id(&data.ioc_obdo1.o_oi), data.ioc_obdo1.o_mode); } return rc; } @@ -1336,6 +1779,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; @@ -1345,7 +1789,8 @@ int jt_obd_test_getattr(int argc, char **argv) if (argc < 2 || argc > 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; count = strtoull(argv[1], &end, 0); if (*end) { fprintf(stderr, "error: %s: invalid iteration count '%s'\n", @@ -1380,13 +1825,20 @@ 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)); + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); 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 = 0xffffffff; - IOC_PACK(argv[0], data); + ostid_set_id(&data.ioc_obdo1.o_oi, objid); + data.ioc_obdo1.o_mode = S_IFREG; + data.ioc_obdo1.o_valid = 0xffffffff; + 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, &data); - shmem_bump(); + shmem_bump(1); if (rc < 0) { fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n", jt_cmdname(argv[0]), i, errno, strerror(rc = errno)); @@ -1426,6 +1878,7 @@ 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; @@ -1516,7 +1969,8 @@ int jt_obd_test_brw(int argc, char **argv) } } - IOC_INIT(data); + memset(&data, 0, 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 @@ -1563,31 +2017,29 @@ int jt_obd_test_brw(int argc, char **argv) obj_idx = (thread - 1)/nthr_per_obj; objid += obj_idx; stride *= nthr_per_obj; - if (thread == 1) - shared_data->offsets[obj_idx] = stride + thr_offset; + if ((thread - 1) % nthr_per_obj == 0) { + shared_data->body.offsets[obj_idx] = + stride + thr_offset; + } thr_offset += ((thread - 1) % nthr_per_obj) * len; } else { /* threads disjoint */ thr_offset += (thread - 1) * len; } - shared_data->barrier--; - if (shared_data->barrier == 0) - l_cond_broadcast(&shared_data->cond); - else - l_cond_wait(&shared_data->cond, - &shared_data->mutex); - + shmem_start_time_locked(); 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); + ostid_set_seq_echo(&data.ioc_obdo1.o_oi); + ostid_set_id(&data.ioc_obdo1.o_oi, 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 | OBD_MD_FLGROUP; + data.ioc_obdo1.o_flags = (verify ? OBD_FL_DEBUG_CHECK : 0); + data.ioc_count = len; + data.ioc_offset = (repeat_offset ? 0 : thr_offset); gettimeofday(&start, NULL); next_time.tv_sec = start.tv_sec - verbose; @@ -1601,21 +2053,27 @@ int jt_obd_test_brw(int argc, char **argv) cmd = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ; 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, 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, cmd, buf); - shmem_bump(); + shmem_bump(1); if (rc) { fprintf(stderr, "error: %s: #%d - %s on %s\n", jt_cmdname(argv[0]), i, strerror(rc = errno), write ? "write" : "read"); break; } 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 * getpagesize())); - shmem_unlock (); + shmem_lock (); + printf("%s: %s number %d @ "LPD64":"LPU64" for %d\n", + jt_cmdname(argv[0]), write ? "write" : "read", i, + ostid_id(&data.ioc_obdo1.o_oi), data.ioc_offset, + (int)(pages * getpagesize())); + shmem_unlock (); } if (!repeat_offset) { @@ -1624,8 +2082,9 @@ int jt_obd_test_brw(int argc, char **argv) data.ioc_offset += stride; } else if (i < count) { shmem_lock (); - data.ioc_offset = shared_data->offsets[obj_idx]; - shared_data->offsets[obj_idx] += len; + data.ioc_offset = + shared_data->body.offsets[obj_idx]; + shared_data->body.offsets[obj_idx] += len; shmem_unlock (); } #else @@ -1653,6 +2112,13 @@ int jt_obd_test_brw(int argc, char **argv) ctime(&end.tv_sec)); } +#ifdef MAX_THREADS + if (thread) { + shmem_lock(); + shmem_end_time_locked(); + shmem_unlock(); + } +#endif return rc; } @@ -1661,11 +2127,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, 0, sizeof(data)); + data.ioc_dev = cur_device; if (argc != 2) return CMD_HELP; @@ -1683,7 +2151,6 @@ int jt_obd_lov_getconfig(int argc, char **argv) desc.ld_tgt_count = ((OBD_MAX_IOCTL_BUFFER-sizeof(data)-sizeof(desc)) / (sizeof(*uuidarray) + sizeof(*obdgens))); - repeat: uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); if (!uuidarray) { @@ -1700,6 +2167,7 @@ repeat: goto out_uuidarray; } + memset(buf, 0, sizeof(rawbuf)); data.ioc_inllen1 = sizeof(desc); data.ioc_inlbuf1 = (char *)&desc; data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); @@ -1707,7 +2175,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; @@ -1726,7 +2194,7 @@ 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; @@ -1758,70 +2226,27 @@ out: return rc; } -int jt_obd_ldlm_regress_start(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - char argstring[200]; - int i, count = sizeof(argstring) - 1; - - IOC_INIT(data); - if (argc > 5) - return CMD_HELP; - - argstring[0] = '\0'; - for (i = 1; i < argc; i++) { - strncat(argstring, " ", count); - count--; - strncat(argstring, argv[i], count); - count -= strlen(argv[i]); - } - - if (strlen(argstring)) { - data.ioc_inlbuf1 = argstring; - data.ioc_inllen1 = strlen(argstring) + 1; - } - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf); - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - - return rc; -} - -int jt_obd_ldlm_regress_stop(int argc, char **argv) -{ - int rc; - struct obd_ioctl_data data; - IOC_INIT(data); - - if (argc != 1) - return CMD_HELP; - - IOC_PACK(argv[0], data); - rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf); - - if (rc) - fprintf(stderr, "error: %s: test failed: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - return rc; -} - 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, 0, 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", @@ -1830,6 +2255,56 @@ static int do_activate(int argc, char **argv, int flag) return rc; } +/** + * Replace nids for given device. + * lctl replace_nids [,nid2,nid3] + * Command should be started on MGS server. + * Only MGS server should be started (command execution + * returns error in another cases). Command mount + * -t lustre -o nosvc + * can be used for that. + * + * llogs for MDTs and clients are processed. All + * records copied as is except add_uuid and setup. This records + * are skipped and recorded with new nids and uuid. + * + * \see mgs_replace_nids + * \see mgs_replace_nids_log + * \see mgs_replace_handler + */ +int jt_replace_nids(int argc, char **argv) +{ + int rc; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data data; + + memset(&data, 0, sizeof(data)); + data.ioc_dev = get_mgs_device(); + if (argc != 3) + return CMD_HELP; + + data.ioc_inllen1 = strlen(argv[1]) + 1; + data.ioc_inlbuf1 = argv[1]; + + data.ioc_inllen2 = strlen(argv[2]) + 1; + data.ioc_inlbuf2 = argv[2]; + 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_REPLACE_NIDS, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); + } + + return rc; +} + int jt_obd_deactivate(int argc, char **argv) { return do_activate(argc, argv, 0); @@ -1843,9 +2318,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, 0, sizeof(data)); + data.ioc_dev = cur_device; if (argc > 2) return CMD_HELP; @@ -1854,7 +2331,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]), @@ -1867,6 +2350,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; @@ -1878,12 +2362,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, 0, 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) { @@ -1900,7 +2391,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); @@ -1912,17 +2408,24 @@ int jt_obd_mdc_lookup(int argc, char **argv) int jt_cfg_dump_log(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, 0, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; 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 = l_ioctl(OBD_DEV_ID, OBD_IOC_DUMP_LOG, buf); if (rc < 0) fprintf(stderr, "OBD_IOC_DUMP_LOG failed: %s\n", @@ -1934,15 +2437,22 @@ int jt_cfg_dump_log(int argc, char **argv) int jt_llog_catlist(int argc, char **argv) { struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; if (argc != 1) return CMD_HELP; - IOC_INIT(data); - data.ioc_inllen1 = max - size_round(sizeof(data)); - IOC_PACK(argv[0], data); - + memset(&data, 0, 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: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf); if (rc == 0) fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); @@ -1956,17 +2466,25 @@ int jt_llog_catlist(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; if (argc != 2) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; 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); + 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; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf); if (rc == 0) @@ -1981,12 +2499,14 @@ int jt_llog_info(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; if (argc != 2 && argc != 4) return CMD_HELP; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; if (argc == 4) { @@ -2001,11 +2521,17 @@ int jt_llog_print(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_PRINT, buf); if (rc == 0) @@ -2017,42 +2543,129 @@ int jt_llog_print(int argc, char **argv) return rc; } +static int llog_cancel_parse_optional(int argc, char **argv, + struct obd_ioctl_data *data) +{ + int cOpt; + const char *const short_options = "c:l:i:h"; + const struct option long_options[] = { + {"catalog", required_argument, NULL, 'c'}, + {"log_id", required_argument, NULL, 'l'}, + {"log_idx", required_argument, NULL, 'i'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + + /* sanity check */ + if (!data || argc <= 1) { + return -1; + } + + /*now process command line arguments*/ + while ((cOpt = getopt_long(argc, argv, short_options, + long_options, NULL)) != -1) { + switch (cOpt) { + case 'c': + data->ioc_inllen1 = strlen(optarg) + 1; + data->ioc_inlbuf1 = optarg; + break; + + case 'l': + data->ioc_inllen2 = strlen(optarg) + 1; + data->ioc_inlbuf2 = optarg; + break; + + case 'i': + data->ioc_inllen3 = strlen(optarg) + 1; + data->ioc_inlbuf3 = optarg; + break; + + case 'h': + default: + return -1; + } + } + + if ((data->ioc_inlbuf1 == NULL) || (data->ioc_inlbuf3 == NULL)) { + /* missing mandatory parameters */ + return -1; + } + + return 0; +} + int jt_llog_cancel(int argc, char **argv) { + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc, i; + + /* check that the arguments provided are either all + * optional or all positional. No mixing allowed + * + * if argc is 4 or 3 then check all arguments to ensure that none + * of them start with a '-'. If so then this is invalid. + * Otherwise if arg is > 4 then assume that this is optional + * arguments, and parse as such ignoring any thing that's not + * optional. The result is that user must use optional arguments + * for all mandatory parameters. Code will ignore all other args + * + * The positional arguments option should eventually be phased out. + */ + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + + if (argc == 3 || argc == 4) { + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') + return CMD_HELP; + } + 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 { + data.ioc_inllen3 = strlen(argv[2]) + 1; + data.ioc_inlbuf3 = argv[2]; + } + } else { + if (llog_cancel_parse_optional(argc, argv, &data) != 0) + return CMD_HELP; + } + + 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) + fprintf(stdout, "index %s was canceled.\n", + argc == 4 ? argv[3] : argv[2]); + else + fprintf(stderr, "OBD_IOC_LLOG_CANCEL failed: %s\n", + strerror(errno)); + + return rc; +} + +int jt_llog_check(int argc, char **argv) +{ struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; int rc; - if (argc != 4) + if (argc != 2 && argc != 4) return CMD_HELP; - IOC_INIT(data); - 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); - - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CANCEL, buf); - if (rc == 0) - fprintf(stdout, "index %s be canceled.\n", argv[3]); - else - fprintf(stderr, "OBD_IOC_LLOG_CANCEL failed: %s\n", - strerror(errno)); - - return rc; - -} -int jt_llog_check(int argc, char **argv) -{ - struct obd_ioctl_data data; - int rc; - - if (argc != 2 && argc != 4) - return CMD_HELP; - - IOC_INIT(data); + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; data.ioc_inllen1 = strlen(argv[1]) + 1; data.ioc_inlbuf1 = argv[1]; if (argc == 4) { @@ -2067,11 +2680,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) @@ -2085,26 +2704,35 @@ 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, 0, 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) { - if (argc == 3) - fprintf(stdout, "log %s are removed.\n", argv[2]); - else - fprintf(stdout, "the log in catalog %s are removed. \n", argv[1]); + if (argc == 2) + fprintf(stdout, "log %s is removed.\n", argv[1]); + else + fprintf(stdout, "the log in catalog %s is removed. \n", + argv[1]); } else fprintf(stderr, "OBD_IOC_LLOG_REMOVE failed: %s\n", strerror(errno)); @@ -2146,14 +2774,18 @@ static int jt_blockdev_find_module(const char *module) { FILE *fp; int found = 0; - char modname[256]; + char buf[1024]; + char *ptr; fp = fopen("/proc/modules", "r"); if (fp == NULL) return -1; - while (fscanf(fp, "%s %*s %*s %*s %*s %*s", modname) == 1) { - if (strcmp(module, modname) == 0) { + while (fgets(buf, 1024, fp) != NULL) { + ptr = strchr(buf, ' '); + if (ptr != NULL) + *ptr = 0; + if (strcmp(module, buf) == 0) { found = 1; break; } @@ -2281,7 +2913,7 @@ int jt_blockdev_info(int argc, char **argv) { char *filename; int rc, fd; - __u64 ino; + struct lu_fid fid; if (argc != 2) return CMD_HELP; @@ -2294,17 +2926,17 @@ int jt_blockdev_info(int argc, char **argv) return CMD_HELP; } - rc = ioctl(fd, LL_IOC_LLOOP_INFO, &ino); + rc = ioctl(fd, LL_IOC_LLOOP_INFO, &fid); if (rc < 0) { rc = errno; fprintf(stderr, "error: %s\n", strerror(errno)); goto out; } fprintf(stdout, "lloop device info: "); - if (ino == 0ULL) + if (fid_is_zero(&fid)) fprintf(stdout, "Not attached\n"); else - fprintf(stdout, "attached to inode "LPU64"\n", ino); + fprintf(stdout, "attached to inode "DFID"\n", PFID(&fid)); out: close(fd); return -rc; @@ -2321,131 +2953,47 @@ static void signal_server(int 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; + if (shmem_setup() != 0) + return -1; - shmem_setup(); - register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH, - OBD_DEV_MAJOR, OBD_DEV_MINOR); + register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH, + OBD_DEV_MAJOR, OBD_DEV_MINOR); - return 0; + return 0; } void obd_finalize(int argc, char **argv) { struct sigaction sigact; + /* sigact initialization */ sigact.sa_handler = signal_server; sigfillset(&sigact.sa_mask); sigact.sa_flags = SA_RESTART; + /* coverity[uninit_use_in_call] */ sigaction(SIGINT, &sigact, NULL); - shmem_stop(); + shmem_cleanup(); do_disconnect(argv[0], 1); } -static int find_target_obdpath(char *fsname, char *path) -{ - glob_t glob_info; - char pattern[PATH_MAX + 1]; - int rc; - - snprintf(pattern, PATH_MAX, - "/proc/fs/lustre/lov/%s-*/target_obd", - fsname); - rc = glob(pattern, GLOB_BRACE, NULL, &glob_info); - if (rc) - return -EINVAL; - - if (glob_info.gl_pathc == 0) { - globfree(&glob_info); - return -EINVAL; - } - - strcpy(path, glob_info.gl_pathv[0]); - return 0; -} - -static int find_poolpath(char *fsname, char *poolname, char *poolpath) +static int check_pool_cmd(enum lcfg_command_type cmd, + char *fsname, char *poolname, + char *ostname) { - glob_t glob_info; - char pattern[PATH_MAX + 1]; int rc; - snprintf(pattern, PATH_MAX, - "/proc/fs/lustre/lov/%s-*/pools/%s", - fsname, poolname); - rc = glob(pattern, GLOB_BRACE, NULL, &glob_info); - if (rc) - return -EINVAL; - - if (glob_info.gl_pathc == 0) { - globfree(&glob_info); - return -EINVAL; - } - - strcpy(poolpath, glob_info.gl_pathv[0]); - return 0; -} - -/* - * if pool is NULL, search ostname in target_obd - * if pool is no NULL - * if pool not found returns < 0 - * if ostname is NULL, returns 1 if pool is not empty and 0 if pool empty - * if ostname is not NULL, returns 1 if OST is in pool and 0 if not - */ -static int search_ost(char *fsname, char *poolname, char *ostname) -{ - FILE *fd; - char buffer[PATH_MAX + 1]; - int len = 0, rc; - - if (ostname != NULL) - len = strlen(ostname); - - if (poolname == NULL) - rc = find_target_obdpath(fsname, buffer); - else - rc = find_poolpath(fsname, poolname, buffer); - if (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; - - if ((fd = fopen(buffer, "r")) == NULL) - return -EINVAL; - - while (fgets(buffer, sizeof(buffer), fd) != NULL) { - if (poolname == NULL) { - /* we search ostname in target_obd */ - if (strncmp(buffer + 3, ostname, len) == 0) { - fclose(fd); - return 1; - } - } else { - /* we search a non empty pool or - an ostname in a pool */ - if ((ostname == NULL) || - (strncmp(buffer, ostname, len) == 0)) { - fclose(fd); - return 1; - } - } } - fclose(fd); - return 0; -} - -static int check_pool_cmd(enum lcfg_command_type cmd, - char *fsname, char *poolname, - char *ostname) -{ - int rc = 0; switch (cmd) { case LCFG_POOL_NEW: { - if (search_ost(fsname, poolname, NULL) >= 0) { + LASSERT(ostname == NULL); + if (rc >= 0) { fprintf(stderr, "Pool %s.%s already exists\n", fsname, poolname); return -EEXIST; @@ -2453,12 +3001,7 @@ static int check_pool_cmd(enum lcfg_command_type cmd, return 0; } case LCFG_POOL_DEL: { - rc = search_ost(fsname, poolname, NULL); - if (rc < 0) { - fprintf(stderr, "Pool %s.%s not found\n", - fsname, poolname); - return -ENOENT; - } + LASSERT(ostname == NULL); if (rc == 1) { fprintf(stderr, "Pool %s.%s not empty, " "please remove all members\n", @@ -2468,32 +3011,20 @@ static int check_pool_cmd(enum lcfg_command_type cmd, return 0; } case LCFG_POOL_ADD: { - rc = search_ost(fsname, NULL, ostname); - if (rc == 0) { - fprintf(stderr, "OST %s not found in lov of %s\n", - ostname, fsname); - return -ENOENT; - } - rc = search_ost(fsname, poolname, ostname); - if (rc < 0) { - fprintf(stderr, "Pool %s.%s not found\n", - fsname, poolname); - return -ENOENT; - } if (rc == 1) { - fprintf(stderr, "OST %s already in pool %s.%s\n", + 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: { - rc = search_ost(fsname, poolname, ostname); - if (rc < 0) { - fprintf(stderr, "Pool %s.%s not found\n", - fsname, poolname); - return -ENOENT; - } if (rc == 0) { fprintf(stderr, "OST %s not found in pool %s.%s\n", ostname, fsname, poolname); @@ -2501,83 +3032,105 @@ static int check_pool_cmd(enum lcfg_command_type cmd, } return 0; } - default: { - } - } - return 0; + default: + break; + } /* switch */ + return -EINVAL; } -static void check_pool_cmd_result(enum lcfg_command_type cmd, - char *fsname, char *poolname, - char *ostname) +/* 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, rc = 0; + int cpt = 10; + int rc = 0; - cpt = 10; switch (cmd) { case LCFG_POOL_NEW: { do { - rc = search_ost(fsname, poolname, NULL); + 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) + if (rc >= 0) { fprintf(stderr, "Pool %s.%s created\n", fsname, poolname); - else + return 0; + } else { fprintf(stderr, "Warning, pool %s.%s not found\n", fsname, poolname); - return; + return -ENOENT; + } } case LCFG_POOL_DEL: { do { - rc = search_ost(fsname, poolname, NULL); - if (rc >= 0) + rc = llapi_search_ost(fsname, poolname, NULL); + if (rc == -ENODEV) + return rc; + if (rc >= 0) sleep(2); - cpt--; + cpt--; } while ((rc >= 0) && (cpt > 0)); - if (rc < 0) + if (rc < 0) { fprintf(stderr, "Pool %s.%s destroyed\n", fsname, poolname); - else + return 0; + } else { fprintf(stderr, "Warning, pool %s.%s still found\n", fsname, poolname); - return; + return -EEXIST; + } } case LCFG_POOL_ADD: { do { - rc = search_ost(fsname, poolname, ostname); + 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) + if (rc == 1) { fprintf(stderr, "OST %s added to pool %s.%s\n", ostname, fsname, poolname); - else + return 0; + } else { fprintf(stderr, "Warning, OST %s not found in pool %s.%s\n", ostname, fsname, poolname); - return; + return -ENOENT; + } } case LCFG_POOL_REM: { do { - rc = search_ost(fsname, poolname, ostname); + 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) + if (rc != 1) { fprintf(stderr, "OST %s removed from pool %s.%s\n", ostname, fsname, poolname); - else + return 0; + } else { fprintf(stderr, "Warning, OST %s still found in pool %s.%s\n", ostname, fsname, poolname); - return; - } - default: { + return -EEXIST; + } } + default: + break; } + return -EINVAL; } static int check_and_complete_ostname(char *fsname, char *ostname) @@ -2596,7 +3149,9 @@ static int check_and_complete_ostname(char *fsname, char *ostname) ostname, fsname); return -EINVAL; } else { - strcpy(real_ostname, ostname); + if (strlen(ostname) > sizeof(real_ostname)-1) + return -E2BIG; + strncpy(real_ostname, ostname, sizeof(real_ostname)); } /* real_ostname is fsname-????? */ ptr = real_ostname + strlen(fsname) + 1; @@ -2639,9 +3194,13 @@ static int pool_cmd(enum lcfg_command_type cmd, 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) + 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); @@ -2650,13 +3209,11 @@ static int pool_cmd(enum lcfg_command_type cmd, 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; - } + lcfg = lustre_cfg_new(cmd, &bufs); + if (lcfg == NULL) + return -ENOMEM; - IOC_INIT(data); + memset(&data, 0, sizeof(data)); rc = data.ioc_dev = get_mgs_device(); if (rc < 0) goto out; @@ -2665,8 +3222,15 @@ static int pool_cmd(enum lcfg_command_type cmd, data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens); data.ioc_pbuf1 = (void *)lcfg; - IOC_PACK(cmdname, 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(cmdname)); + lustre_cfg_free(lcfg); + return rc; + } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_POOL, buf); out: if (rc) @@ -2675,6 +3239,686 @@ out: return rc; } +/** + * Format and send the ioctl to the MGS. + * + * \param cmd IOCTL to send + * \param ret_data void pointer to return anything from + * ioctl + * \param num_args number of arguments to pack into the + * ioctl buffer + * \param argv[] variable number of string arguments + * + * \retval 0 on success + */ +static int nodemap_cmd(enum lcfg_command_type cmd, void *ret_data, + unsigned int ret_size, ...) +{ + va_list ap; + char *arg; + int i = 0; + struct lustre_cfg_bufs bufs; + struct obd_ioctl_data data; + struct lustre_cfg *lcfg; + char rawbuf[MAX_IOC_BUFLEN]; + char *buf = rawbuf; + int rc = 0; + + lustre_cfg_bufs_reset(&bufs, NULL); + + va_start(ap, ret_size); + arg = va_arg(ap, char *); + while (arg != NULL) { + lustre_cfg_bufs_set_string(&bufs, i, arg); + i++; + arg = va_arg(ap, char *); + } + va_end(ap); + + lcfg = lustre_cfg_new(cmd, &bufs); + if (lcfg == NULL) + return -ENOMEM; + + memset(&data, 0, 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 != 0) { + fprintf(stderr, "error: invalid ioctl: %08x errno: %d with " + "rc=%d\n", cmd, errno, rc); + goto out; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NODEMAP, buf); + if (rc != 0) { + fprintf(stderr, "error: invalid ioctl: %08x errno: %d with " + "rc=%d\n", cmd, errno, rc); + goto out; + } + + if (ret_data != NULL) { + rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + if (rc != 0) + goto out; + + memcpy(ret_data, data.ioc_pbuf1, data.ioc_plen1); + if (ret_data == NULL || sizeof(ret_data) != ret_size) + rc = -errno; + } +out: + lustre_cfg_free(lcfg); + + return rc; +} + +/** + * activate nodemap functions + * + * \param argc number of args + * \param argv[] variable string arguments + * + * argv[0] 1 for activate or 0 for deactivate + * + * \retval 0 on success + */ +int jt_nodemap_activate(int argc, char **argv) +{ + int rc; + + rc = nodemap_cmd(LCFG_NODEMAP_ACTIVATE, NULL, 0, argv[0], argv[1], + NULL); + + if (rc != 0) { + errno = -rc; + perror(argv[0]); + } + + return rc; +} + +/** + * add a nodemap + * + * \param argc number of args + * \param argv[] variable string arguments + * + * argv[0] nodemap name + * + * \retval 0 on success + */ +int jt_nodemap_add(int argc, char **argv) +{ + int rc; + + rc = llapi_nodemap_exists(argv[1]); + if (rc == 0) { + fprintf(stderr, "error: %s existing nodemap name\n", argv[1]); + return 1; + } + + rc = nodemap_cmd(LCFG_NODEMAP_ADD, NULL, 0, argv[0], argv[1], NULL); + + if (rc != 0) { + errno = -rc; + perror(argv[0]); + } + + return rc; +} + +/** + * delete a nodemap + * + * \param argc number of args + * \param argv[] variable string arguments + * + * argv[0] nodemap name + * + * \retval 0 on success + */ +int jt_nodemap_del(int argc, char **argv) +{ + int rc; + + rc = llapi_nodemap_exists(argv[1]); + if (rc != 0) { + fprintf(stderr, "error: %s not existing nodemap name\n", + argv[1]); + return rc; + } + rc = nodemap_cmd(LCFG_NODEMAP_DEL, NULL, 0, argv[0], argv[1], NULL); + + if (rc != 0) { + errno = -rc; + perror(argv[0]); + } + + return rc; +} + +/** + * test a nid for nodemap membership + * + * \param argc number of args + * \param argv[] variable string arguments + * + * argv[0] properly formatted nid + * + * \retval 0 on success + */ +int jt_nodemap_test_nid(int argc, char **argv) +{ + + char rawbuf[MAX_IOC_BUFLEN]; + int rc; + + rc = nodemap_cmd(LCFG_NODEMAP_TEST_NID, &rawbuf, sizeof(rawbuf), + argv[0], argv[1], NULL); + if (rc == 0) + printf("%s\n", (char *)rawbuf); + + return rc; +} + +/** + * test a nodemap id pair for mapping + * + * \param argc number of args + * \param argv[[] variable string arguments + * + * \retval 0 on success + * + * The argv array should contain the nodemap name, the id + * to checking the mapping on, and the id type (UID or GID) + * + */ +int jt_nodemap_test_id(int argc, char **argv) +{ + char rawbuf[MAX_IOC_BUFLEN]; + char *nidstr = NULL; + char *idstr = NULL; + char *typestr = NULL; + int rc = 0; + int c; + + static struct option long_options[] = { + { + .name = "nid", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "idtype", + .has_arg = required_argument, + .flag = 0, + .val = 't', + }, + { + .name = "id", + .has_arg = required_argument, + .flag = 0, + .val = 'i', + }, + { + NULL + } + }; + + while ((c = getopt_long(argc, argv, "n:t:i:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nidstr = optarg; + break; + case 't': + typestr = optarg; + break; + case 'i': + idstr = optarg; + break; + } + } + + if (nidstr == NULL || typestr == NULL || idstr == NULL) { + fprintf(stderr, "usage: nodemap_test_id --nid " + "--idtype [uid|gid] --id \n"); + return -1; + } + + rc = nodemap_cmd(LCFG_NODEMAP_TEST_ID, &rawbuf, sizeof(rawbuf), + argv[0], nidstr, typestr, idstr); + if (rc == 0) + printf("%s\n", (char *)rawbuf); + + return rc; +} + +/** + * add an nid range to a nodemap + * + * \param argc number of args + * \param argv[] variable string arguments + * + * --name nodemap name + * --range properly formatted nid range + * + * \retval 0 on success + */ +int jt_nodemap_add_range(int argc, char **argv) +{ + char *nodemap_name = NULL; + char *nodemap_range = NULL; + struct list_head nidlist; + char min_nid[LNET_NIDSTR_SIZE + 1]; + char max_nid[LNET_NIDSTR_SIZE + 1]; + char nid_range[2 * LNET_NIDSTR_SIZE + 2]; + int rc = 0; + int c; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "range", + .has_arg = required_argument, + .flag = 0, + .val = 'r', + }, + { + NULL + } + }; + + INIT_LIST_HEAD(&nidlist); + + while ((c = getopt_long(argc, argv, "n:r:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'r': + nodemap_range = optarg; + break; + } + } + + if (nodemap_name == NULL || nodemap_range == NULL) { + fprintf(stderr, "usage: nodemap_add_range --name " + "--range \n"); + return -1; + } + + if (cfs_parse_nidlist(nodemap_range, strlen(nodemap_range), + &nidlist) <= 0) { + fprintf(stderr, "error: %s: can't parse nid range: %s\n", + jt_cmdname(argv[0]), nodemap_range); + return -1; + } + + if (!cfs_nidrange_is_contiguous(&nidlist)) { + fprintf(stderr, "error: %s: nodemap ranges must be " + "contiguous\n", jt_cmdname(argv[0])); + return -1; + } + + cfs_nidrange_find_min_max(&nidlist, &min_nid[0], &max_nid[0], + LNET_NIDSTR_SIZE); + snprintf(nid_range, sizeof(nid_range), "%s:%s", min_nid, max_nid); + + rc = nodemap_cmd(LCFG_NODEMAP_ADD_RANGE, NULL, 0, argv[0], + nodemap_name, nid_range, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "error: %s: cannot add range '%s' to nodemap " + "'%s': rc = %d\n", + jt_cmdname(argv[0]), nodemap_range, nodemap_name, rc); + } + + return rc; +} + +/** + * delete an nid range to a nodemap + * + * \param argc number of args + * \param argv[] variable string arguments + * + * --name nodemap name + * --range properly formatted nid range + * + * \retval 0 on success + */ +int jt_nodemap_del_range(int argc, char **argv) +{ + char *nodemap_name = NULL; + char *nodemap_range = NULL; + struct list_head nidlist; + char min_nid[LNET_NIDSTR_SIZE + 1]; + char max_nid[LNET_NIDSTR_SIZE + 1]; + char nid_range[2 * LNET_NIDSTR_SIZE + 2]; + int rc = 0; + int c; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "range", + .has_arg = required_argument, + .flag = 0, + .val = 'r', + }, + { + NULL + } + }; + + INIT_LIST_HEAD(&nidlist); + + while ((c = getopt_long(argc, argv, "n:r:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'r': + nodemap_range = optarg; + break; + } + } + + if (nodemap_name == NULL || nodemap_range == NULL) { + fprintf(stderr, "usage: nodemap_del_range --name " + "--range \n"); + return -1; + } + + if (cfs_parse_nidlist(nodemap_range, strlen(nodemap_range), + &nidlist) <= 0) { + fprintf(stderr, "error: %s: can't parse nid range: %s\n", + jt_cmdname(argv[0]), nodemap_range); + return -1; + } + + if (!cfs_nidrange_is_contiguous(&nidlist)) { + fprintf(stderr, "error: %s: nodemap ranges must be " + "contiguous\n", jt_cmdname(argv[0])); + return -1; + } + + cfs_nidrange_find_min_max(&nidlist, &min_nid[0], &max_nid[0], + LNET_NIDSTR_SIZE); + snprintf(nid_range, sizeof(nid_range), "%s:%s", min_nid, max_nid); + + rc = nodemap_cmd(LCFG_NODEMAP_DEL_RANGE, NULL, 0, argv[0], + nodemap_name, nid_range, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "error: %s: cannot delete range '%s' to " + "nodemap '%s': rc = %d\n", + jt_cmdname(argv[0]), nodemap_range, nodemap_name, rc); + } + + return rc; +} + +/** + * modify a nodemap's behavior + * + * \param argc number of args + * \param argv[] variable string arguments + * + * --name nodemap name + * --property nodemap property to change + * admin, trusted, squash_uid, squash_gid) + * --value value to set property + * + * \retval 0 on success + */ +int jt_nodemap_modify(int argc, char **argv) +{ + int c; + int rc = 0; + enum lcfg_command_type cmd = 0; + char *nodemap_name = NULL; + char *param = NULL; + char *value = NULL; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "property", + .has_arg = required_argument, + .flag = 0, + .val = 'p', + }, + { + .name = "value", + .has_arg = required_argument, + .flag = 0, + .val = 'v', + }, + { + NULL + } + }; + + while ((c = getopt_long(argc, argv, "n:p:v:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'p': + param = optarg; + break; + case 'v': + value = optarg; + break; + } + } + + if (nodemap_name == NULL || param == NULL || value == NULL) { + fprintf(stderr, "usage: nodemap_modify --name " + "--property --value \n"); + fprintf(stderr, "valid properties: admin trusted " + "squash_uid squash_gid\n"); + return -1; + } + + if (strcmp("admin", param) == 0) { + cmd = LCFG_NODEMAP_ADMIN; + } else if (strcmp("trusted", param) == 0) { + cmd = LCFG_NODEMAP_TRUSTED; + } else if (strcmp("squash_uid", param) == 0) { + cmd = LCFG_NODEMAP_SQUASH_UID; + } else if (strcmp("squash_gid", param) == 0) { + cmd = LCFG_NODEMAP_SQUASH_GID; + } else { + fprintf(stderr, "error: %s: nodemap_modify invalid " + "subcommand: %s\n", + jt_cmdname(argv[0]), param); + return -1; + } + + rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, param, + value, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "error: %s: cannot modify nodemap '%s' " + "to param '%s': value '%s': rc = %d\n", + jt_cmdname(argv[0]), nodemap_name, param, value, rc); + } + + return rc; +} + +int jt_nodemap_add_idmap(int argc, char **argv) +{ + int c; + enum lcfg_command_type cmd = 0; + char *nodemap_name = NULL; + char *idmap = NULL; + char *idtype = NULL; + int rc = 0; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "idmap", + .has_arg = required_argument, + .flag = 0, + .val = 'm', + }, + { + .name = "idtype", + .has_arg = required_argument, + .flag = 0, + .val = 'i', + }, + { + NULL + } + }; + + while ((c = getopt_long(argc, argv, "n:m:i:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'm': + idmap = optarg; + break; + case 'i': + idtype = optarg; + break; + } + } + + if (nodemap_name == NULL || idmap == NULL || idtype == NULL) { + fprintf(stderr, "usage: %s --name --idtype [uid | gid]" + " --idmap :\n", argv[0]); + return -1; + } + + if (strcmp("uid", idtype) == 0) { + cmd = LCFG_NODEMAP_ADD_UIDMAP; + } else if (strcmp("gid", idtype) == 0) { + cmd = LCFG_NODEMAP_ADD_GIDMAP; + } else { + fprintf(stderr, "usage: %s --name --idtype [uid | gid]" + " --idmap :\n", argv[0]); + return -1; + } + + rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, idmap, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "cannot add %smap '%s' to nodemap '%s'" + ": rc = %d\n", idtype, idmap, nodemap_name, rc); + } + + return rc; +} + +int jt_nodemap_del_idmap(int argc, char **argv) +{ + int c; + enum lcfg_command_type cmd = 0; + char *nodemap_name = NULL; + char *idmap = NULL; + char *idtype = NULL; + int rc = 0; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .flag = 0, + .val = 'n', + }, + { + .name = "idmap", + .has_arg = required_argument, + .flag = 0, + .val = 'm', + }, + { + .name = "idtype", + .has_arg = required_argument, + .flag = 0, + .val = 'i', + }, + { + NULL + } + }; + + while ((c = getopt_long(argc, argv, "n:m:i:", + long_options, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'm': + idmap = optarg; + break; + case 'i': + idtype = optarg; + break; + } + } + + if (nodemap_name == NULL || idmap == NULL || idtype == NULL) { + fprintf(stderr, "usage: %s --name --idtype [uid | gid]" + " --idmap :\n", argv[0]); + return -1; + } + + if (strcmp("uid", idtype) == 0) + cmd = LCFG_NODEMAP_DEL_UIDMAP; + else + cmd = LCFG_NODEMAP_DEL_GIDMAP; + + rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, idmap, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "cannot delete %smap '%s' from nodemap '%s'" + ": rc = %d\n", idtype, idmap, nodemap_name, rc); + } + + return rc; +} + /* * this function tranforms a rule [start-end/step] into an array * of matching numbers @@ -2708,7 +3952,7 @@ static int get_array_idx(char *rule, char *format, int **array) end++; start++; /* put in format the printf format (the rule without the range) */ - sprintf(format, "%s%%.4d%s", rule, end); + sprintf(format, "%s%%.4x%s", rule, end); array_idx = 0; array_sz = 0; @@ -2716,7 +3960,7 @@ static int get_array_idx(char *rule, char *format, int **array) /* loop on , separator */ do { /* extract the 3 fields */ - rc = sscanf(start, "%u-%u/%u", &lo, &hi, &step); + rc = sscanf(start, "%x-%x/%u", &lo, &hi, &step); switch (rc) { case 0: { return 0; @@ -2781,15 +4025,15 @@ static int extract_fsname_poolname(char *arg, char *fsname, char *poolname) rc = -EINVAL; goto err; } - if (len > MAXPOOLNAME) { + if (len > LOV_MAXPOOLNAME) { fprintf(stderr, "poolname %s is too long (length is %d max is %d)\n", - ptr + 1, len, MAXPOOLNAME); + ptr + 1, len, LOV_MAXPOOLNAME); rc = -ENAMETOOLONG; goto err; } - strncpy(poolname, ptr + 1, MAXPOOLNAME); - poolname[MAXPOOLNAME] = '\0'; + strncpy(poolname, ptr + 1, LOV_MAXPOOLNAME); + poolname[LOV_MAXPOOLNAME] = '\0'; *ptr = '\0'; return 0; @@ -2802,7 +4046,7 @@ int jt_pool_cmd(int argc, char **argv) { enum lcfg_command_type cmd; char fsname[PATH_MAX + 1]; - char poolname[MAXPOOLNAME + 1]; + char poolname[LOV_MAXPOOLNAME + 1]; char *ostnames_buf = NULL; int i, rc; int *array = NULL, array_sz; @@ -2827,8 +4071,7 @@ int jt_pool_cmd(int argc, char **argv) if (rc) break; - rc = pool_cmd(cmd, argv[0], argv[1], - fsname, poolname, NULL); + rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); if (rc) break; @@ -2892,6 +4135,9 @@ int jt_pool_cmd(int argc, char **argv) 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) { @@ -2915,17 +4161,14 @@ int jt_pool_cmd(int argc, char **argv) free(array); if (cmds) free(cmds); - if (ostnames_buf); - free(ostnames_buf); + if (ostnames_buf != NULL) + free(ostnames_buf); } - return 0; - } + /* fall through */ } - + } /* switch */ out: - if ((rc == -EINVAL) || (rc == -ENOENT)) - fprintf(stderr, "Does the fs, pool or ost exist?\n"); if (rc != 0) { errno = -rc; perror(argv[0]); @@ -2933,3 +4176,195 @@ out: return rc; } + +int jt_get_obj_version(int argc, char **argv) +{ + struct lu_fid fid; + struct obd_ioctl_data data; + __u64 version, id = ULLONG_MAX, group = ULLONG_MAX; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf, *fidstr; + int rc, c; + + while ((c = getopt(argc, argv, "i:g:")) != -1) { + switch (c) { + case 'i': + id = strtoull(optarg, NULL, 0); + break; + case 'g': + group = strtoull(optarg, NULL, 0); + break; + default: + return CMD_HELP; + } + } + + argc -= optind; + argv += optind; + + if (!(id != ULLONG_MAX && group != ULLONG_MAX && argc == 0) && + !(id == ULLONG_MAX && group == ULLONG_MAX && argc == 1)) + return CMD_HELP; + + memset(&data, 0, sizeof data); + data.ioc_dev = cur_device; + if (argc == 1) { + fidstr = *argv; + while (*fidstr == '[') + fidstr++; + sscanf(fidstr, SFID, RFID(&fid)); + + data.ioc_inlbuf1 = (char *) &fid; + data.ioc_inllen1 = sizeof fid; + } else { + data.ioc_inlbuf3 = (char *) &id; + data.ioc_inllen3 = sizeof id; + data.ioc_inlbuf4 = (char *) &group; + data.ioc_inllen4 = sizeof group; + } + 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; +} + +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, 0, 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) { + if (strlen(lcfg_get_devname()) > sizeof(devname)-1) { + fprintf(stderr, "Dev name too long\n"); + return -E2BIG; + } + strncpy(devname, lcfg_get_devname(), sizeof(devname)); + } else { + if (snprintf(devname, sizeof(devname), "dev %d", cur_device) >= + sizeof(devname)) { + fprintf(stderr, "Dev name too long\n"); + return -E2BIG; + } + } + + 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, 0, 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) { + if (strlen(lcfg_get_devname()) > sizeof(devname)-1) { + fprintf(stderr, "Dev name too long\n"); + return -E2BIG; + } + strncpy(devname, lcfg_get_devname(), sizeof(devname)); + } else { + if (snprintf(devname, sizeof(devname), "dev %d", cur_device) >= + sizeof(devname)) { + fprintf(stderr, "Dev name too long\n"); + return -E2BIG; + } + } + + printf("%s: Deregistered changelog user '"CHANGELOG_USER_PREFIX"%d'\n", + devname, data.ioc_u32_1); + return 0; +} + +