From e3f2357691bc326eb8bf2d0d9bc556b8d0b36493 Mon Sep 17 00:00:00 2001 From: adilger Date: Mon, 21 Oct 2002 21:16:46 +0000 Subject: [PATCH] Change lctl lovconfig command into lov_getconfig, and add lov_setconfig. Update all scripts/docs which refer to the lovconfig command. lov_getconfig compiles OK, and does not affect normal operation, but it is not working yet (user-space segfault) and I need to run it on a real system (can't run GDB under UML). --- lustre/include/linux/lustre_lib.h | 32 ++++++-- lustre/mds/mds_lov.c | 29 +++++++- lustre/tests/common.sh | 2 +- lustre/utils/lconf | 10 +-- lustre/utils/lctl.c | 7 +- lustre/utils/obd.c | 152 ++++++++++++++++++++++++++++++-------- lustre/utils/obdctl.c | 2 +- lustre/utils/obdctl.h | 3 +- 8 files changed, 186 insertions(+), 51 deletions(-) diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index 0e398bd..9fb8c2f 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -305,7 +305,7 @@ static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, data->ioc_len = obd_ioctl_packlen(data); data->ioc_version = OBD_IOCTL_VERSION; - if (*pbuf && obd_ioctl_packlen(data) > max) + if (*pbuf && data->ioc_len > max) return 1; if (*pbuf == NULL) { *pbuf = malloc(data->ioc_len); @@ -328,6 +328,27 @@ static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, return 0; } +static inline int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, + int max) +{ + char *ptr; + struct obd_ioctl_data *overlay; + + if (!*pbuf) + return 1; + overlay = (struct obd_ioctl_data *)*pbuf; + memcpy(data, *pbuf, sizeof(*data)); + + ptr = overlay->ioc_bulk; + if (data->ioc_inlbuf1) + LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr); + if (data->ioc_inlbuf2) + LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr); + if (data->ioc_inlbuf3) + LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr); + + return 0; +} #else #include @@ -340,7 +361,6 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) int err; ENTRY; - err = copy_from_user(&hdr, (void *)arg, sizeof(hdr)); if ( err ) { EXIT; @@ -432,15 +452,17 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) #define OBD_IOC_UUID2DEV _IOWR('f', 130, long) #define OBD_IOC_RECOVD_NEWCONN _IOWR('f', 131, long) -#define OBD_IOC_LOV_CONFIG _IOWR('f', 132, long) - -#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 133 ) +#define OBD_IOC_LOV_SET_CONFIG _IOWR('f', 132, long) +#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 133, long) +#define OBD_IOC_LOV_CONFIG OBD_IOC_LOV_SET_CONFIG #define OBD_IOC_OPEN _IOWR('f', 134, long) #define OBD_IOC_CLOSE _IOWR('f', 135, long) #define OBD_IOC_RECOVD_FAILCONN _IOWR('f', 136, long) +#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139 ) + /* * l_wait_event is a flexible sleeping function, permitting simple caller * configuration of interrupt and timeout sensitivity along with actions to diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 85feb9d..ba08c2e 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -24,8 +24,8 @@ #include #include -int mds_configure_lov(struct obd_device *obd, struct lov_desc *desc, - obd_uuid_t *uuidarray) +int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc, + obd_uuid_t *uuidarray) { struct mds_obd *mds = &obd->u.mds; struct obd_run_ctxt saved; @@ -155,7 +155,7 @@ int mds_iocontrol(long cmd, struct lustre_handle *conn, switch (cmd) { - case OBD_IOC_LOV_CONFIG: + case OBD_IOC_LOV_SET_CONFIG: desc = (struct lov_desc *)data->ioc_inlbuf1; if (sizeof(*desc) > data->ioc_inllen1) { CERROR("descriptor size wrong\n"); @@ -168,7 +168,28 @@ int mds_iocontrol(long cmd, struct lustre_handle *conn, CERROR("UUID array size wrong\n"); RETURN(-EINVAL); } - rc = mds_configure_lov(obd, desc, uuidarray); + rc = mds_set_lovdesc(obd, desc, uuidarray); + + RETURN(rc); + case OBD_IOC_LOV_GET_CONFIG: + desc = (struct lov_desc *)data->ioc_inlbuf1; + if (sizeof(*desc) > data->ioc_inllen1) { + CERROR("descriptor size wrong\n"); + RETURN(-EINVAL); + } + + count = desc->ld_tgt_count; + uuidarray = (obd_uuid_t *)data->ioc_inlbuf2; + if (sizeof(*uuidarray) * count != data->ioc_inllen2) { + CERROR("UUID array size wrong\n"); + RETURN(-EINVAL); + } + rc = mds_get_lovdesc(obd, desc); + if (desc->ld_tgt_count > count) { + CERROR("UUID array size too small\n"); + RETURN(-ENOSPC); + } + rc = mds_get_lovtgts(obd, desc->ld_tgt_count, uuidarray); RETURN(rc); default: diff --git a/lustre/tests/common.sh b/lustre/tests/common.sh index 8ebe8e5..34e3b83 100644 --- a/lustre/tests/common.sh +++ b/lustre/tests/common.sh @@ -364,7 +364,7 @@ setup_mds_lov() { $OBDCTL <<- EOF || return $? name2dev MDSDEV connect - lovconfig ${LOVUUID} 1 4096 0 OSCDEV-`hostname` + lov_setconfig ${LOVUUID} 1 65536 0 OSCDEV-`hostname` disconnect quit EOF diff --git a/lustre/utils/lconf b/lustre/utils/lconf index cbea680..ec711cf 100755 --- a/lustre/utils/lconf +++ b/lustre/utils/lconf @@ -374,11 +374,11 @@ class LCTLInterface: self.run(cmds) # create an lov - def lovconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist): + def lov_setconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist): cmds = """ device $%s probe - lovconfig %s %d %d %d %s %s + lov_setconfig %s %d %d %d %s %s quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist) self.run(cmds) @@ -883,9 +883,9 @@ class LOVConfig(Module): lov = self.lov self.info(lov.mds_uuid, lov.stripe_cnt, lov.stripe_sz, lov.stripe_off, lov.pattern, lov.devlist, lov.mds_name) - lctl.lovconfig(lov.uuid, lov.mds_name, lov.stripe_cnt, - lov.stripe_sz, lov.stripe_off, lov.pattern, - string.join(lov.devlist)) + lctl.lov_setconfig(lov.uuid, lov.mds_name, lov.stripe_cnt, + lov.stripe_sz, lov.stripe_off, lov.pattern, + string.join(lov.devlist)) def cleanup(self): #nothing to do here diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 767c286..c4ac85c 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -125,9 +125,12 @@ command_t cmdlist[] = { {"detach", jt_obd_detach, 0, "remove driver (and name and uuid) from current device\n" "usage: detach"}, - {"lovconfig", jt_obd_lov_config, 0, + {"lov_setconfig", jt_obd_lov_setconfig, 0, "write lov configuration to an mds device\n" - "usage: lovconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"}, + "usage: lov_setconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"}, + {"lov_getconfig", jt_obd_lov_getconfig, 0, + "read lov configuration from an mds device\n" + "usage: lov_getconfig lov-uuid"}, /* Device operations */ {"=== device operations ==", jt_noop, 0, "device operations"}, diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 6b1f042..aece8d7 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -75,7 +75,7 @@ uint64_t conn_addr = -1; uint64_t conn_cookie; char rawbuf[8192]; char *buf = rawbuf; -int max = 8192; +int max = sizeof(rawbuf); static int thread; @@ -1143,12 +1143,12 @@ int jt_obd_test_brw(int argc, char **argv) return rc; } -int jt_obd_lov_config(int argc, char **argv) +int jt_obd_lov_setconfig(int argc, char **argv) { struct obd_ioctl_data data; struct lov_desc desc; - obd_uuid_t *uuidarray; - int rc, size, i; + obd_uuid_t *uuidarray, *ptr; + int rc, i; char *end; IOCINIT(data); @@ -1156,14 +1156,15 @@ int jt_obd_lov_config(int argc, char **argv) if (argc <= 6) return CMD_HELP; - if (strlen(argv[1]) > sizeof(*uuidarray) - 1) { - fprintf(stderr, "error: %s: no %dB memory for uuid's\n", - cmdname(argv[0]), strlen(argv[1])); - return -ENOMEM; + if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { + fprintf(stderr, + "error: %s: LOV uuid '%s' longer than %d characters\n", + cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); + return -EINVAL; } memset(&desc, 0, sizeof(desc)); - strncpy(desc.ld_uuid, argv[1], sizeof(*uuidarray) - 1); + strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); desc.ld_tgt_count = argc - 6; desc.ld_default_stripe_count = strtoul(argv[2], &end, 0); if (*end) { @@ -1173,26 +1174,31 @@ int jt_obd_lov_config(int argc, char **argv) } if (desc.ld_default_stripe_count > desc.ld_tgt_count) { fprintf(stderr, - "error: %s: stripe count %d more than OST count %d\n", + "error: %s: default stripe count %u > OST count %u\n", cmdname(argv[0]), desc.ld_default_stripe_count, desc.ld_tgt_count); return -EINVAL; } - if (desc.ld_default_stripe_count == 0) - desc.ld_default_stripe_count = desc.ld_tgt_count; - desc.ld_default_stripe_size = strtoul(argv[3], &end, 0); + desc.ld_default_stripe_size = strtoull(argv[3], &end, 0); if (*end) { fprintf(stderr, "error: %s: bad default stripe size '%s'\n", cmdname(argv[0]), argv[3]); return CMD_HELP; } if (desc.ld_default_stripe_size < 4096) { - fprintf(stderr, "error: %s: stripe size %ld too small\n", - cmdname(argv[0]), (long)desc.ld_default_stripe_size); + fprintf(stderr, + "error: %s: default stripe size "LPU64" too small\n", + cmdname(argv[0]), desc.ld_default_stripe_size); + return -EINVAL; + } else if ((long)desc.ld_default_stripe_size < + desc.ld_default_stripe_size) { + fprintf(stderr, + "error: %s: default stripe size "LPU64" too large\n", + cmdname(argv[0]), desc.ld_default_stripe_size); return -EINVAL; } - desc.ld_default_stripe_offset = (__u64) strtoul(argv[4], &end, 0); + desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0); if (*end) { fprintf(stderr, "error: %s: bad default stripe offset '%s'\n", cmdname(argv[0]), argv[4]); @@ -1205,39 +1211,121 @@ int jt_obd_lov_config(int argc, char **argv) return CMD_HELP; } - size = desc.ld_tgt_count * sizeof(*uuidarray); - uuidarray = malloc(size); + /* NOTE: it is possible to overwrite the default striping parameters, + * but EXTREME care must be taken when saving the OST UUID list. + * It must be EXACTLY the same, or have only additions at the + * end of the list, or only overwrite individual OST entries + * that are restored from backups of the previous OST. + */ + uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); if (!uuidarray) { - fprintf(stderr, "error: %s: no %dB memory for uuid's\n", - cmdname(argv[0]), size); - return -ENOMEM; + fprintf(stderr, "error: %s: no memory for %d UUIDs\n", + cmdname(argv[0]), desc.ld_tgt_count); + rc = -ENOMEM; + goto out; } - memset(uuidarray, 0, size); - for (i = 6; i < argc; i++) { - char *buf = (char *)(uuidarray + i - 6); - if (strlen(argv[i]) >= sizeof(*uuidarray)) { + for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) { + if (strlen(argv[i]) >= sizeof(*ptr)) { fprintf(stderr, "error: %s: arg %d (%s) too long\n", cmdname(argv[0]), i, argv[i]); - free(uuidarray); - return -EINVAL; + rc = -EINVAL; + goto out; } - strcpy(buf, argv[i]); + strcpy((char *)ptr, argv[i]); } data.ioc_inllen1 = sizeof(desc); data.ioc_inlbuf1 = (char *)&desc; - data.ioc_inllen2 = size; + data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); data.ioc_inlbuf2 = (char *)uuidarray; if (obd_ioctl_pack(&data, &buf, max)) { fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -EINVAL; + rc = -EINVAL; + goto out; } - rc = ioctl(fd, OBD_IOC_LOV_CONFIG, buf); + rc = ioctl(fd, OBD_IOC_LOV_SET_CONFIG, buf); if (rc) - fprintf(stderr, "lov_config: error: %s: %s\n", + fprintf(stderr, "error: %s: ioctl error: %s\n", + cmdname(argv[0]), strerror(rc = errno)); +out: + free(uuidarray); + return rc; +} + +#define DEF_UUID_ARRAY_LEN (8192 / 40) + +int jt_obd_lov_getconfig(int argc, char **argv) +{ + struct obd_ioctl_data data; + struct lov_desc desc; + obd_uuid_t *uuidarray; + int rc; + + IOCINIT(data); + + if (argc != 2) + return CMD_HELP; + + if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { + fprintf(stderr, + "error: %s: LOV uuid '%s' longer than %d characters\n", + cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); + return -EINVAL; + } + + memset(&desc, 0, sizeof(desc)); + strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); + desc.ld_tgt_count = DEF_UUID_ARRAY_LEN; +repeat: + uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); + if (!uuidarray) { + fprintf(stderr, "error: %s: no memory for %d uuid's\n", + cmdname(argv[0]), desc.ld_tgt_count); + return -ENOMEM; + } + + data.ioc_inllen1 = sizeof(desc); + data.ioc_inlbuf1 = (char *)&desc; + data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); + data.ioc_inlbuf2 = (char *)uuidarray; + + if (obd_ioctl_pack(&data, &buf, max)) { + fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); + rc = -EINVAL; + goto out; + } + + rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); + if (rc == -ENOSPC) { + free(uuidarray); + goto repeat; + } else if (rc) { + fprintf(stderr, "error: %s: ioctl error: %s\n", cmdname(argv[0]), strerror(rc = errno)); + } else { + obd_uuid_t *ptr; + int i; + + if (obd_ioctl_unpack(&data, buf, max)) { + fprintf(stderr, "error: %s: invalid reply\n", + cmdname(argv[0])); + rc = -EINVAL; + goto out; + } + printf("default_stripe_count: %u\n", + desc.ld_default_stripe_count); + printf("default_stripe_size: "LPU64"\n", + desc.ld_default_stripe_size); + printf("default_stripe_offset: "LPU64"\n", + desc.ld_default_stripe_offset); + printf("default_stripe_pattern: %u\n", desc.ld_pattern); + printf("obd_count: %u\n", desc.ld_tgt_count); + for (i = 0, ptr = uuidarray; i < desc.ld_tgt_count; i++, ptr++) + printf("%u: %s\n", i, (char *)ptr); + } +out: free(uuidarray); return rc; } diff --git a/lustre/utils/obdctl.c b/lustre/utils/obdctl.c index a19112f..b34504d 100644 --- a/lustre/utils/obdctl.c +++ b/lustre/utils/obdctl.c @@ -46,7 +46,7 @@ command_t cmdlist[] = { "--threads "}, /* Device configuration commands */ - {"lovconfig", jt_obd_lov_config, 0, "configure lov data on MDS " + {"lov_setconfig", jt_obd_lov_setconfig, 0, "configure lov data on MDS " "[usage: lovconfig lov-uuid stripecount, stripesize, pattern, UUID1, [UUID2, ...]"}, {"list", jt_obd_list, 0, "list the devices (no args)"}, {"newdev", jt_obd_newdev, 0, "set device to a new unused obd (no args)"}, diff --git a/lustre/utils/obdctl.h b/lustre/utils/obdctl.h index d1b5f20..0895743 100644 --- a/lustre/utils/obdctl.h +++ b/lustre/utils/obdctl.h @@ -49,7 +49,8 @@ int jt_obd_destroy(int argc, char **argv); int jt_obd_getattr(int argc, char **argv); int jt_obd_test_getattr(int argc, char **argv); int jt_obd_test_brw(int argc, char **argv); -int jt_obd_lov_config(int argc, char **argv); +int jt_obd_lov_setconfig(int argc, char **argv); +int jt_obd_lov_getconfig(int argc, char **argv); int jt_obd_test_ldlm(int argc, char **argv); int jt_obd_ldlm_regress_start(int argc, char **argv); int jt_obd_ldlm_regress_stop(int argc, char **argv); -- 1.8.3.1