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);
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 <linux/obd_support.h>
int err;
ENTRY;
-
err = copy_from_user(&hdr, (void *)arg, sizeof(hdr));
if ( err ) {
EXIT;
#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
#include <linux/obd_lov.h>
#include <linux/lustre_lib.h>
-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;
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");
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:
uint64_t conn_cookie;
char rawbuf[8192];
char *buf = rawbuf;
-int max = 8192;
+int max = sizeof(rawbuf);
static int thread;
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);
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) {
}
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]);
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;
}