X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fobd.c;h=f3294ffd63adbd112eca63993bb42c337de2dc0a;hp=4c0c14ecf9884d8cfd33a853876fefd2069d34a3;hb=0d75d5cd5a6217ec75bac8d3f479bbfb8a10be29;hpb=9c5fad36aac2086b38f91e28db90da01efc9126a diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 4c0c14e..f3294ff 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -23,7 +23,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2016, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -58,7 +58,6 @@ #include #include #include - #include "obdctl.h" #include "lustreapi_internal.h" #include @@ -67,16 +66,16 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -#include #include -#include -#include #define MAX_STRING_SIZE 128 @@ -116,34 +115,28 @@ const int nthreads = 1; static int cur_device = -1; -static int l2_ioctl(int dev_id, int opc, void *buf) -{ - return l_ioctl(dev_id, opc, buf); -} - -int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg) +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; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - 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; - 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; - } + 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; + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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); + rc = l_ioctl(dev_id, OBD_IOC_PROCESS_CFG, buf); - return rc; + return rc; } static int do_device(char *func, char *devname); @@ -171,33 +164,31 @@ static int get_mgs_device() /* Returns -1 on error with errno set */ 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; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - 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) { - fprintf(stderr, "error: %s: invalid ioctl\n", - jt_cmdname(func)); - return rc; - } + 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 = llapi_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); + 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; + if (rc && errno == ENOSYS) + fprintf(stderr, "Make sure cfg_device is set first.\n"); + + return rc; } char *obdo_print(struct obdo *obd) @@ -225,33 +216,31 @@ 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; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; - data.ioc_inllen1 = strlen(name) + 1; - data.ioc_inlbuf1 = name; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + data.ioc_inllen1 = strlen(name) + 1; + data.ioc_inlbuf1 = name; - memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc < 0) { - fprintf(stderr, "error: %s: invalid ioctl\n", - jt_cmdname(func)); + 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; - rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); - if (rc) { - fprintf(stderr, "error: %s: invalid reply\n", - jt_cmdname(func)); - return rc; - } + } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf); + if (rc < 0) + return errno; + rc = llapi_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; + return data.ioc_dev + N2D_OFF; } /* @@ -260,25 +249,27 @@ static int do_name2dev(char *func, char *name) */ int parse_devname(char *func, char *name) { - int rc; - int ret = -1; + int rc; + int ret = -1; + int try_digit; + + if (!name) + return ret; - if (!name) - return ret; - if (isdigit(name[0])) { + try_digit = isdigit(name[0]); + + if (name[0] == '$' || name[0] == '%') + name++; + + rc = do_name2dev(func, name); + if (rc >= N2D_OFF) + return rc - N2D_OFF; + + if (try_digit) 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); - } else { - fprintf(stderr, "No device found for name %s: %s\n", + else + fprintf(stderr, "No device found for name %s: %s\n", name, strerror(rc)); - } - } return ret; } @@ -528,16 +519,21 @@ static void shmem_snap(int total_threads, int live_threads) } 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); + 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])); - prev_time = this_time; - if (!prev_valid && - running == total_threads) - prev_valid = 1; + memcpy(counter_snapshot[1], counter_snapshot[0], + total_threads * sizeof(counter_snapshot[0][0])); + prev_time = this_time; + } + if (!prev_valid && running == total_threads) { + prev_valid = 1; + /* drop counters when all threads were started */ + memcpy(counter_snapshot[1], counter_snapshot[0], + total_threads * sizeof(counter_snapshot[0][0])); + prev_time = this_time; + } } static void shmem_stop(void) @@ -678,7 +674,7 @@ static void parent_sighandler (int sig) int jt_opt_threads(int argc, char **argv) { - static char cmdstr[128]; + static char cmdstr[129]; sigset_t saveset; sigset_t sigset; struct sigaction sigact; @@ -713,8 +709,9 @@ int jt_opt_threads(int argc, char **argv) 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]); + snprintf(cmdstr + strlen(cmdstr), + sizeof(cmdstr) - strlen(cmdstr), + " %s", argv[i]); printf("%s: starting %ld threads on device %s running %s\n", argv[0], threads, argv[3], cmdstr); @@ -845,83 +842,83 @@ 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; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - if (argc != 1) - return CMD_HELP; + if (argc != 1) + 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 = l2_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), - strerror(rc = errno)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_NO_TRANSNO, buf); + if (rc < 0) + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); - return rc; + return rc; } int jt_obd_set_readonly(int argc, char **argv) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - if (argc != 1) - return CMD_HELP; + if (argc != 1) + 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 = l2_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), - strerror(rc = errno)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_SET_READONLY, buf); + if (rc < 0) + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); - return rc; + return rc; } int jt_obd_abort_recovery(int argc, char **argv) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - if (argc != 1) - return CMD_HELP; + if (argc != 1) + 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 = 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)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_ABORT_RECOVERY, buf); + if (rc < 0) + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); - return rc; + return rc; } int jt_get_version(int argc, char **argv) @@ -1008,25 +1005,26 @@ int jt_obd_list_ioctl(int argc, char **argv) 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; + sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(*data), 8); + data->ioc_inlbuf1 = buf + __ALIGN_KERNEL(sizeof(*data), 8); + 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); - } - if (rc != 0) { - if (errno == ENOENT) - /* no device or the last device */ - rc = 0; - else - fprintf(stderr, "Error getting device list: %s: " - "check dmesg.\n", strerror(errno)); - } - return rc; + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETDEVICE, buf); + if (rc != 0) + break; + printf("%s\n", (char *)data->ioc_bulk); + } + if (rc != 0) { + if (errno == ENOENT) + /* no device or the last device */ + rc = 0; + else + fprintf(stderr, + "Error getting device list: %s: check dmesg\n", + strerror(errno)); + } + return rc; } int jt_obd_list(int argc, char **argv) @@ -1036,35 +1034,32 @@ int jt_obd_list(int argc, char **argv) glob_t path; FILE *fp; - if (argc > 2) - return CMD_HELP; - else if (argc == 2) { - if (strcmp(argv[1], "-t") == 0) - print_obd = 1; - else - return CMD_HELP; - } + if (argc > 2) + return CMD_HELP; - if (cfs_get_param_paths(&path, "devices") != 0) - return -errno; + if (argc == 2) { + if (strcmp(argv[1], "-t") == 0) + print_obd = 1; + else + return CMD_HELP; + } - fp = fopen(path.gl_pathv[0], "r"); - if (fp == NULL) { - fprintf(stderr, "error: %s: %s opening %s\n", - jt_cmdname(argv[0]), strerror(errno), path.gl_pathv[0]); + if (cfs_get_param_paths(&path, "devices") || + !(fp = fopen(path.gl_pathv[0], "r"))) { cfs_free_param_data(&path); - return jt_obd_list_ioctl(argc, argv); - } - while (fgets(buf, sizeof(buf), fp) != NULL) - if (print_obd) - print_obd_line(buf); - else - printf("%s", buf); + return jt_obd_list_ioctl(argc, argv); + } + + while (fgets(buf, sizeof(buf), fp) != NULL) + if (print_obd) + print_obd_line(buf); + else + printf("%s", buf); cfs_free_param_data(&path); - fclose(fp); - return 0; + fclose(fp); + return 0; } struct jt_fid_space { @@ -1074,46 +1069,46 @@ struct jt_fid_space { }; int jt_obd_alloc_fids(struct jt_fid_space *space, struct lu_fid *fid, - __u64 *count) + __u64 *count) { - int rc; + 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; + 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; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - data.ioc_pbuf1 = (char *)&seqnr; - data.ioc_plen1 = sizeof(seqnr); + data.ioc_pbuf1 = (char *)&seqnr; + data.ioc_plen1 = sizeof(seqnr); - data.ioc_pbuf2 = (char *)&max_count; - data.ioc_plen2 = sizeof(max_count); + data.ioc_pbuf2 = (char *)&max_count; + data.ioc_plen2 = sizeof(max_count); - 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; - } + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: invalid ioctl rc = %d\n", rc); + return rc; + } - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_ALLOC_SEQ, buf); - if (rc) { - fprintf(stderr, "ioctl error: rc = %d\n", rc); - return rc; - } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ECHO_ALLOC_SEQ, buf); + if (rc) { + fprintf(stderr, "ioctl error: rc = %d\n", rc); + return rc; + } - 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; + 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; space->jt_id = space->jt_id + *count; if (space->jt_id > space->jt_width) @@ -1370,26 +1365,26 @@ int jt_obd_md_common(int argc, char **argv, int cmd) return rc; } data.ioc_obdo1.o_oi.oi_fid = fid; - } + } - child_base_id += data.ioc_count; - count += data.ioc_count; + 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; - } + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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); + rc = l_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); @@ -1511,35 +1506,36 @@ int jt_obd_create(int argc, char **argv) OBD_MD_FLGID | OBD_MD_FLGROUP | OBD_MD_FLPROJID; - 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)) { + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_CREATE, buf); + llapi_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:%#jx\n", jt_cmdname(argv[0]), i, (uintmax_t)data.ioc_obdo1.o_valid); - rc = EINVAL; - break; - } + rc = EINVAL; + break; + } if (be_verbose(verbose, &next_time, i, &next_count, count)) printf("%s: #%d is object id %#jx\n", jt_cmdname(argv[0]), i, (uintmax_t) ostid_id(&data.ioc_obdo1.o_oi)); - } - return rc; + } + + return rc; } int jt_obd_setattr(int argc, char **argv) @@ -1551,10 +1547,10 @@ int jt_obd_setattr(int argc, char **argv) int mode; int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; - if (argc != 2) - return CMD_HELP; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (argc != 2) + return CMD_HELP; objid = strtoull(argv[1], &end, 0); if (*end) { @@ -1564,60 +1560,60 @@ int jt_obd_setattr(int argc, char **argv) } if (objid >= OBIF_MAX_OID) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - jt_cmdname(argv[0]), argv[1]); - return CMD_HELP; - } + fprintf(stderr, "error: %s: invalid objid '%s'\n", + jt_cmdname(argv[0]), argv[1]); + return CMD_HELP; + } 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 (*end) { + fprintf(stderr, "error: %s: invalid mode '%s'\n", + jt_cmdname(argv[0]), argv[2]); + return CMD_HELP; + } ostid_set_seq_echo(&data.ioc_obdo1.o_oi); data.ioc_obdo1.o_mode = S_IFREG | mode; data.ioc_obdo1.o_oi.oi_fid.f_oid = objid; data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - 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]), - strerror(rc = errno)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_SETATTR, buf); + if (rc < 0) + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); - return rc; + return rc; } int jt_obd_test_setattr(int argc, char **argv) { - struct obd_ioctl_data data; - struct timeval start, next_time; + 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; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int verbose = 1; __u64 objid = 3; - char *end; - int rc = 0; + char *end; + int rc = 0; - if (argc < 2 || argc > 4) - return CMD_HELP; + if (argc < 2 || argc > 4) + return CMD_HELP; - 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", - jt_cmdname(argv[0]), argv[1]); - return CMD_HELP; - } + 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", + jt_cmdname(argv[0]), argv[1]); + return CMD_HELP; + } if (argc >= 3) { verbose = get_verbose(argv[0], argv[2]); @@ -1648,37 +1644,36 @@ int jt_obd_test_setattr(int argc, char **argv) (uintmax_t)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++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { if (objid >= OBIF_MAX_OID) { fprintf(stderr, "errr: %s: invalid objid '%llu'\n", - jt_cmdname(argv[0]), objid); + jt_cmdname(argv[0]), (unsigned long long)objid); return -E2BIG; } data.ioc_obdo1.o_oi.oi_fid.f_oid = objid; - data.ioc_obdo1.o_mode = S_IFREG; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; - 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(1); - if (rc < 0) { + data.ioc_obdo1.o_mode = S_IFREG; + data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | + OBD_MD_FLMODE; + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_SETATTR, &data); + shmem_bump(1); + if (rc < 0) { fprintf(stderr, "error: %s: #%jd - %d:%s\n", jt_cmdname(argv[0]), (uintmax_t)i, errno, strerror(rc = errno)); - break; - } else { - if (be_verbose - (verbose, &next_time, i, &next_count, count)) - printf("%s: set attr #%jd\n", - jt_cmdname(argv[0]), (uintmax_t)i); - } - } + break; + } + if (be_verbose(verbose, &next_time, i, &next_count, count)) + printf("%s: set attr #%jd\n", + jt_cmdname(argv[0]), (uintmax_t)i); + } if (!rc) { struct timeval end; @@ -1713,6 +1708,7 @@ int jt_obd_destroy(int argc, char **argv) if (argc < 2 || argc > 4) return CMD_HELP; + errno = 0; id = strtoull(argv[1], &end, 0); if (*end || id == 0 || errno != 0) { fprintf(stderr, "error: %s: invalid objid '%s'\n", @@ -1736,14 +1732,15 @@ int jt_obd_destroy(int argc, char **argv) } printf("%s: %jd objects\n", jt_cmdname(argv[0]), (uintmax_t)count); - gettimeofday(&next_time, NULL); - next_time.tv_sec -= verbose; + 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++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); + i++, id++) { if (id >= OBIF_MAX_OID) { fprintf(stderr, "errr: %s: invalid objid '%llu'\n", - jt_cmdname(argv[0]), id); + jt_cmdname(argv[0]), (unsigned long long)id); return -E2BIG; } @@ -1751,41 +1748,41 @@ int jt_obd_destroy(int argc, char **argv) data.ioc_obdo1.o_mode = S_IFREG | 0644; data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; - 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); - obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); - shmem_bump(1); - if (rc < 0) { + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_DESTROY, buf); + llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); + shmem_bump(1); + if (rc < 0) { fprintf(stderr, "error: %s: objid %#jx: %s\n", jt_cmdname(argv[0]), (uintmax_t)id, strerror(rc = errno)); - break; - } + break; + } - if (be_verbose(verbose, &next_time, i, &next_count, count)) + if (be_verbose(verbose, &next_time, i, &next_count, count)) printf("%s: #%d is object id %#jx\n", jt_cmdname(argv[0]), i, (uintmax_t)id); - } + } - return rc; + return rc; } int jt_obd_getattr(int argc, char **argv) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; __u64 objid; - char *end; - int rc; + char *end; + int rc; - if (argc != 2) - return CMD_HELP; + if (argc != 2) + return CMD_HELP; objid = strtoull(argv[1], &end, 0); if (*end) { @@ -1810,82 +1807,82 @@ int jt_obd_getattr(int argc, char **argv) printf("%s: object id %#jx\n", jt_cmdname(argv[0]), (uintmax_t)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; - } - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf); - obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); - if (rc) { - fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), - strerror(rc = errno)); - } else { + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_GETATTR, buf); + llapi_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 %ju, mode %o\n", jt_cmdname(argv[0]), (uintmax_t)ostid_id(&data.ioc_obdo1.o_oi), data.ioc_obdo1.o_mode); - } - return rc; + } + return rc; } 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; + 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; + int verbose = 1; __u64 objid = 3; - char *end; - int rc = 0; + char *end; + int rc = 0; - if (argc < 2 || argc > 4) - return CMD_HELP; + if (argc < 2 || argc > 4) + return CMD_HELP; - 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", - jt_cmdname(argv[0]), argv[1]); - return CMD_HELP; - } + 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", + jt_cmdname(argv[0]), argv[1]); + return CMD_HELP; + } - if (argc >= 3) { - verbose = get_verbose(argv[0], argv[2]); - if (verbose == BAD_VERBOSE) - return CMD_HELP; - } + if (argc >= 3) { + verbose = get_verbose(argv[0], argv[2]); + if (verbose == BAD_VERBOSE) + return CMD_HELP; + } - if (argc >= 4) { - if (argv[3][0] == 't') { - objid = strtoull(argv[3] + 1, &end, 0); - if (thread) - objid += thread - 1; - } else - objid = strtoull(argv[3], &end, 0); - if (*end) { - fprintf(stderr, "error: %s: invalid objid '%s'\n", - jt_cmdname(argv[0]), argv[3]); - return CMD_HELP; - } - } + if (argc >= 4) { + if (argv[3][0] == 't') { + objid = strtoull(argv[3] + 1, &end, 0); + if (thread) + objid += thread - 1; + } else + objid = strtoull(argv[3], &end, 0); + if (*end) { + fprintf(stderr, "error: %s: invalid objid '%s'\n", + jt_cmdname(argv[0]), argv[3]); + return CMD_HELP; + } + } - gettimeofday(&start, NULL); - next_time.tv_sec = start.tv_sec - verbose; - next_time.tv_usec = start.tv_usec; - if (verbose != 0) + gettimeofday(&start, NULL); + next_time.tv_sec = start.tv_sec - verbose; + next_time.tv_usec = start.tv_usec; + if (verbose != 0) printf("%s: getting %jd attrs (objid %#jx): %s", - jt_cmdname(argv[0]), (uintmax_t) count, + jt_cmdname(argv[0]), (uintmax_t)count, (uintmax_t)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++) { + for (i = 1, next_count = verbose; i <= count && shmem_running(); i++) { if (objid >= OBIF_MAX_OID) { fprintf(stderr, "errr: %s: invalid objid '%llu'\n", - jt_cmdname(argv[0]), objid); + jt_cmdname(argv[0]), (unsigned long long)objid); return -E2BIG; } @@ -1893,42 +1890,41 @@ int jt_obd_test_getattr(int argc, char **argv) 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)); + rc = llapi_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(1); - if (rc < 0) { + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data); + shmem_bump(1); + if (rc < 0) { fprintf(stderr, "error: %s: #%jd - %d:%s\n", jt_cmdname(argv[0]), (uintmax_t)i, errno, strerror(rc = errno)); - break; - } else { - if (be_verbose - (verbose, &next_time, i, &next_count, count)) - printf("%s: got attr #%jd\n", - jt_cmdname(argv[0]), (uintmax_t)i); - } - } + break; + } + if (be_verbose(verbose, &next_time, i, &next_count, count)) + printf("%s: got attr #%jd\n", + jt_cmdname(argv[0]), (uintmax_t)i); + } - if (!rc) { - struct timeval end; - double diff; + if (!rc) { + struct timeval end; + double diff; - gettimeofday(&end, NULL); + gettimeofday(&end, NULL); - diff = difftime(&end, &start); + diff = difftime(&end, &start); - --i; - if (verbose != 0) + --i; + if (verbose != 0) printf("%s: %jd attrs in %.3fs (%.3f attr/s): %s", - jt_cmdname(argv[0]), (uintmax_t) i, diff, + jt_cmdname(argv[0]), (uintmax_t)i, diff, i / diff, ctime(&end.tv_sec)); - } - return rc; + } + + return rc; } /* test_brw count @@ -2098,7 +2094,7 @@ int jt_obd_test_brw(int argc, char **argv) ostid_set_seq_echo(&data.ioc_obdo1.o_oi); if (objid >= OBIF_MAX_OID) { fprintf(stderr, "errr: %s: invalid objid '%llu'\n", - jt_cmdname(argv[0]), objid); + jt_cmdname(argv[0]), (unsigned long long)objid); return -E2BIG; } @@ -2120,24 +2116,25 @@ int jt_obd_test_brw(int argc, char **argv) (uintmax_t)count, pages, (uintmax_t) objid, (uintmax_t)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 && shmem_running(); i++) { - data.ioc_obdo1.o_valid &= ~(OBD_MD_FLBLOCKS|OBD_MD_FLGRANT); - 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(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)) { + 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); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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, cmd, buf); + 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 @ %jd:%ju for %d\n", jt_cmdname(argv[0]), write ? "write" : "read", i, @@ -2145,7 +2142,7 @@ int jt_obd_test_brw(int argc, char **argv) (uintmax_t)data.ioc_offset, (int)(pages * getpagesize())); shmem_unlock (); - } + } if (!repeat_offset) { #ifdef MAX_THREADS @@ -2219,7 +2216,7 @@ int jt_obd_lov_getconfig(int argc, char **argv) memset(&desc, 0, sizeof(desc)); obd_str2uuid(&desc.ld_uuid, argv[1]); - desc.ld_tgt_count = ((OBD_MAX_IOCTL_BUFFER-sizeof(data)-sizeof(desc)) / + desc.ld_tgt_count = ((MAX_IOC_BUFLEN-sizeof(data)-sizeof(desc)) / (sizeof(*uuidarray) + sizeof(*obdgens))); repeat: @@ -2246,26 +2243,26 @@ repeat: data.ioc_inllen3 = desc.ld_tgt_count * sizeof(*obdgens); data.ioc_inlbuf3 = (char *)obdgens; - if (obd_ioctl_pack(&data, &buf, sizeof(rawbuf))) { - fprintf(stderr, "error: %s: invalid ioctl\n", - jt_cmdname(argv[0])); - rc = -EINVAL; - goto out_obdgens; - } - rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); - if (rc == -ENOSPC) { - free(uuidarray); - free(obdgens); - goto repeat; - } else if (rc) { - fprintf(stderr, "error: %s: ioctl error: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - } else { - struct obd_uuid *uuidp; - __u32 *genp; - int i; + if (llapi_ioctl_pack(&data, &buf, sizeof(rawbuf))) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + rc = -EINVAL; + goto out_obdgens; + } + rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); + if (rc == -ENOSPC) { + free(uuidarray); + free(obdgens); + goto repeat; + } else if (rc) { + fprintf(stderr, "error: %s: ioctl error: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + } else { + struct obd_uuid *uuidp; + __u32 *genp; + int i; - if (obd_ioctl_unpack(&data, buf, sizeof(rawbuf))) { + if (llapi_ioctl_unpack(&data, buf, sizeof(rawbuf))) { fprintf(stderr, "error: %s: invalid reply\n", jt_cmdname(argv[0])); rc = -EINVAL; @@ -2278,7 +2275,7 @@ repeat: desc.ld_default_stripe_count); printf("default_stripe_size: %ju\n", (uintmax_t)desc.ld_default_stripe_size); - printf("default_stripe_offset: %ju\n", + printf("default_stripe_offset: %jd\n", (uintmax_t)desc.ld_default_stripe_offset); printf("default_stripe_pattern: %u\n", desc.ld_pattern); printf("obd_count: %u\n", desc.ld_tgt_count); @@ -2299,31 +2296,31 @@ out: static int do_activate(int argc, char **argv, int flag) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; - if (argc != 1) - return CMD_HELP; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (argc != 1) + return CMD_HELP; - /* reuse offset for 'active' */ - data.ioc_offset = flag; + /* reuse offset for 'active' */ + data.ioc_offset = flag; - 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", - jt_cmdname(argv[0]), strerror(rc = errno)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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, IOC_OSC_SET_ACTIVE, buf); + if (rc) + fprintf(stderr, "error: %s: failed: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); - return rc; + return rc; } /** @@ -2340,8 +2337,8 @@ static int do_activate(int argc, char **argv, int flag) * are skipped and recorded with new nids and uuid. * * \see mgs_replace_nids - * \see mgs_replace_nids_log - * \see mgs_replace_handler + * \see mgs_replace_log + * \see mgs_replace_nids_handler */ int jt_replace_nids(int argc, char **argv) { @@ -2360,14 +2357,60 @@ int jt_replace_nids(int argc, char **argv) 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)); + rc = llapi_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_REPLACE_NIDS, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); + } + + return rc; +} + +/** + * Clear config logs for given device or filesystem. + * lctl clear_conf + * Command has to be run on MGS node having MGS device mounted with -o + * nosvc. + * + * Configuration logs for filesystem or one particular log is + * processed. New log is created, original log is read, its records + * marked SKIP do not get copied to new log. Others are copied as-is. + * Original file is renamed to log.${time}.bak. + * + * \see mgs_clear_configs + * \see mgs_replace_log + * \see mgs_clear_config_handler + **/ +int jt_lcfg_clear(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 != 2) + return CMD_HELP; + + data.ioc_inllen1 = strlen(argv[1]) + 1; + data.ioc_inlbuf1 = argv[1]; + + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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); + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEAR_CONFIGS, buf); if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -2378,91 +2421,91 @@ int jt_replace_nids(int argc, char **argv) int jt_obd_deactivate(int argc, char **argv) { - return do_activate(argc, argv, 0); + return do_activate(argc, argv, 0); } int jt_obd_activate(int argc, char **argv) { - return do_activate(argc, argv, 1); + return do_activate(argc, argv, 1); } int jt_obd_recover(int argc, char **argv) { - int rc; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + struct obd_ioctl_data data; + int rc; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; - if (argc > 2) - return CMD_HELP; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + if (argc > 2) + return CMD_HELP; - if (argc == 2) { - data.ioc_inllen1 = strlen(argv[1]) + 1; - data.ioc_inlbuf1 = argv[1]; - } + if (argc == 2) { + data.ioc_inllen1 = strlen(argv[1]) + 1; + data.ioc_inlbuf1 = argv[1]; + } - 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]), - strerror(rc = errno)); - } + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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_CLIENT_RECOVER, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), + strerror(rc = errno)); + } - return rc; + return rc; } 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; + struct obd_ioctl_data data; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + char *parent, *child; + int rc, fd, verbose = 1; - if (argc < 3 || argc > 4) - return CMD_HELP; + if (argc < 3 || argc > 4) + return CMD_HELP; - parent = argv[1]; - child = argv[2]; - if (argc == 4) - verbose = get_verbose(argv[0], argv[3]); + parent = argv[1]; + child = argv[2]; + if (argc == 4) + verbose = get_verbose(argv[0], argv[3]); - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; - data.ioc_inllen1 = strlen(child) + 1; - data.ioc_inlbuf1 = child; + data.ioc_inllen1 = strlen(child) + 1; + data.ioc_inlbuf1 = child; - 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; - } + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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) { - fprintf(stderr, "open \"%s\" failed: %s\n", parent, - strerror(errno)); - return -1; - } + fd = open(parent, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "open \"%s\" failed: %s\n", parent, + strerror(errno)); + return -1; + } - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); - if (rc < 0) { - fprintf(stderr, "error: %s: ioctl error: %s\n", - jt_cmdname(argv[0]), strerror(rc = errno)); - } - close(fd); + rc = ioctl(fd, IOC_MDC_LOOKUP, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: ioctl error: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + } + close(fd); - if (verbose) { - rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + if (verbose) { + rc = llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "error: %s: invalid reply\n", jt_cmdname(argv[0])); @@ -2493,7 +2536,7 @@ int jt_lcfg_fork(int argc, char **argv) data.ioc_inlbuf2 = argv[2]; memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "error: %s: invalid ioctl\n", jt_cmdname(argv[0])); @@ -2528,7 +2571,7 @@ int jt_lcfg_erase(int argc, char **argv) data.ioc_inlbuf1 = argv[1]; memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "error: %s: invalid ioctl\n", jt_cmdname(argv[0])); @@ -2554,149 +2597,408 @@ int jt_llog_catlist(int argc, char **argv) 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); - else - fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", - strerror(errno)); + data.ioc_inllen1 = sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(data), 8); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_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); + else + fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", + strerror(errno)); - return rc; + return rc; } int jt_llog_info(int argc, char **argv) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; + const struct option long_opts[] = { + /* Allow optional "--catalog" for compatibility with llog commands. */ + { .val = 'c', .name = "catalog", .has_arg = required_argument }, + { .val = 'h', .name = "help", .has_arg = no_argument }, + { .name = NULL } }; + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN] = "", *buf = rawbuf; + char *cmd = argv[0]; + char *catalog = NULL; + int rc, c; - if (argc != 2) - return CMD_HELP; + while ((c = getopt_long(argc, argv, "c:h", long_opts, NULL)) != -1) { + switch (c) { + case 'c': + catalog = optarg; + break; + case 'h': + default: + return CMD_HELP; + } + } + argc -= optind; + argv += optind; + /* support "logname" positional parameter */ + if (argc == 1) { + if (catalog) { + fprintf(stderr, + "%s: catalog is set, unknown argument '%s'\n", + cmd, optarg); + return CMD_HELP; + } + catalog = argv[0]; + } else if (!catalog || argc > 1) { + 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]; - 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; - } + data.ioc_dev = cur_device; + data.ioc_inllen1 = strlen(catalog) + 1; + data.ioc_inlbuf1 = catalog; + data.ioc_inllen2 = sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(data), 8) - + __ALIGN_KERNEL(data.ioc_inllen1, 8); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: ioctl_pack failed for catalog '%s': %s\n", + jt_cmdname(cmd), catalog, strerror(-rc)); + return rc; + } - 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)); + 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, "%s: OBD_IOC_LLOG_INFO failed: %s\n", + jt_cmdname(cmd), strerror(errno)); - return rc; + return rc; } -int jt_llog_print(int argc, char **argv) +int jt_llog_print_cb(const char *record, void *private) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; + printf("%s\n", record); - if (argc != 2 && argc != 4) - return CMD_HELP; + return 0; +} - 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) { - 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; - } +static int +llog_process_records(int (record_cb)(const char *record, void *private), + const char *record, void *private, bool reverse) +{ + char *ptr = NULL; + char *tmp = NULL; + int rc = 0; + + if (!reverse) { + do { + ptr = strchr(record, '\n'); + if (ptr) + *ptr = '\0'; + rc = record_cb(record, private); + if (rc) + goto out; + if (ptr) + record = ptr + 1; + } while (ptr && *(ptr + 1)); + } else { + tmp = (char *)record; - 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)); + ptr = strrchr(record, '\n'); + if (ptr) + *ptr = '\0'; + else + goto out; + while ((ptr = strrchr(record, '\n'))) { + tmp = ptr + 1; + *ptr = '\0'; + rc = record_cb(tmp, private); + if (rc) + goto out; + }; + rc = record_cb(record, private); + if (rc) + goto out; + } +out: + return rc; +} - return rc; +/** + * Iterate over llog records, typically YAML-formatted configuration logs + * + * \param logname[in] name of llog file or FID + * \param start[in] first record to process + * \param end[in] last record to process (inclusive) + * \param cb[in] callback for records. Return -ve error, or +ve abort. + * \param private[in,out] private data passed to the \a record_cb function + * \param reverse[in] print the llog records from the beginning or the end + * + * \retval 0 on success + * others handled by the caller + */ +int jt_llog_print_iter(char *logname, long start, long end, + int (record_cb)(const char *record, void *private), + void *private, bool reverse) +{ + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + char startbuf[16], endbuf[16]; + static long inc = sizeof(rawbuf) / 128; + long rec; + int rc = 0; + + if (end == -1) + end = 0x7fffffff; + + data.ioc_dev = cur_device; + data.ioc_inlbuf1 = logname; + data.ioc_inllen1 = strlen(logname) + 1; + + /* + * Estimate about 128 characters per configuration record. Not all + * records will be printed in any case, so they should easily fit. If + * not, the kernel will return -EOVERFLOW and ask for fewer records. + * + * We don't want to request records from the kernel one-at-a-time, as + * it restarts the config llog iteration from the beginning, so we + * fetch multiple records from the kernel per call and split locally. + */ + for (rec = start; rec < end; rec += inc) { + char *record = ((struct obd_ioctl_data *)buf)->ioc_bulk; + +retry: + snprintf(startbuf, sizeof(startbuf), "%lu", rec); + snprintf(endbuf, sizeof(endbuf), "%lu", + end < rec + inc - 1 ? end : rec + inc - 1); + + /* start and end record numbers are passed as ASCII digits */ + data.ioc_inlbuf2 = startbuf; + data.ioc_inllen2 = strlen(startbuf) + 1; + data.ioc_inlbuf3 = endbuf; + data.ioc_inllen3 = strlen(endbuf) + 1; + + data.ioc_inllen4 = sizeof(rawbuf) - + __ALIGN_KERNEL(sizeof(data), 8) - + __ALIGN_KERNEL(data.ioc_inllen1, 8) - + __ALIGN_KERNEL(data.ioc_inllen2, 8) - + __ALIGN_KERNEL(data.ioc_inllen3, 8); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: invalid ioctl data\n", logname); + goto out; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_PRINT, buf); + if (rc == -EOVERFLOW && inc > 2) { + inc /= 2; + goto retry; + } + if (rc) { + fprintf(stderr, "%s: OBD_IOC_LLOG_PRINT failed: %s\n", + logname, strerror(errno)); + rc = -errno; + goto out; + } + + /* There is no "end of list" marker, record was not modified */ + if (strcmp(record, logname) == 0) + break; + + rc = llog_process_records(record_cb, record, private, reverse); + if (rc) + goto out; + } + +out: + return rc; } -static int llog_cancel_parse_optional(int argc, char **argv, - struct obd_ioctl_data *data) +static int llog_parse_catalog_start_end(int *argc, char **argv[], + char **catalog, long *start, long *end) { - int cOpt; - const char *const short_opts = "c:l:i:h"; const struct option long_opts[] = { + /* the --catalog option is not required, just for consistency */ + { .val = 'c', .name = "catalog", .has_arg = required_argument }, + { .val = 'e', .name = "end", .has_arg = required_argument }, + { .val = 'h', .name = "help", .has_arg = no_argument }, + { .val = 's', .name = "start", .has_arg = required_argument }, + { .name = NULL } }; + char *cmd = (*argv)[0]; + char *endp; + int c; + + if (catalog == NULL || start == NULL || end == NULL) + return -EINVAL; + + /* now process command line arguments*/ + while ((c = getopt_long(*argc, *argv, "c:e:hs:", + long_opts, NULL)) != -1) { + switch (c) { + case 'c': + *catalog = optarg; + break; + case 'e': + *end = strtol(optarg, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "%s: bad end value '%s'\n", + cmd, optarg); + return CMD_HELP; + } + break; + case 's': + *start = strtol(optarg, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "%s: bad start value '%s'\n", + cmd, optarg); + return CMD_HELP; + } + break; + case 'h': + default: + return CMD_HELP; + } + } + *argc -= optind; + *argv += optind; + + /* support old optional positional parameters only if they were + * not already specified with named arguments: logname [start [end]] + */ + if (*argc >= 1) { + if (*catalog) { + fprintf(stderr, + "%s: catalog is set, unknown argument '%s'\n", + cmd, (*argv)[0]); + return CMD_HELP; + } + *catalog = (*argv)[0]; + (*argc)--; + (*argv)++; + } + + if (*argc >= 1) { + if (*start != 1) { + fprintf(stderr, + "%s: --start is set, unknown argument '%s'\n", + cmd, (*argv)[0]); + return CMD_HELP; + } + + *start = strtol((*argv)[0], &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "%s: bad start value '%s'\n", + cmd, (*argv)[0]); + return CMD_HELP; + } + (*argc)--; + (*argv)++; + } + if (*argc >= 1) { + if (*end != -1) { + fprintf(stderr, + "%s: --end is set, unknown argument '%s'\n", + cmd, (*argv)[0]); + return CMD_HELP; + } + + *end = strtol((*argv)[0], &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "%s: bad end value '%s'\n", + cmd, (*argv)[0]); + return CMD_HELP; + } + (*argc)--; + (*argv)++; + } + if (*argc > 1) { + fprintf(stderr, "%s: unknown argument '%s'\n", cmd, (*argv)[0]); + return CMD_HELP; + } + + if (*end != -1 && *end < *start) { + fprintf(stderr, "%s: end '%lu' less than than start '%lu'\n", + cmd, *end, *start); + return CMD_HELP; + } + + return 0; +} + +int jt_llog_print(int argc, char **argv) +{ + char *catalog = NULL; + long start = 1, end = -1; + int rc; + + rc = llog_parse_catalog_start_end(&argc, &argv, &catalog, &start, &end); + if (rc) + return rc; + + rc = jt_llog_print_iter(catalog, start, end, jt_llog_print_cb, + NULL, false); + + return rc; +} + +/* Parse catalog, log ID, and optionally a log index with either optional + * arguments or positional arguments. Only the initial catalog argument + * may be positional with other optional arguments. + * + * The positional arguments option should eventually be phased out. + */ +static int llog_parse_catalog_log_idx(int *argc, char ***argv, const char *opts, + int max_args, struct obd_ioctl_data *data) +{ + const struct option long_opts[] = { + /* the --catalog option is not required, just for consistency */ { .val = 'c', .name = "catalog", .has_arg = required_argument }, { .val = 'h', .name = "help", .has_arg = no_argument }, { .val = 'i', .name = "log_idx", .has_arg = required_argument }, { .val = 'l', .name = "log_id", .has_arg = required_argument }, { .name = NULL } }; + int c; /* sanity check */ - if (!data || argc <= 1) { + if (!data || *argc <= 1) return -1; - } - /*now process command line arguments*/ - while ((cOpt = getopt_long(argc, argv, short_opts, - long_opts, NULL)) != -1) { - switch (cOpt) { + data->ioc_dev = cur_device; + + /* now process command line arguments*/ + while ((c = getopt_long(*argc, *argv, opts, long_opts, NULL)) != -1) { + switch (c) { 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 'l': /* The log_id option isn't currently needed for + * cancel as mdt_iocontrol() handles IOC_LLOG_CANCEL, + * but we may as well keep it for now. + */ + data->ioc_inllen2 = strlen(optarg) + 1; + data->ioc_inlbuf2 = optarg; + break; case 'h': default: - return -1; + return CMD_HELP; } } - if ((data->ioc_inlbuf1 == NULL) || (data->ioc_inlbuf3 == NULL)) { - /* missing mandatory parameters */ - return -1; + *argc -= optind; + *argv += optind; + + /* Allow catalog to be specified as first option without --catalog */ + if (data->ioc_inlbuf1 == NULL && *argc > 0) { + data->ioc_inlbuf1 = (*argv)[0]; + data->ioc_inllen1 = strlen((*argv)[0]) + 1; + (*argc)--; + (*argv)++; } return 0; @@ -2704,183 +3006,516 @@ static int llog_cancel_parse_optional(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, i; + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN] = "", *buf = rawbuf; + char *cmd = argv[0]; + int rc; - /* 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. + /* Parse catalog file (in inlbuf1) and named parameters */ + rc = llog_parse_catalog_log_idx(&argc, &argv, "c:hi:l:", 3, &data); + + /* Handle old positional parameters if not using named parameters, + * either " " or " ". + * It was "inlbuf3 = log_idx", and "inlbuf2 = log_id" (ignored by + * config log cancel), and shows why I hate positional parameters. */ - memset(&data, 0, sizeof(data)); + if (argc == 1) { + data.ioc_inllen3 = strlen(argv[0]) + 1; + data.ioc_inlbuf3 = argv[0]; + } else if (argc == 2) { + data.ioc_inllen2 = strlen(argv[0]) + 1; + data.ioc_inlbuf2 = argv[0]; + data.ioc_inllen3 = strlen(argv[1]) + 1; + data.ioc_inlbuf3 = argv[1]; + } + + if (data.ioc_inlbuf1 == NULL || data.ioc_inlbuf3 == NULL) + /* missing mandatory parameters */ + return CMD_HELP; + + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: ioctl_pack for catalog '%s' failed: %s\n", + jt_cmdname(cmd), data.ioc_inlbuf1, strerror(-rc)); + return rc; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CANCEL, buf); + if (rc) + fprintf(stderr, "%s: cancel catalog '%s:%s' failed: %s\n", + jt_cmdname(cmd), data.ioc_inlbuf1, data.ioc_inlbuf3, + strerror(errno)); + + return rc; +} + +int jt_llog_check(int argc, char **argv) +{ + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN] = "", *buf = rawbuf; + char *catalog = NULL; + char startbuf[16], endbuf[16]; + long start = 1, end = -1; + char *cmd = argv[0]; + int rc; + + rc = llog_parse_catalog_start_end(&argc, &argv, &catalog, &start, &end); + if (rc) + return rc; + + if (end == -1) + end = 0x7fffffff; + + data.ioc_dev = cur_device; + data.ioc_inllen1 = strlen(catalog) + 1; + data.ioc_inlbuf1 = catalog; + + snprintf(startbuf, sizeof(startbuf), "%lu", start); + snprintf(endbuf, sizeof(endbuf), "%lu", end); + /* start and end record numbers are passed as ASCII digits */ + data.ioc_inllen2 = strlen(startbuf) + 1; + data.ioc_inlbuf2 = startbuf; + data.ioc_inllen3 = strlen(endbuf) + 1; + data.ioc_inlbuf3 = endbuf; + + data.ioc_inllen4 = sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(data), 8) - + __ALIGN_KERNEL(data.ioc_inllen1, 8) - + __ALIGN_KERNEL(data.ioc_inllen2, 8) - + __ALIGN_KERNEL(data.ioc_inllen3, 8); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: ioctl_pack failed for catalog '%s': %s\n", + jt_cmdname(cmd), data.ioc_inlbuf1, strerror(-rc)); + return rc; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CHECK, buf); + if (rc == 0) + fprintf(stdout, "%s", ((struct obd_ioctl_data *)buf)->ioc_bulk); + else + fprintf(stderr, "%s: OBD_IOC_LLOG_CHECK failed: %s\n", + jt_cmdname(cmd), strerror(errno)); + return rc; +} + +int jt_llog_remove(int argc, char **argv) +{ + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN] = "", *buf = rawbuf; + char *cmd = argv[0]; + int rc; + + rc = llog_parse_catalog_log_idx(&argc, &argv, "c:hl:", 2, &data); + if (rc) + return rc; + + if (argc == 1) { + if (data.ioc_inlbuf2) { + fprintf(stderr, + "%s: --log_id is set, unknown argument '%s'\n", + jt_cmdname(cmd), argv[0]); + return CMD_HELP; + } + + data.ioc_inllen2 = strlen(argv[0]) + 1; + data.ioc_inlbuf2 = argv[0]; + } + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: ioctl_pack for catalog '%s' failed: %s\n", + jt_cmdname(cmd), data.ioc_inlbuf1, strerror(-rc)); + return rc; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_REMOVE, buf); + if (rc) + fprintf(stderr, "%s: cancel catalog '%s:%s' failed: %s\n", + jt_cmdname(cmd), data.ioc_inlbuf1, data.ioc_inlbuf2, + strerror(-rc)); + + 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); + } +} + +int obd_initialize(int argc, char **argv) +{ + if (shmem_setup() != 0) + return -1; + + register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH); + + 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_cleanup(); + do_disconnect(argv[0], 1); +} + +/** + * Get the index of the last llog record + * + * logid: [0x3:0xa:0x0]:0 + * flags: 4 (plain) + * records_count: 57 + * last_index: 57 + * + * \param logname[in] pointer to config log name + * + * \retval > 0 on success + * <= 0 on error + */ +static long llog_last_index(char *logname) +{ + struct obd_ioctl_data data = { 0 }; + char rawbuf[MAX_IOC_BUFLEN] = "", *buf = rawbuf; + char *last_index; + long rc; + data.ioc_dev = cur_device; + data.ioc_inllen1 = strlen(logname) + 1; + data.ioc_inlbuf1 = logname; + data.ioc_inllen2 = sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(data), 8) - + __ALIGN_KERNEL(data.ioc_inllen1, 8); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "%s: ioctl_pack failed for catalog '%s': %s\n", + __func__, logname, strerror(-rc)); + return rc; + } + + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf); + if (rc == 0) { + last_index = strstr(((struct obd_ioctl_data *)buf)->ioc_bulk, + "last_index:"); + return strtol(last_index + 11, NULL, 10); + } else { + rc = -errno; + } + + return rc; +} + +static char *get_llog_event_name(__u32 cmd) +{ + struct lcfg_type_data *data; + + data = lcfg_cmd2data(cmd); + if (data) + return data->ltd_name; + return NULL; +} + +static char *get_event_filter(__u32 cmd) +{ + char *event_name; + char *filter = NULL; + int len; + + event_name = get_llog_event_name(cmd); + if (event_name) { + /* 9 bytes for "event: , " */ + len = 9 + strlen(event_name); + filter = malloc(len + 1); + if (!filter) + return NULL; + memset(filter, 0, len + 1); + snprintf(filter, len, "event: %s, ", event_name); + return filter; + } + + return NULL; +} + +/** + * Callback to search ostname in llog + * - { index: 23, event: attach, device: lustre-OST0000-osc, type: osc, + * UUID: lustre-clilov_UUID } + * - { index: 24, event: setup, device: lustre-OST0000-osc, + * UUID: lustre-OST0000_UUID, node: 192.168.0.120@tcp } + * - { index: 25, event: add_osc, device: lustre-clilov, + * ost: lustre-OST0000_UUID, index: 0, gen: 1 } + * + * \param record[in] pointer to llog record + * \param data[in] pointer to ostname + * + * \retval 1 if ostname is found + * 0 if ostname is not found + * -ENOENT if ostname is deleted + */ +static int llog_search_ost_cb(const char *record, void *data) +{ + char *ostname = data; + char ost_filter[MAX_STRING_SIZE] = {'\0'}; + char *add_osc, *del_osc, *setup, *cleanup; + + add_osc = get_event_filter(LCFG_LOV_ADD_OBD); + del_osc = get_event_filter(LCFG_LOV_DEL_OBD); + setup = get_event_filter(LCFG_SETUP); + cleanup = get_event_filter(LCFG_CLEANUP); + if (!add_osc || !del_osc || !setup || !cleanup) + return -ENOMEM; + + if (ostname && ostname[0]) + snprintf(ost_filter, sizeof(ost_filter), " %s,", ostname); + + if (strstr(record, ost_filter)) { + if (strstr(record, add_osc) || strstr(record, setup)) + return 1; + if (strstr(record, del_osc) || strstr(record, cleanup)) + return -ENOENT; + } + + free(add_osc); + free(del_osc); + free(setup); + free(cleanup); + + return 0; +} + +/** + * Search ost in llog + * + * \param logname[in] pointer to config log name + * \param last_index[in] the index of the last llog record + * \param ostname[in] pointer to ost name + * + * \retval 1 if ostname is found + * 0 if ostname is not found + */ +static int llog_search_ost(char *logname, long last_index, char *ostname) +{ + long start, end, inc = MAX_IOC_BUFLEN / 128; + int rc = 0; + + for (end = last_index; end > 1; end -= inc) { + start = end - inc > 0 ? end - inc : 1; + rc = jt_llog_print_iter(logname, start, end, llog_search_ost_cb, + ostname, true); + if (rc) + break; + } + + return (rc == 1 ? 1 : 0); +} + +struct llog_pool_data { + char lpd_fsname[LUSTRE_MAXFSNAME + 1]; + char lpd_poolname[LOV_MAXPOOLNAME + 1]; + char lpd_ostname[MAX_OBD_NAME + 1]; + enum lcfg_command_type lpd_cmd_type; + bool lpd_pool_exists; + int lpd_ost_num; +}; + +/** + * Called for each formatted line in the config log (within range). + * + * - { index: 74, event: new_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * - { index: 77, event: add_pool, device: tfs-clilov, fsname: tfs, pool: tmp, + * ost: tfs-OST0000_UUID } + * - { index: 224, event: remove_pool, device: tfs-clilov, fsname: tfs, + * pool: tmp, ost: tfs-OST0003_UUID } + * - { index: 227, event: del_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * + * \param record[in] pointer to llog record + * \param data[in] pointer to llog_pool_data + * + * \retval 1 if pool or OST is found + * 0 if pool or OST is not found + * -ENOENT if pool or OST is removed + */ +static int llog_search_pool_cb(const char *record, void *data) +{ + struct llog_pool_data *lpd = data; + char pool_filter[MAX_STRING_SIZE] = ""; + char *new_pool, *del_pool, *add_pool, *rem_pool; + char *found = NULL; + int fs_pool_len = 0, rc = 0; + + new_pool = get_event_filter(LCFG_POOL_NEW); + del_pool = get_event_filter(LCFG_POOL_DEL); + add_pool = get_event_filter(LCFG_POOL_ADD); + rem_pool = get_event_filter(LCFG_POOL_REM); + if (!new_pool || !del_pool || !add_pool || !rem_pool) { + rc = -ENOMEM; + goto out; + } - if (argc == 3 || argc == 4) { - for (i = 1; i < argc; i++) { - if (argv[i][0] == '-') - return CMD_HELP; + fs_pool_len = 16 + strlen(lpd->lpd_fsname) + strlen(lpd->lpd_poolname); + snprintf(pool_filter, fs_pool_len + 1, "fsname: %s, pool: %s", + lpd->lpd_fsname, lpd->lpd_poolname); + + /* search poolname */ + found = strstr(record, pool_filter); + if (found && + (found[fs_pool_len] == ' ' || found[fs_pool_len] == ',')) { + if (strstr(record, new_pool)) { + lpd->lpd_pool_exists = true; + rc = 1; + goto out; } - 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]; + if (strstr(record, del_pool)) { + lpd->lpd_pool_exists = false; + rc = -ENOENT; + goto out; } - } 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; + if (lpd->lpd_cmd_type == LCFG_POOL_NEW || + lpd->lpd_cmd_type == LCFG_POOL_DEL) { + if (strstr(record, add_pool)) + lpd->lpd_ost_num++; + if (strstr(record, rem_pool)) + lpd->lpd_ost_num--; + } else if (lpd->lpd_ostname && lpd->lpd_ostname[0]) { + if (strstr(record, lpd->lpd_ostname)) { + lpd->lpd_pool_exists = true; + if (strstr(record, add_pool)) { + lpd->lpd_ost_num = 1; + rc = 1; + goto out; + } + if (strstr(record, rem_pool)) { + lpd->lpd_ost_num = 0; + rc = -ENOENT; + goto out; + } + } + } } - - 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)); +out: + if (new_pool) + free(new_pool); + if (del_pool) + free(del_pool); + if (add_pool) + free(add_pool); + if (rem_pool) + free(rem_pool); return rc; } -int jt_llog_check(int argc, char **argv) +/* Search pool and its ost in llog + * + * \param logname[in] pointer to config log name + * \param last_index[in] the index of the last llog record + * \param fsname[in] pointer to filesystem name + * \param poolname[in] pointer pool name + * \param ostname[in] pointer to OST name(OSTnnnn-UUID) + * \param cmd[in] pool command type + * + * \retval < 0 on error + * 0 if pool is empty or OST is not found + * 1 if pool is not empty or OST is found + */ +static int llog_search_pool(char *logname, long last_index, char *fsname, + char *poolname, char *ostname, + enum lcfg_command_type cmd) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; - - if (argc != 2 && argc != 4) - 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]; - 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; - } + struct llog_pool_data lpd; + long start, end, inc = MAX_IOC_BUFLEN / 128; + int rc = 0; + + memset(&lpd, 0, sizeof(lpd)); + lpd.lpd_cmd_type = cmd; + lpd.lpd_pool_exists = false; + lpd.lpd_ost_num = 0; + strncpy(lpd.lpd_fsname, fsname, sizeof(lpd.lpd_fsname) - 1); + if (poolname && poolname[0]) + strncpy(lpd.lpd_poolname, poolname, + sizeof(lpd.lpd_poolname) - 1); + if (ostname && ostname[0]) + strncpy(lpd.lpd_ostname, ostname, sizeof(lpd.lpd_ostname) - 1); + + for (end = last_index; end > 1; end -= inc) { + start = end - inc > 0 ? end - inc : 1; + rc = jt_llog_print_iter(logname, start, end, + llog_search_pool_cb, &lpd, true); + if (rc) { + if (rc == 1 && lpd.lpd_pool_exists) + rc = lpd.lpd_ost_num ? 1 : 0; + else if (rc == -ENOENT && lpd.lpd_pool_exists && + !lpd.lpd_ost_num) + rc = 0; + goto out; + } + } - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CHECK, buf); - if (rc == 0) - fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk); - else - fprintf(stderr, "OBD_IOC_LLOG_CHECK failed: %s\n", - strerror(errno)); - return rc; + rc = -ENOENT; +out: + return rc; } -int jt_llog_remove(int argc, char **argv) +static bool combined_mgs_mds(char *fsname) { - struct obd_ioctl_data data; - char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; - int rc; - - if (argc != 3 && 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]; - if (argc == 3){ - 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; - } + glob_t path; + int rc; - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_REMOVE, buf); - if (rc == 0) { - 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)); + rc = cfs_get_param_paths(&path, "mdt/%s-MDT0000", fsname); + if (!rc) + cfs_free_param_data(&path); - return rc; -} + if (get_mgs_device() > 0 && !rc) + return true; -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); + return false; } -int obd_initialize(int argc, char **argv) +/* + * if pool is NULL, search ostname in target_obd + * if pool is not NULL: + * - if pool not found returns errno < 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 + */ +int lctl_search_ost(char *fsname, char *poolname, char *ostname, + enum lcfg_command_type cmd) { - if (shmem_setup() != 0) - return -1; + char logname[MAX_OBD_NAME] = {'\0'}; + long last_index; - register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH, - OBD_DEV_MAJOR, OBD_DEV_MINOR); + if (fsname && fsname[0] == '\0') + fsname = NULL; + if (!fsname) + return -EINVAL; - return 0; -} + if (combined_mgs_mds(fsname)) + return llapi_search_ost(fsname, poolname, ostname); -void obd_finalize(int argc, char **argv) -{ - struct sigaction sigact; + /* fetch the last_index of llog record */ + snprintf(logname, sizeof(logname), "%s-client", fsname); + last_index = llog_last_index(logname); + if (last_index < 0) + return last_index; - /* 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); + /* if pool is NULL, search ostname in target_obd */ + if (!poolname && ostname) + return llog_search_ost(logname, last_index, ostname); - shmem_cleanup(); - do_disconnect(argv[0], 1); + return llog_search_pool(logname, last_index, fsname, poolname, + ostname, cmd); } static int check_pool_cmd(enum lcfg_command_type cmd, @@ -2889,7 +3524,7 @@ static int check_pool_cmd(enum lcfg_command_type cmd, { int rc; - rc = llapi_search_ost(fsname, poolname, ostname); + rc = lctl_search_ost(fsname, poolname, ostname, cmd); if (rc < 0 && (cmd != LCFG_POOL_NEW)) { fprintf(stderr, "Pool %s.%s not found\n", fsname, poolname); @@ -2926,7 +3561,7 @@ static int check_pool_cmd(enum lcfg_command_type cmd, ostname, fsname, poolname); return -EEXIST; } - rc = llapi_search_ost(fsname, NULL, ostname); + rc = lctl_search_ost(fsname, NULL, ostname, cmd); if (rc == 0) { fprintf(stderr, "OST %s is not part of the '%s' fs.\n", ostname, fsname); @@ -2963,7 +3598,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, switch (cmd) { case LCFG_POOL_NEW: { do { - rc = llapi_search_ost(fsname, poolname, NULL); + rc = lctl_search_ost(fsname, poolname, NULL, cmd); if (rc == -ENODEV) return rc; if (rc < 0) @@ -2982,7 +3617,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } case LCFG_POOL_DEL: { do { - rc = llapi_search_ost(fsname, poolname, NULL); + rc = lctl_search_ost(fsname, poolname, NULL, cmd); if (rc == -ENODEV) return rc; if (rc >= 0) @@ -3001,7 +3636,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } case LCFG_POOL_ADD: { do { - rc = llapi_search_ost(fsname, poolname, ostname); + rc = lctl_search_ost(fsname, poolname, ostname, cmd); if (rc == -ENODEV) return rc; if (rc != 1) @@ -3020,7 +3655,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } case LCFG_POOL_REM: { do { - rc = llapi_search_ost(fsname, poolname, ostname); + rc = lctl_search_ost(fsname, poolname, ostname, cmd); if (rc == -ENODEV) return rc; if (rc == 1) @@ -3125,30 +3760,46 @@ static int pool_cmd(enum lcfg_command_type cmd, return -ENOMEM; lustre_cfg_init(lcfg, cmd, &bufs); - memset(&data, 0, sizeof(data)); - rc = data.ioc_dev = get_mgs_device(); - if (rc < 0) - goto out; + 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; + 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)); + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(cmdname)); free(lcfg); - return rc; - } - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_POOL, buf); + return rc; + } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_POOL, buf); out: - if (rc) - rc = -errno; + if (rc) + rc = -errno; + switch (rc) { + case -ENAMETOOLONG: + fprintf(stderr, "error: %s: either the pool or file " + "system name is too long (max pool name len " + "is %d and file system name is %d)\n", + jt_cmdname(cmdname), LOV_MAXPOOLNAME, + LUSTRE_MAXFSNAME); + break; + case -EINVAL: + fprintf(stderr, "error: %s can contain only " + "alphanumeric characters, underscores, and " + "dashes besides the required '.'\n", + jt_cmdname(cmdname)); + default: + break; + } free(lcfg); - return rc; + return rc; } /** @@ -3203,7 +3854,7 @@ static int nodemap_cmd(enum lcfg_command_type cmd, void *ret_data, data.ioc_pbuf1 = (void *)lcfg; memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc != 0) { fprintf(stderr, "error: invalid ioctl: %08x errno: %d with " "rc=%d\n", cmd, errno, rc); @@ -3218,7 +3869,7 @@ static int nodemap_cmd(enum lcfg_command_type cmd, void *ret_data, } if (ret_data != NULL) { - rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + rc = llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (rc != 0) goto out; @@ -3363,32 +4014,15 @@ int jt_nodemap_test_id(int argc, char **argv) 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 - } - }; + static struct option long_opts[] = { + { .val = 'i', .name = "id", .has_arg = required_argument }, + { .val = 'n', .name = "nid", .has_arg = required_argument }, + { .val = 't', .name = "idtype", + .has_arg = required_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "n:t:i:", - long_options, NULL)) != -1) { + long_opts, NULL)) != -1) { switch (c) { case 'n': nidstr = optarg; @@ -3417,6 +4051,51 @@ int jt_nodemap_test_id(int argc, char **argv) } /** + * parse nid range + * + * \param nodemap_range --range string + * \param nid_range nid range string, min_nid:max_nid + * + * \retval 0 on success + */ +static int parse_nid_range(char *nodemap_range, char *nid_range, int range_len) +{ + char min_nid[LNET_NIDSTR_SIZE + 1]; + char max_nid[LNET_NIDSTR_SIZE + 1]; + struct list_head nidlist; + int rc = 0; + + INIT_LIST_HEAD(&nidlist); + + if (cfs_parse_nidlist(nodemap_range, strlen(nodemap_range), + &nidlist) <= 0) { + fprintf(stderr, + "error: nodemap_xxx_range: can't parse nid range: %s\n", + nodemap_range); + return -1; + } + + rc = cfs_nidrange_find_min_max(&nidlist, &min_nid[0], &max_nid[0], + LNET_NIDSTR_SIZE); + if (rc < 0) { + if (rc == -EINVAL) + fprintf(stderr, + "error: nodemap_xxx_range: nid range uses " + "currently unsupported features\n"); + else if (rc == -ERANGE) + fprintf(stderr, + "error: nodemap_xxx_range: nodemap ranges must " + "be contiguous\n"); + + return rc; + } + + snprintf(nid_range, range_len, "%s:%s", min_nid, max_nid); + + return rc; +} + +/** * add an nid range to a nodemap * * \param argc number of args @@ -3431,9 +4110,6 @@ 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; @@ -3443,8 +4119,6 @@ int jt_nodemap_add_range(int argc, char **argv) { .val = 'r', .name = "range", .has_arg = required_argument }, { .name = NULL } }; - INIT_LIST_HEAD(&nidlist); - while ((c = getopt_long(argc, argv, "n:r:", long_opts, NULL)) != -1) { switch (c) { @@ -3463,23 +4137,11 @@ int jt_nodemap_add_range(int argc, char **argv) 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; + rc = parse_nid_range(nodemap_range, nid_range, sizeof(nid_range)); + if (rc) { + errno = -rc; + return rc; } - - 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) { @@ -3507,35 +4169,17 @@ 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); + static struct option long_opts[] = { + { .val = 'n', .name = "name", .has_arg = required_argument }, + { .val = 'r', .name = "range", .has_arg = required_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "n:r:", - long_options, NULL)) != -1) { + long_opts, NULL)) != -1) { switch (c) { case 'n': nodemap_name = optarg; @@ -3552,23 +4196,11 @@ int jt_nodemap_del_range(int argc, char **argv) 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; + rc = parse_nid_range(nodemap_range, nid_range, sizeof(nid_range)); + if (rc) { + errno = -rc; + return rc; } - - 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) { @@ -3604,31 +4236,95 @@ int jt_nodemap_set_fileset(int argc, char **argv) { .val = 'n', .name = "name", .has_arg = required_argument }, { .name = NULL } }; - while ((c = getopt_long(argc, argv, "n:f:", - long_opts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "n:f:", + long_opts, NULL)) != -1) { + switch (c) { + case 'n': + nodemap_name = optarg; + break; + case 'f': + fileset_name = optarg; + break; + } + } + + if (nodemap_name == NULL || fileset_name == NULL) { + fprintf(stderr, "usage: nodemap_set_fileset --name " + "--fileset \n"); + return -1; + } + + rc = nodemap_cmd(LCFG_NODEMAP_SET_FILESET, NULL, 0, argv[0], + nodemap_name, fileset_name, NULL); + if (rc != 0) { + errno = -rc; + fprintf(stderr, "error: %s: cannot set fileset '%s' on nodemap " + "'%s': rc = %d\n", + jt_cmdname(argv[0]), fileset_name, nodemap_name, rc); + } + + return rc; +} + +/** + * set SELinux policy info on a nodemap + * + * \param argc number of args + * \param argv[] variable string arguments + * + * --name nodemap name + * --sepol SELinux policy info + * + * \retval 0 on success + */ +int jt_nodemap_set_sepol(int argc, char **argv) +{ + char *nodemap_name = NULL; + char *sepol = NULL; + int rc = 0; + int c; + + static struct option long_options[] = { + { + .name = "name", + .has_arg = required_argument, + .val = 'n', + }, + { + .name = "sepol", + .has_arg = required_argument, + .val = 's', + }, + { + .name = NULL, + } + }; + + while ((c = getopt_long(argc, argv, "n:s:", + long_options, NULL)) != -1) { switch (c) { case 'n': nodemap_name = optarg; break; - case 'f': - fileset_name = optarg; + case 's': + sepol = optarg; break; } } - if (nodemap_name == NULL || fileset_name == NULL) { - fprintf(stderr, "usage: nodemap_set_fileset --name " - "--fileset \n"); + if (nodemap_name == NULL || sepol == NULL) { + fprintf(stderr, "usage: nodemap_set_sepol --name " + "--sepol \n"); return -1; } - rc = nodemap_cmd(LCFG_NODEMAP_SET_FILESET, NULL, 0, argv[0], - nodemap_name, fileset_name, NULL); + rc = nodemap_cmd(LCFG_NODEMAP_SET_SEPOL, NULL, 0, argv[0], + nodemap_name, sepol, NULL); if (rc != 0) { errno = -rc; - fprintf(stderr, "error: %s: cannot set fileset '%s' on nodemap " + fprintf(stderr, "error: %s: cannot set sepol '%s' on nodemap " "'%s': rc = %d\n", - jt_cmdname(argv[0]), fileset_name, nodemap_name, rc); + jt_cmdname(argv[0]), sepol, nodemap_name, rc); } return rc; @@ -3656,32 +4352,14 @@ int jt_nodemap_modify(int argc, char **argv) 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 - } - }; + static struct option long_opts[] = { + { .val = 'n', .name = "name", .has_arg = required_argument }, + { .val = 'p', .name = "property", .has_arg = required_argument }, + { .val = 'v', .name = "value", .has_arg = required_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "n:p:v:", - long_options, NULL)) != -1) { + long_opts, NULL)) != -1) { switch (c) { case 'n': nodemap_name = optarg; @@ -3699,7 +4377,7 @@ int jt_nodemap_modify(int argc, char **argv) fprintf(stderr, "usage: nodemap_modify --name " "--property --value \n"); fprintf(stderr, "valid properties: admin trusted map_mode " - "squash_uid squash_gid deny_unknown\n"); + "squash_uid squash_gid deny_unknown audit_mode\n"); return -1; } @@ -3715,6 +4393,8 @@ int jt_nodemap_modify(int argc, char **argv) cmd = LCFG_NODEMAP_SQUASH_GID; } else if (strcmp("map_mode", param) == 0) { cmd = LCFG_NODEMAP_MAP_MODE; + } else if (strcmp("audit_mode", param) == 0) { + cmd = LCFG_NODEMAP_AUDIT_MODE; } else { fprintf(stderr, "error: %s: nodemap_modify invalid " "subcommand: %s\n", @@ -3743,32 +4423,14 @@ int jt_nodemap_add_idmap(int argc, char **argv) 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 - } - }; + static struct option long_opts[] = { + { .val = 'i', .name = "idtype", .has_arg = required_argument }, + { .val = 'm', .name = "idmap", .has_arg = required_argument }, + { .val = 'n', .name = "name", .has_arg = required_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "n:m:i:", - long_options, NULL)) != -1) { + long_opts, NULL)) != -1) { switch (c) { case 'n': nodemap_name = optarg; @@ -3817,32 +4479,14 @@ int jt_nodemap_del_idmap(int argc, char **argv) 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 - } - }; + static struct option long_opts[] = { + { .val = 'i', .name = "idtype", .has_arg = required_argument }, + { .val = 'm', .name = "idmap", .has_arg = required_argument }, + { .val = 'n', .name = "name", .has_arg = required_argument }, + { .name = NULL } }; while ((c = getopt_long(argc, argv, "n:m:i:", - long_options, NULL)) != -1) { + long_opts, NULL)) != -1) { switch (c) { case 'n': nodemap_name = optarg; @@ -3967,15 +4611,192 @@ err: return 0; } -static int extract_fsname_poolname(const char *arg, char *fsname, +struct llog_pool_name { + char lpn_name[UUID_MAX]; + struct list_head lpn_list; +}; + +struct llog_pool_list_data { + char lpld_fsname[LUSTRE_MAXFSNAME + 1]; + char lpld_poolname[LOV_MAXPOOLNAME + 1]; + bool lpld_exists; + struct list_head lpld_list_head; +}; + +/** + * Callback to list pool information in llog + * - { index: 74, event: new_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * - { index: 77, event: add_pool, device: tfs-clilov, fsname: tfs, pool: tmp, + * ost: tfs-OST0000_UUID } + * - { index: 224, event: remove_pool, device: tfs-clilov, fsname: tfs, + * pool: tmp, ost: tfs-OST0003_UUID } + * - { index: 227, event: del_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * + * \param record[in] pointer to llog record + * \param data[in] pointer to struct llog_pool_list_data + * + * \retval 0 on success + * <0 on error + */ +static int llog_poollist_cb(const char *record, void *data) +{ + struct llog_pool_list_data *lpld = data; + char pool_filter[MAX_STRING_SIZE] = ""; + char *new_record, *del_record, *del_pool, *found; + char type[10] = ""; + int filter_len, rc = 0; + + filter_len = snprintf(pool_filter, sizeof(pool_filter), " fsname: %s,", + lpld->lpld_fsname); + if (lpld->lpld_poolname[0] == '\0') { + new_record = get_event_filter(LCFG_POOL_NEW); + del_record = get_event_filter(LCFG_POOL_DEL); + strncpy(type, " pool: ", sizeof(type)); + } else { + filter_len += snprintf(pool_filter + filter_len, + sizeof(pool_filter) - filter_len, + " pool: %s", lpld->lpld_poolname); + new_record = get_event_filter(LCFG_POOL_ADD); + del_record = get_event_filter(LCFG_POOL_REM); + strncpy(type, " ost: ", sizeof(type)); + } + del_pool = get_event_filter(LCFG_POOL_DEL); + + if (!new_record || !del_record || !del_pool) { + rc = -ENOMEM; + goto out; + } + + found = strstr(record, pool_filter); + if (found && + (found[filter_len] == ' ' || found[filter_len] == ',')) { + struct llog_pool_name *tmp = NULL; + struct list_head *head = &lpld->lpld_list_head; + char *name; + int name_len, type_len = strlen(type); + + lpld->lpld_exists = true; + if (strstr(record, new_record)) { + name = strstr(record, type); + /* 2 bytes for " }" */ + name_len = strlen(name) - type_len - 2; + if (name_len <= 0 || name_len > sizeof(tmp->lpn_name)) + return -EINVAL; + tmp = malloc(sizeof(struct llog_pool_name)); + if (tmp == NULL) { + rc = -ENOMEM; + goto out; + } + memset(tmp, 0, sizeof(struct llog_pool_name)); + strncpy(tmp->lpn_name, name + type_len, name_len); + list_add_tail(&tmp->lpn_list, &lpld->lpld_list_head); + } else if (strstr(record, del_record)) { + name = strstr(record, type); + name_len = strlen(name) - type_len - 2; + list_for_each_entry(tmp, head, lpn_list) { + if (strncmp(tmp->lpn_name, name + type_len, + name_len) == 0 && + tmp->lpn_name[name_len] == '\0') { + list_del(&tmp->lpn_list); + free(tmp); + break; + } + } + } + /* verify if the specified pool still exists */ + if (lpld->lpld_poolname[0] && strstr(record, del_pool)) + lpld->lpld_exists = false; + } +out: + if (new_record) + free(new_record); + if (del_record) + free(del_record); + if (del_pool) + free(del_pool); + + return rc; +} + +/** + * List pool information by config log + * + * \param fsname[in] pointer to filesystem name + * \param poolname[in] pointer to pool name + * + * \retval 0 on success + * < 0 on error + */ +int llog_poollist(char *fsname, char *poolname) +{ + char logname[MAX_OBD_NAME] = {'\0'}; + struct llog_pool_list_data lpld; + struct llog_pool_name *tmp; + struct list_head *head; + int rc = 0; + + if (fsname && fsname[0] == '\0') + fsname = NULL; + if (!fsname) + return -EINVAL; + + memset(&lpld, 0, sizeof(lpld)); + INIT_LIST_HEAD(&lpld.lpld_list_head); + lpld.lpld_exists = false; + strncpy(lpld.lpld_fsname, fsname, sizeof(lpld.lpld_fsname) - 1); + if (poolname && poolname[0]) + strncpy(lpld.lpld_poolname, poolname, + sizeof(lpld.lpld_poolname) - 1); + snprintf(logname, sizeof(logname), "%s-client", fsname); + rc = jt_llog_print_iter(logname, 0, -1, llog_poollist_cb, &lpld, false); + + if (poolname && poolname[0]) + printf("Pool: %s.%s\n", fsname, poolname); + else + printf("Pools from %s:\n", fsname); + + head = &lpld.lpld_list_head; + if (poolname && poolname[0] && !lpld.lpld_exists && list_empty(head)) + return -ENOENT; + + list_for_each_entry(tmp, head, lpn_list) { + if (poolname && poolname[0]) + printf("%s\n", tmp->lpn_name); + else + printf("%s.%s\n", fsname, tmp->lpn_name); + list_del(&tmp->lpn_list); + free(tmp); + } + + return rc; +} + +static bool get_pools_path(char *fsname) +{ + glob_t path; + int rc; + + rc = cfs_get_param_paths(&path, "lov/%s-*/pools", fsname); + if (!rc) + cfs_free_param_data(&path); + + return (rc == 0); +} + +static int extract_fsname_poolname(char **argv, char *fsname, char *poolname) { + char *cmd = argv[0], *param = argv[1]; char *ptr; int rc; - strlcpy(fsname, arg, PATH_MAX + 1); + snprintf(fsname, PATH_MAX + 1, "%s", param); ptr = strchr(fsname, '.'); if (ptr == NULL) { + if (strcmp(cmd, "pool_list") == 0) { + poolname = NULL; + goto out; + } fprintf(stderr, ". is missing in %s\n", fsname); rc = -EINVAL; goto err; @@ -3998,63 +4819,76 @@ static int extract_fsname_poolname(const char *arg, char *fsname, strncpy(poolname, ptr, LOV_MAXPOOLNAME); poolname[LOV_MAXPOOLNAME] = '\0'; + + if (strncmp(poolname, "none", LOV_MAXPOOLNAME) == 0) { + fprintf(stderr, "poolname cannot be 'none'\n"); + return -EINVAL; + } +out: return 0; err: - fprintf(stderr, "argument %s must be .\n", arg); + fprintf(stderr, "argument %s must be .\n", param); 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; + 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: { + rc = extract_fsname_poolname(argv, fsname, poolname); + if (rc) + break; - rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); - if (rc) - break; + 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) { + if (get_pools_path(fsname)) + return llapi_poollist(argv[1]); + if (get_mgs_device() > 0) + return llog_poollist(fsname, poolname); + fprintf(stderr, "Cannot run pool_list command " + "since there is no local MGS/MDT or client\n"); + return CMD_HELP; + } else { + return CMD_HELP; + } - check_pool_cmd_result(cmd, fsname, poolname, NULL); - break; - } - default: { - char format[2*MAX_OBD_NAME]; + rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); + if (rc) + break; - 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; - } + check_pool_cmd_result(cmd, fsname, poolname, NULL); + break; + } + default: { + char format[2 * MAX_OBD_NAME]; - rc = extract_fsname_poolname(argv[1], fsname, poolname); - if (rc) - break; + 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, fsname, poolname); + if (rc) + break; for (i = 2; i < argc; i++) { int j; @@ -4140,6 +4974,7 @@ out: return rc; } +#ifdef HAVE_SERVER_SUPPORT static const char *barrier_status2name(enum barrier_status status) { switch (status) { @@ -4199,7 +5034,7 @@ int jt_barrier_freeze(int argc, char **argv) data.ioc_inlbuf1 = (char *)&bc; data.ioc_inllen1 = sizeof(bc); memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; @@ -4242,7 +5077,7 @@ int jt_barrier_thaw(int argc, char **argv) data.ioc_inlbuf1 = (char *)&bc; data.ioc_inllen1 = sizeof(bc); memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; @@ -4256,7 +5091,7 @@ int jt_barrier_thaw(int argc, char **argv) return rc; } -int __jt_barrier_stat(int argc, char **argv, struct barrier_ctl *bc) +int __jt_barrier_stat(const char *fsname, struct barrier_ctl *bc) { struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; @@ -4270,11 +5105,11 @@ int __jt_barrier_stat(int argc, char **argv, struct barrier_ctl *bc) memset(bc, 0, sizeof(*bc)); bc->bc_version = BARRIER_VERSION_V1; bc->bc_cmd = BC_STAT; - strncpy(bc->bc_name, argv[1], sizeof(bc->bc_name)); + strncpy(bc->bc_name, fsname, sizeof(bc->bc_name) - 1); data.ioc_inlbuf1 = (char *)bc; data.ioc_inllen1 = sizeof(*bc); memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; @@ -4283,9 +5118,9 @@ int __jt_barrier_stat(int argc, char **argv, struct barrier_ctl *bc) rc = l_ioctl(OBD_DEV_ID, OBD_IOC_BARRIER, buf); if (rc < 0) fprintf(stderr, "Fail to query barrier for %s: %s\n", - argv[1], strerror(errno)); + fsname, strerror(errno)); else - obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); return rc; } @@ -4293,26 +5128,68 @@ int __jt_barrier_stat(int argc, char **argv, struct barrier_ctl *bc) int jt_barrier_stat(int argc, char **argv) { struct barrier_ctl bc; + static struct option long_opt_barrier_stat[] = { + { + .val = 's', + .name = "state", + .has_arg = no_argument, + }, + { .val = 't', + .name = "timeout", + .has_arg = no_argument, + }, + { + NULL + } + }; + const char *name; + int index; + int opt; int rc; + bool state = false; + bool timeout = false; + + while ((opt = getopt_long(argc, argv, "st", long_opt_barrier_stat, + &index)) != EOF) { + switch (opt) { + case 's': + state = true; + break; + case 't': + timeout = true; + break; + default: + return CMD_HELP; + } + } - if (argc != 2) + if (optind >= argc) return CMD_HELP; - if (strlen(argv[1]) > 8) { + name = argv[optind]; + if (strlen(name) > 8) { fprintf(stderr, "fsname name %s is too long. " - "It should not exceed 8.\n", argv[1]); + "It should not exceed 8.\n", name); return -EINVAL; } - rc = __jt_barrier_stat(argc, argv, &bc); + rc = __jt_barrier_stat(name, &bc); if (!rc) { - printf("The barrier for %s is in '%s'\n", - argv[1], barrier_status2name(bc.bc_status)); - if (bc.bc_status == BS_FREEZING_P1 || - bc.bc_status == BS_FREEZING_P2 || - bc.bc_status == BS_FROZEN) - printf("The barrier will be expired after %d " - "seconds\n", bc.bc_timeout); + if (state && !timeout) + printf("%s\n", barrier_status2name(bc.bc_status)); + else if (timeout && !state) + printf("%d\n", + (bc.bc_status == BS_FREEZING_P1 || + bc.bc_status == BS_FREEZING_P2 || + bc.bc_status == BS_FROZEN) ? + bc.bc_timeout : 0); + else + printf("state: %s\ntimeout: %d seconds\n", + barrier_status2name(bc.bc_status), + (bc.bc_status == BS_FREEZING_P1 || + bc.bc_status == BS_FREEZING_P2 || + bc.bc_status == BS_FROZEN) ? + bc.bc_timeout : 0); } return rc; @@ -4351,7 +5228,7 @@ int jt_barrier_rescan(int argc, char **argv) data.ioc_inlbuf1 = (char *)&bc; data.ioc_inllen1 = sizeof(bc); memset(buf, 0, sizeof(rawbuf)); - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; @@ -4362,13 +5239,14 @@ int jt_barrier_rescan(int argc, char **argv) fprintf(stderr, "Fail to rescan barrier bitmap for %s: %s\n", argv[1], strerror(errno)); } else { - obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); printf("%u of %u MDT(s) in the filesystem %s are inactive\n", bc.bc_absence, bc.bc_total, argv[1]); } return rc; } +#endif /* HAVE_SERVER_SUPPORT */ int jt_get_obj_version(int argc, char **argv) { @@ -4417,24 +5295,25 @@ int jt_get_obj_version(int argc, char **argv) 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; - } + memset(buf, 0, sizeof *buf); + rc = llapi_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; - } + rc = l_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); + llapi_ioctl_unpack(&data, buf, sizeof rawbuf); printf("%#jx\n", (uintmax_t)version); - return 0; + + return 0; } int jt_changelog_register(int argc, char **argv) @@ -4466,14 +5345,14 @@ int jt_changelog_register(int argc, char **argv) data.ioc_dev = cur_device; - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc < 0) { fprintf(stderr, "error: %s: cannot pack ioctl: %s\n", jt_cmdname(argv[0]), strerror(-rc)); return rc; } - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_REG, buf); + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_REG, buf); if (rc < 0) { rc = -errno; fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), @@ -4481,7 +5360,7 @@ int jt_changelog_register(int argc, char **argv) return rc; } - obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); + llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (data.ioc_u32_1 == 0) { fprintf(stderr, "received invalid userid!\n"); @@ -4520,23 +5399,139 @@ int jt_changelog_deregister(int argc, char **argv) data.ioc_dev = cur_device; data.ioc_u32_1 = id; - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc < 0) { fprintf(stderr, "error: %s: invalid ioctl\n", jt_cmdname(argv[0])); return rc; } - rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CHANGELOG_DEREG, buf); + rc = l_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)); + llapi_ioctl_unpack(&data, buf, sizeof(rawbuf)); printf("%s: Deregistered changelog user '%s%u'\n", device, CHANGELOG_USER_PREFIX, data.ioc_u32_1); return 0; } + +int jt_pcc_add(int argc, char **argv) +{ + struct option long_opts[] = { + { .val = 'p', .name = "param", .has_arg = required_argument }, + { .name = NULL } }; + const char *mntpath; + const char *pccpath; + char *param = NULL; + char cmd[PATH_MAX]; + int rc; + + optind = 1; + while ((rc = getopt_long(argc, argv, "p:", + long_opts, NULL)) != -1) { + switch (rc) { + case 'p': + param = optarg; + break; + default: + return CMD_HELP; + } + } + + if (!param) { + fprintf(stderr, "%s: must specify the config param for PCC\n", + jt_cmdname(argv[0])); + return CMD_HELP; + } + + if (optind + 2 != argc) { + fprintf(stderr, + "%s: must specify mount path and PCC path %d:%d\n", + jt_cmdname(argv[0]), optind, argc); + return CMD_HELP; + } + + mntpath = argv[optind++]; + pccpath = argv[optind]; + + snprintf(cmd, PATH_MAX, "add %s %s", pccpath, param); + rc = llapi_pccdev_set(mntpath, cmd); + if (rc < 0) + fprintf(stderr, "%s: failed to run '%s' on %s\n", + jt_cmdname(argv[0]), cmd, mntpath); + + return rc; +} + +int jt_pcc_del(int argc, char **argv) +{ + const char *mntpath; + const char *pccpath; + char cmd[PATH_MAX]; + int rc; + + optind = 1; + if (argc != 3) { + fprintf(stderr, "%s: require 3 arguments\n", + jt_cmdname(argv[0])); + return CMD_HELP; + } + + mntpath = argv[optind++]; + pccpath = argv[optind++]; + + snprintf(cmd, PATH_MAX, "del %s", pccpath); + rc = llapi_pccdev_set(mntpath, cmd); + if (rc < 0) + fprintf(stderr, "%s: failed to run '%s' on %s\n", + jt_cmdname(argv[0]), cmd, mntpath); + + return rc; +} + +int jt_pcc_clear(int argc, char **argv) +{ + const char *mntpath; + int rc; + + optind = 1; + if (argc != 2) { + fprintf(stderr, "%s: require 2 arguments\n", + jt_cmdname(argv[0])); + return CMD_HELP; + } + + mntpath = argv[optind]; + rc = llapi_pccdev_set(mntpath, "clear"); + if (rc < 0) + fprintf(stderr, "%s: failed to run 'clear' on %s\n", + jt_cmdname(argv[0]), mntpath); + + return rc; +} + +int jt_pcc_list(int argc, char **argv) +{ + const char *mntpath; + int rc; + + optind = 1; + if (argc != 2) { + fprintf(stderr, "%s: require 2 arguments\n", + jt_cmdname(argv[0])); + return CMD_HELP; + } + + mntpath = argv[optind]; + rc = llapi_pccdev_get(mntpath); + if (rc < 0) + fprintf(stderr, "%s: failed to run 'pcc list' on %s\n", + jt_cmdname(argv[0]), mntpath); + + return rc; +}