*/
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 ********************/
/**
* \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 ********************/
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);
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);
}
/* 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]);
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);
}
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;
* 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;
if (!list)
return -EINVAL;
- if (fname) {
+ if (fname && check_fname) {
struct llapi_layout *layout;
layout = llapi_layout_get_by_path(fname, 0);
return -ENODATA;
}
- rc = llapi_layout_sanity(layout, false, true);
+ rc = llapi_layout_sanity(layout, fname, false, true);
llapi_layout_free(layout);
}
}
- 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;
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;
{
int rc;
- rc = mirror_create_sanity_check(fname, mirror_list);
+ rc = mirror_create_sanity_check(fname, mirror_list, true);
if (rc)
return rc;
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;
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.
* 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,
}
}
+ 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) {
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]));
}
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,
/* 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;
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;
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 */
}
/* 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 <fsname>.<poolname>,
- * 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)
* 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 ||
* \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;
}
}
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);
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);
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);
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);
LSE_START_GT_END,
LSE_ALIGN_END,
LSE_ALIGN_EXT,
+ LSE_UNKNOWN_OST,
LSE_LAST,
};
"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;
#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)
{
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:
* 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
* \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;
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;
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 <fsname>.<poolname>,
+ * 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)