From 149934fe28dac22a51ec9b2873c4f215cb204947 Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Tue, 27 Apr 2021 22:15:30 +0300 Subject: [PATCH] LU-14645 utils: setstripe cleanup lfs setstripe checks stripe parameters differently for PFL and !PFL layouts. Whereas the PFL layout is checked in comp_args_to_layout() individually and in llapi_layout_sanity_cb() in pairs, !PFL layout verification is done partially in several places. Create a common llapi_stripe_param_verify() for this purpose. Make the checks for both cases symmetric. Signed-off-by: Vitaly Fertman Change-Id: I456b1b2e876229ac1a354d4e3879624325856574 HPE-bug-id: LUS-9886 Reviewed-on: https://es-gerrit.dev.cray.com/158589 Reviewed-by: Andriy Skulysh Reviewed-by: Alexander Boyko Tested-by: Alexander Lezhoev Reviewed-on: https://review.whamcloud.com/43465 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alexander Boyko Reviewed-by: Andriy Skulysh Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustreapi.h | 9 +- lustre/tests/llapi_layout_test.c | 6 +- lustre/utils/lfs.c | 88 ++++++++++------ lustre/utils/liblustreapi.c | 211 ++++++++++++++++++++++--------------- lustre/utils/liblustreapi_layout.c | 81 ++++++++++---- lustre/utils/lustreapi_internal.h | 31 ++++++ 6 files changed, 285 insertions(+), 141 deletions(-) diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 4d7c299..af0587f 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -837,6 +837,10 @@ int llapi_layout_stripe_count_get(const struct llapi_layout *layout, */ int llapi_layout_stripe_count_set(struct llapi_layout *layout, uint64_t count); +/** + * Check if the stripe count \a stripe_count \a is valid. + */ +bool llapi_layout_stripe_count_is_valid(int64_t stripe_count); /******************** Stripe Size ********************/ /** @@ -968,7 +972,7 @@ int llapi_layout_pool_name_get(const struct llapi_layout *layout, * \retval -1 Invalid argument, errno set to EINVAL. */ int llapi_layout_pool_name_set(struct llapi_layout *layout, - const char *pool_name); + char *pool_name); /******************** File Creation ********************/ @@ -1189,7 +1193,8 @@ int llapi_mirror_punch(int fd, unsigned int id, off_t start, size_t length); int llapi_heat_get(int fd, struct lu_heat *heat); int llapi_heat_set(int fd, __u64 flags); -int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr); +int llapi_layout_sanity(struct llapi_layout *layout, const char *fname, + bool incomplete, bool flr); void llapi_layout_sanity_perror(int error); int llapi_layout_dom_size(struct llapi_layout *layout, uint64_t *size); diff --git a/lustre/tests/llapi_layout_test.c b/lustre/tests/llapi_layout_test.c index f875f91..890dd8d 100644 --- a/lustre/tests/llapi_layout_test.c +++ b/lustre/tests/llapi_layout_test.c @@ -932,7 +932,7 @@ void test21(void) ASSERTF(layout != NULL, "errno = %d", errno); fd = llapi_layout_file_create(template, 0, 0640, layout); - ASSERTF(fd == -1 && errno == ENOTTY, + ASSERTF(fd == -1 && errno == ENOENT, "fd = %d, errno = %d, template = %s", fd, errno, template); llapi_layout_free(layout); } @@ -1366,7 +1366,7 @@ void test30(void) /* set non-contiguous extent will fail */ rc = llapi_layout_comp_extent_set(layout, start[1] * 2, end[1]); ASSERTF(rc == 0, "errno %d", errno); - rc = llapi_layout_sanity(layout, false, false); + rc = llapi_layout_sanity(layout, NULL, false, false); ASSERTF(rc == 12 /*LSE_NOT_ADJACENT_PREV*/, "rc %d", rc); rc = llapi_layout_comp_extent_set(layout, start[1], end[1]); @@ -1734,7 +1734,7 @@ void test34(void) layout = llapi_layout_get_by_path(path, 0); ASSERTF(layout != NULL, "errno = %d", errno); - rc = llapi_layout_sanity(layout, false, false); + rc = llapi_layout_sanity(layout, NULL, false, false); ASSERTF(rc == 0, "errno %d", errno); } diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 9ce1585..479c2be 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1189,7 +1189,7 @@ int lfs_layout_compid_by_pool(char *fname, const char *pool, int *comp_id) rc = -errno; goto free_layout; } - rc = llapi_layout_sanity(layout, false, true); + rc = llapi_layout_sanity(layout, fname, false, true); if (rc < 0) { llapi_layout_sanity_perror(errno); goto free_layout; @@ -1619,7 +1619,8 @@ enum mirror_flags { * Return: 0 on success or a negative error code on failure. */ static int mirror_create_sanity_check(const char *fname, - struct mirror_args *list) + struct mirror_args *list, + bool check_fname) { int rc = 0; bool has_m_file = false; @@ -1628,7 +1629,7 @@ static int mirror_create_sanity_check(const char *fname, if (!list) return -EINVAL; - if (fname) { + if (fname && check_fname) { struct llapi_layout *layout; layout = llapi_layout_get_by_path(fname, 0); @@ -1639,7 +1640,7 @@ static int mirror_create_sanity_check(const char *fname, return -ENODATA; } - rc = llapi_layout_sanity(layout, false, true); + rc = llapi_layout_sanity(layout, fname, false, true); llapi_layout_free(layout); @@ -1671,7 +1672,7 @@ static int mirror_create_sanity_check(const char *fname, } } - rc = llapi_layout_sanity(list->m_layout, false, true); + rc = llapi_layout_sanity(list->m_layout, fname, false, true); if (rc) { llapi_layout_sanity_perror(rc); return rc; @@ -1727,7 +1728,7 @@ static int mirror_create(char *fname, struct mirror_args *mirror_list) int i = 0; int rc = 0; - rc = mirror_create_sanity_check(NULL, mirror_list); + rc = mirror_create_sanity_check(fname, mirror_list, false); if (rc) return rc; @@ -2028,7 +2029,7 @@ static int mirror_extend(char *fname, struct mirror_args *mirror_list, { int rc; - rc = mirror_create_sanity_check(fname, mirror_list); + rc = mirror_create_sanity_check(fname, mirror_list, true); if (rc) return rc; @@ -2229,7 +2230,7 @@ static int mirror_split(const char *fname, __u32 id, const char *pool, return -EINVAL; } - rc = llapi_layout_sanity(layout, false, true); + rc = llapi_layout_sanity(layout, fname, false, true); if (rc) { llapi_layout_sanity_perror(rc); goto free_layout; @@ -2644,6 +2645,33 @@ static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa) lsa->lsa_comp_end != 0); } +static int lsa_args_stripe_count_check(struct lfs_setstripe_args *lsa) +{ + if (lsa->lsa_nr_tgts) { + if (lsa->lsa_nr_tgts < 0 || + lsa->lsa_nr_tgts >= LOV_MAX_STRIPE_COUNT) { + fprintf(stderr, "Invalid nr_tgts(%d)\n", + lsa->lsa_nr_tgts); + errno = EINVAL; + return -1; + } + + if (lsa->lsa_stripe_count > 0 && + lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT && + lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE && + lsa->lsa_nr_tgts != lsa->lsa_stripe_count) { + fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n", + lsa->lsa_stripe_count, + lsa->lsa_nr_tgts); + errno = EINVAL; + return -1; + } + } + + return 0; + +} + /** * comp_args_to_layout() - Create or extend a composite layout. * @composite: Pointer to the composite layout. @@ -2652,6 +2680,8 @@ static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa) * This function creates or extends a composite layout by adding a new * component with stripe options from @lsa. * + * When modified, adjust llapi_stripe_param_verify() if needed as well. + * * Return: 0 on success or an error code on failure. */ static int comp_args_to_layout(struct llapi_layout **composite, @@ -2827,22 +2857,28 @@ new_comp: } } + rc = lsa_args_stripe_count_check(lsa); + if (rc) + return rc; + if (lsa->lsa_nr_tgts > 0) { - if (lsa->lsa_stripe_count > 0 && - lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT && - lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE && - lsa->lsa_nr_tgts != lsa->lsa_stripe_count) { - fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n", - lsa->lsa_stripe_count, - lsa->lsa_nr_tgts); - errno = EINVAL; - return -1; - } + bool found = false; + for (i = 0; i < lsa->lsa_nr_tgts; i++) { rc = llapi_layout_ost_index_set(layout, i, lsa->lsa_tgts[i]); if (rc) break; + + /* Make sure stripe offset is in OST list. */ + if (lsa->lsa_tgts[i] == lsa->lsa_stripe_off) + found = true; + } + if (!found) { + fprintf(stderr, "Invalid stripe offset '%lld', not in the target list", + lsa->lsa_stripe_off); + errno = EINVAL; + return -1; } } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT && lsa->lsa_stripe_off != -1) { @@ -4217,6 +4253,9 @@ static int lfs_setstripe_internal(int argc, char **argv, migrate_mdt_param.fp_lmv_md = lmu; migrate_mdt_param.fp_migrate = 1; } else if (!layout) { + if (lsa_args_stripe_count_check(&lsa)) + goto usage_error; + /* initialize stripe parameters */ param = calloc(1, offsetof(typeof(*param), lsp_osts[lsa.lsa_nr_tgts])); @@ -4250,19 +4289,8 @@ static int lfs_setstripe_internal(int argc, char **argv, } param->lsp_pool = lsa.lsa_pool_name; param->lsp_is_specific = false; - if (lsa.lsa_nr_tgts > 0) { - if (lsa.lsa_stripe_count > 0 && - lsa.lsa_stripe_count != LLAPI_LAYOUT_DEFAULT && - lsa.lsa_stripe_count != LLAPI_LAYOUT_WIDE && - lsa.lsa_nr_tgts != lsa.lsa_stripe_count) { - fprintf(stderr, - "error: %s: stripe count %lld doesn't match the number of OSTs: %d\n", - argv[0], lsa.lsa_stripe_count, - lsa.lsa_nr_tgts); - free(param); - goto usage_error; - } + if (lsa.lsa_nr_tgts > 0) { param->lsp_is_specific = true; param->lsp_stripe_count = lsa.lsa_nr_tgts; memcpy(param->lsp_osts, tgts, diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 14263ac..ff645c2 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -400,9 +400,54 @@ int llapi_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) /* XXX: llapi_xxx() functions return negative values upon failure */ -int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset, - int stripe_count, int stripe_pattern) +int llapi_layout_search_ost(__u32 ost, char *pname, char *fsname) { + char ostname[MAX_OBD_NAME + 64]; + char *pool_name = pname; + int rc = 0; + + /** + * The current policy is that the pool does not have to exist at the + * setstripe time, see sanity-pfl/-flr tests. + * If this logic will change, re-enable it. + * + * if (pname && strlen(pname) == 0) + */ + pool_name = NULL; + + snprintf(ostname, sizeof(ostname), "%s-OST%04x_UUID", + fsname, ost); + rc = llapi_search_ost(fsname, pool_name, ostname); + if (rc <= 0) { + if (rc == 0) + rc = -ENODEV; + + llapi_error(LLAPI_MSG_ERROR, rc, + "%s: cannot find OST %s in %s", __func__, ostname, + pool_name != NULL ? "pool" : "system"); + return rc; + } + + return 0; +} + +/** + * Verify the setstripe parameters before using. + * This is a pair method for comp_args_to_layout()/llapi_layout_sanity_cb() + * when just 1 component or a non-PFL layout is given. + * + * \param[in] param stripe parameters + * \param[in] pool_name pool name + * \param[in] fsname lustre FS name + * + * \retval 0, success + * < 0, error code on failre + */ +static int llapi_stripe_param_verify(const struct llapi_stripe_param *param, + char **pool_name, + char *fsname) +{ + int count; static int page_size; int rc = 0; @@ -420,33 +465,94 @@ int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset, page_size, LOV_MIN_STRIPE_SIZE); } } - if (!llapi_stripe_size_is_aligned(stripe_size)) { + if (!llapi_stripe_size_is_aligned(param->lsp_stripe_size)) { rc = -EINVAL; llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe_size %llu, must be an even multiple of %d bytes", - (unsigned long long)stripe_size, page_size); + param->lsp_stripe_size, page_size); goto out; } - if (!llapi_stripe_index_is_valid(stripe_offset)) { + if (!llapi_stripe_index_is_valid(param->lsp_stripe_offset)) { rc = -EINVAL; llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe offset %d", - stripe_offset); + param->lsp_stripe_offset); goto out; } - if (!llapi_stripe_count_is_valid(stripe_count)) { + if (llapi_stripe_size_is_too_big(param->lsp_stripe_size)) { rc = -EINVAL; - llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe count %d", - stripe_count); + llapi_error(LLAPI_MSG_ERROR, rc, + "error: stripe size '%llu' over 4GB limit", + param->lsp_stripe_size); goto out; } - if (llapi_stripe_size_is_too_big(stripe_size)) { + + count = param->lsp_stripe_count; + if (param->lsp_stripe_pattern == LOV_PATTERN_MDT) { rc = -EINVAL; llapi_error(LLAPI_MSG_ERROR, rc, - "error: stripe size '%llu' over 4GB limit", - (unsigned long long)stripe_size); + "Invalid pattern: %d, must be specified with -E\n", + param->lsp_stripe_pattern); goto out; + } else { + if (!llapi_stripe_count_is_valid(count)) { + rc = -EINVAL; + llapi_error(LLAPI_MSG_ERROR, rc, + "Invalid stripe count %d\n", count); + goto out; + } + } + + /* Make sure we have a good pool */ + if (*pool_name != NULL) { + if (!llapi_pool_name_is_valid(pool_name, fsname)) { + rc = -EINVAL; + llapi_error(LLAPI_MSG_ERROR, rc, + "Pool '%s' is not on filesystem '%s'", + *pool_name, fsname); + goto out; + } + + /* Make sure the pool exists and is non-empty */ + rc = llapi_search_ost(fsname, *pool_name, NULL); + if (rc < 1) { + char *err = rc == 0 ? "has no OSTs" : "does not exist"; + + rc = -EINVAL; + llapi_error(LLAPI_MSG_ERROR, rc, "pool '%s.%s' %s", + fsname, *pool_name, err); + goto out; + } + rc = 0; } + /* sanity check of target list */ + if (param->lsp_is_specific) { + bool found = false; + int i; + + for (i = 0; i < count; i++) { + rc = llapi_layout_search_ost(param->lsp_osts[i], + *pool_name, fsname); + if (rc) + goto out; + + /* Make sure stripe offset is in OST list. */ + if (param->lsp_osts[i] == param->lsp_stripe_offset) + found = true; + } + if (!found) { + rc = -EINVAL; + llapi_error(LLAPI_MSG_ERROR, rc, + "%s: stripe offset '%d' is not in the target list", + __func__, param->lsp_stripe_offset); + goto out; + } + } else if (param->lsp_stripe_offset != -1) { + rc = llapi_layout_search_ost(param->lsp_stripe_offset, + *pool_name, fsname); + if (rc) + goto out; + } out: errno = -rc; return rc; @@ -570,9 +676,9 @@ int llapi_file_open_param(const char *name, int flags, mode_t mode, const struct llapi_stripe_param *param) { char fsname[MAX_OBD_NAME + 1] = { 0 }; - char *pool_name = param->lsp_pool; struct lov_user_md *lum = NULL; - size_t lum_size = sizeof(*lum); + char *pool_name = param->lsp_pool; + size_t lum_size; int fd, rc; /* Make sure we are on a Lustre file system */ @@ -585,82 +691,17 @@ int llapi_file_open_param(const char *name, int flags, mode_t mode, } /* Check if the stripe pattern is sane. */ - rc = llapi_stripe_limit_check(param->lsp_stripe_size, - param->lsp_stripe_offset, - param->lsp_stripe_count, - param->lsp_stripe_pattern); + rc = llapi_stripe_param_verify(param, &pool_name, fsname); if (rc != 0) return rc; - /* Make sure we have a good pool */ - if (pool_name != NULL) { - /* - * in case user gives the full pool name ., - * strip the fsname - */ - char *ptr = strchr(pool_name, '.'); - - if (ptr != NULL) { - *ptr = '\0'; - if (strcmp(pool_name, fsname) != 0) { - *ptr = '.'; - llapi_err_noerrno(LLAPI_MSG_ERROR, - "Pool '%s' is not on filesystem '%s'", - pool_name, fsname); - return -EINVAL; - } - pool_name = ptr + 1; - } - - /* Make sure the pool exists and is non-empty */ - rc = llapi_search_ost(fsname, pool_name, NULL); - if (rc < 1) { - char *err = rc == 0 ? "has no OSTs" : "does not exist"; - - llapi_err_noerrno(LLAPI_MSG_ERROR, "pool '%s.%s' %s", - fsname, pool_name, err); - return -EINVAL; - } - - lum_size = sizeof(struct lov_user_md_v3); - } - - /* sanity check of target list */ - if (param->lsp_is_specific) { - char ostname[MAX_OBD_NAME + 64]; - bool found = false; - int i; - - for (i = 0; i < param->lsp_stripe_count; i++) { - snprintf(ostname, sizeof(ostname), "%s-OST%04x_UUID", - fsname, param->lsp_osts[i]); - rc = llapi_search_ost(fsname, pool_name, ostname); - if (rc <= 0) { - if (rc == 0) - rc = -ENODEV; - - llapi_error(LLAPI_MSG_ERROR, rc, - "%s: cannot find OST %s in %s", - __func__, ostname, - pool_name != NULL ? - "pool" : "system"); - return rc; - } - - /* Make sure stripe offset is in OST list. */ - if (param->lsp_osts[i] == param->lsp_stripe_offset) - found = true; - } - if (!found) { - llapi_error(LLAPI_MSG_ERROR, -EINVAL, - "%s: stripe offset '%d' is not in the target list", - __func__, param->lsp_stripe_offset); - return -EINVAL; - } - + if (param->lsp_is_specific) lum_size = lov_user_md_size(param->lsp_stripe_count, LOV_USER_MAGIC_SPECIFIC); - } + else if (pool_name) + lum_size = sizeof(struct lov_user_md_v3); + else + lum_size = sizeof(*lum); lum = calloc(1, lum_size); if (lum == NULL) diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index 8cc4606..8753998 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -1157,7 +1157,7 @@ int llapi_layout_stripe_count_get(const struct llapi_layout *layout, * the old API uses 0 and -1. */ -static bool llapi_layout_stripe_count_is_valid(int64_t stripe_count) +bool llapi_layout_stripe_count_is_valid(int64_t stripe_count) { return stripe_count == LLAPI_LAYOUT_DEFAULT || stripe_count == LLAPI_LAYOUT_WIDE || @@ -1526,32 +1526,20 @@ int llapi_layout_pool_name_get(const struct llapi_layout *layout, char *dest, * \retval -1 if arguments are invalid or pool name is too long */ int llapi_layout_pool_name_set(struct llapi_layout *layout, - const char *pool_name) + char *pool_name) { struct llapi_layout_comp *comp; - char *ptr; comp = __llapi_layout_cur_comp(layout); if (comp == NULL) return -1; - if (pool_name == NULL) { - errno = EINVAL; - return -1; - } - - /* Strip off any 'fsname.' portion. */ - ptr = strchr(pool_name, '.'); - if (ptr != NULL) - pool_name = ptr + 1; - - if (strlen(pool_name) > LOV_MAXPOOLNAME) { + if (!llapi_pool_name_is_valid(&pool_name, NULL)) { errno = EINVAL; return -1; } strncpy(comp->llc_pool_name, pool_name, sizeof(comp->llc_pool_name)); - return 0; } @@ -1586,7 +1574,8 @@ int llapi_layout_file_open(const char *path, int open_flags, mode_t mode, } if (layout) { - rc = llapi_layout_sanity((struct llapi_layout *)layout, false, + rc = llapi_layout_sanity((struct llapi_layout *)layout, + path, false, !!(layout->llot_mirror_count > 1)); if (rc) { llapi_layout_sanity_perror(rc); @@ -2217,7 +2206,7 @@ int llapi_layout_file_comp_add(const char *path, goto out; } - rc = llapi_layout_sanity(existing_layout, false, false); + rc = llapi_layout_sanity(existing_layout, path, false, false); if (rc) { tmp_errno = errno; llapi_layout_sanity_perror(rc); @@ -2352,7 +2341,7 @@ int llapi_layout_file_comp_del(const char *path, uint32_t id, uint32_t flags) goto out; } - rc = llapi_layout_sanity(existing_layout, false, false); + rc = llapi_layout_sanity(existing_layout, path, false, false); if (rc) { tmp_errno = errno; llapi_layout_sanity_perror(rc); @@ -2512,7 +2501,7 @@ int llapi_layout_file_comp_set(const char *path, uint32_t *ids, uint32_t *flags, goto out; } - rc = llapi_layout_sanity(existing_layout, false, false); + rc = llapi_layout_sanity(existing_layout, path, false, false); if (rc) { tmp_errno = errno; llapi_layout_sanity_perror(rc); @@ -3149,6 +3138,7 @@ enum llapi_layout_comp_sanity_error { LSE_START_GT_END, LSE_ALIGN_END, LSE_ALIGN_EXT, + LSE_UNKNOWN_OST, LSE_LAST, }; @@ -3185,9 +3175,12 @@ const char *const llapi_layout_strerror[] = "The component end must be aligned by the stripe size", [LSE_ALIGN_EXT] = "The extension size must be aligned by the stripe size", + [LSE_UNKNOWN_OST] = + "An unknown OST idx is specified", }; struct llapi_layout_sanity_args { + char lsa_fsname[MAX_OBD_NAME + 1]; bool lsa_incomplete; bool lsa_flr; bool lsa_ondisk; @@ -3198,6 +3191,9 @@ struct llapi_layout_sanity_args { #define LCME_USER_COMP_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ LCME_FL_EXTENSION) +/** + * When modified, adjust llapi_stripe_param_verify() if needed as well. + */ static int llapi_layout_sanity_cb(struct llapi_layout *layout, void *arg) { @@ -3364,6 +3360,34 @@ static int llapi_layout_sanity_cb(struct llapi_layout *layout, goto out_err; } + if (args->lsa_fsname[0] != '\0') { + int i, rc = 0; + + if (comp->llc_pattern & LLAPI_LAYOUT_SPECIFIC) { + assert(comp->llc_stripe_count <= + comp->llc_objects_count); + + for (i = 0; i < comp->llc_stripe_count && rc == 0; i++){ + if (comp->llc_objects[i].l_ost_idx == + LLAPI_LAYOUT_IDX_MAX) { + args->lsa_rc = -1; + goto out_err; + } + rc = llapi_layout_search_ost( + comp->llc_objects[i].l_ost_idx, + comp->llc_pool_name, args->lsa_fsname); + } + } else if (comp->llc_stripe_offset != LLAPI_LAYOUT_DEFAULT) { + rc = llapi_layout_search_ost( + comp->llc_stripe_offset, + comp->llc_pool_name, args->lsa_fsname); + } + if (rc) { + args->lsa_rc = LSE_UNKNOWN_OST; + goto out_err; + } + } + return LLAPI_LAYOUT_ITER_CONT; out_err: @@ -3398,6 +3422,7 @@ void llapi_layout_sanity_perror(int error) * components"? * * \param[in] layout component layout list. + * \param[in] fname file the layout to be checked for * \param[in] incomplete if layout is complete or not - some checks can * only be done on complete layouts. * \param[in] flr set when this is called from FLR mirror create @@ -3405,9 +3430,12 @@ void llapi_layout_sanity_perror(int error) * \retval 0, success, positive: various errors, see * llapi_layout_sanity_perror, -1, failure */ -int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr) +int llapi_layout_sanity(struct llapi_layout *layout, + const char *fname, + bool incomplete, + bool flr) { - struct llapi_layout_sanity_args args; + struct llapi_layout_sanity_args args = { { 0 } }; struct llapi_layout_comp *curr; int rc = 0; @@ -3418,6 +3446,17 @@ int llapi_layout_sanity(struct llapi_layout *layout, bool incomplete, bool flr) if (!curr) return 0; + /* Make sure we are on a Lustre file system */ + if (fname) { + rc = llapi_search_fsname(fname, args.lsa_fsname); + if (rc) { + llapi_error(LLAPI_MSG_ERROR, rc, + "'%s' is not on a Lustre filesystem", + fname); + return rc; + } + } + /* Set up args */ args.lsa_rc = 0; args.lsa_flr = flr; diff --git a/lustre/utils/lustreapi_internal.h b/lustre/utils/lustreapi_internal.h index 367393d..522b8c3 100644 --- a/lustre/utils/lustreapi_internal.h +++ b/lustre/utils/lustreapi_internal.h @@ -126,6 +126,37 @@ static inline bool llapi_stripe_index_is_valid(int64_t index) return index >= -1 && index <= LOV_V1_INSANE_STRIPE_COUNT; } +static inline bool llapi_pool_name_is_valid(char **pool_name, + const char *fsname) +{ + char *ptr; + + if (*pool_name == NULL) + return false; + + /** + * in case user gives the full pool name ., + * strip the fsname + */ + ptr = strchr(*pool_name, '.'); + if (ptr != NULL) { + *ptr = '\0'; + if (fsname != NULL && strcmp(*pool_name, fsname) != 0) { + *ptr = '.'; + return false; + } + *pool_name = ptr + 1; + } + + if (strlen(*pool_name) > LOV_MAXPOOLNAME) + return false; + + return true; +} + + +int llapi_layout_search_ost(__u32 ost, char *pname, char *fsname); + /* Compatibility macro for legacy llapi functions that use "offset" * terminology instead of the preferred "index". */ #define llapi_stripe_offset_is_valid(os) llapi_stripe_index_is_valid(os) -- 1.8.3.1