#!/bin/bash
+# -*- mode: Bash; tab-width: 4; indent-tabs-mode: t; -*-
+# vim:autoindent:shiftwidth=4:tabstop=4:
#
# Run select tests by setting ONLY, or as arguments to the script.
# Skip specific tests by setting EXCEPT.
local ost_count=$($GETSTRIPE $file | grep 0x | wc -l)
[[ -n "$count" ]] && [[ $ost_count -ne $count ]] && \
- error "Stripe count $count expected; got $ost_count"
+ { error "Stripe count $count expected; got $ost_count" && return 1; }
return 0
}
create_pool_fail $NAME
echo "pool_new should fail if fs-name or poolname are missing."
- do_facet $SINGLEMDS lctl pool_new .pool1
+ do_facet $SINGLEMDS lctl pool_new .pool1 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though fs-name was missing."
- do_facet $SINGLEMDS lctl pool_new pool1
+ do_facet $SINGLEMDS lctl pool_new pool1 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though fs-name was missing."
- do_facet $SINGLEMDS lctl pool_new ${FSNAME}.
+ do_facet $SINGLEMDS lctl pool_new ${FSNAME}. 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though pool name was missing."
- do_facet $SINGLEMDS lctl pool_new .
+ do_facet $SINGLEMDS lctl pool_new . 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though pool name and fs-name " \
"were missing."
- do_facet $SINGLEMDS lctl pool_new ${FSNAME},pool1
+ do_facet $SINGLEMDS lctl pool_new ${FSNAME},pool1 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though pool name format was wrong"
- do_facet $SINGLEMDS lctl pool_new ${FSNAME}/pool1
+ do_facet $SINGLEMDS lctl pool_new ${FSNAME}/pool1 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though pool name format was wrong"
- do_facet $SINGLEMDS lctl pool_new ${FSNAME}.p
+ do_facet $SINGLEMDS lctl pool_new ${FSNAME}.p 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_new did not fail even though pool1 existed"
destroy_pool p
test_2a() {
destroy_pool $POOL
- do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
error " pool_add did not fail even though pool did " \
" not exist."
test_2b() {
do_facet $SINGLEMDS lctl pool_add $FSNAME.p1234567891234567890 \
- $FSNAME-OST0000
+ $FSNAME-OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_add did not fail even though pool name was invalid."
}
[[ $? -ne 0 ]] || \
destroy_pool $POOL
- do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
- error "pool_remove did not fail even though" \
- "pool did not exist."
+ error "pool_remove did not fail even though pool did not exist."
}
run_test 3a "pool_remove: non-existant pool"
test_3b() {
- do_facet $SINGLEMDS lctl pool_remove ${NON_EXISTANT_FS}.$POOL OST0000
+ do_facet $SINGLEMDS lctl pool_remove ${NON_EXISTANT_FS}.$POOL OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_remove did not fail even though fsname did not exist."
}
test_3c() {
do_facet $SINGLEMDS lctl pool_remove $FSNAME.p1234567891234567890 \
- $FSNAME-OST0000
+ $FSNAME-OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_remove did not fail even though pool name was invalid."
}
run_test 3c "pool_remove: Invalid pool name"
-
# Testing various combinations of OST name list
test_3d() {
lctl get_param -n lov.$FSNAME-*.pools.$POOL 2>/dev/null
[[ $? -ne 0 ]] || \
destroy_pool $POOL
- do_facet $SINGLEMDS lctl pool_destroy $FSNAME.$POOL
+ do_facet $SINGLEMDS lctl pool_destroy $FSNAME.$POOL 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_destroy did not fail even though pool did not exist."
}
run_test 4a "pool_destroy: non-existant pool"
test_4b() {
- do_facet $SINGLEMDS lctl pool_destroy ${NON_EXISTANT_FS}.$POOL
+ do_facet $SINGLEMDS lctl pool_destroy ${NON_EXISTANT_FS}.$POOL 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_destroy did not fail even though the filesystem did not exist."
}
do_facet $SINGLEMDS lctl pool_destroy ${FSNAME}.$POOL
[[ $? -ne 0 ]] || \
- error "pool_destroy succeeded with a non-empty pool name."
+ error "pool_destroy succeeded with a non-empty pool."
destroy_pool $POOL
}
run_test 4c "pool_destroy: non-empty pool ==============================="
sub_test_5() {
local LCMD=$1
- $LCMD pool_list
+ $LCMD pool_list 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_list did not fail even though fsname was not mentioned."
- destroy_pool $POOL
- destroy_pool $POOL2
+ destroy_pool $POOL 2>/dev/null
+ destroy_pool $POOL2 2>/dev/null
create_pool_nofail $POOL
create_pool_nofail $POOL2
[[ $? -eq 0 ]] || \
error "pool_list $FSNAME.$POOL failed."
- $LCMD pool_list ${NON_EXISTANT_FS}
+ $LCMD pool_list ${NON_EXISTANT_FS} 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_list did not fail for a non-existant fsname $NON_EXISTANT_FS"
- $LCMD pool_list ${FSNAME}.$NON_EXISTANT_POOL
+ $LCMD pool_list ${FSNAME}.$NON_EXISTANT_POOL 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_list did not fail for a non-existant pool $NON_EXISTANT_POOL"
fi
rm -rf ${DIR}nonexistant
- $LCMD pool_list ${DIR}nonexistant
+ $LCMD pool_list ${DIR}nonexistant 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_list did not fail for invalid mountpoint ${DIR}nonexistant"
check_dir_in_pool $POOL_DIR $POOL
# If an invalid pool name is specified, the command should fail
- $SETSTRIPE -c 2 -p $INVALID_POOL $POOL_DIR
+ $SETSTRIPE -c 2 -p $INVALID_POOL $POOL_DIR 2>/dev/null
[[ $? -ne 0 ]] || \
- error_ignore 19919 "setstripe to invalid pool did not fail."
+ error "setstripe to invalid pool did not fail."
# If the pool name does not exist, the command should fail
- $SETSTRIPE -c 2 -p $NON_EXISTANT_POOL $POOL_DIR
+ $SETSTRIPE -c 2 -p $NON_EXISTANT_POOL $POOL_DIR 2>/dev/null
[[ $? -ne 0 ]] || \
- error_ignore 19919 "setstripe to non-existant pool did not fail."
+ error "setstripe to non-existant pool did not fail."
# lfs setstripe should work as before if a pool name is not specified.
$SETSTRIPE -c -1 $POOL_DIR
# pool is specified.
create_pool_nofail $POOL2
add_pool $POOL2 "OST0000" "$FSNAME-OST0000_UUID "
- $SETSTRIPE -o 1 -p $POOL2 $ROOT_POOL/$tfile
+ $SETSTRIPE -o 1 -p $POOL2 $ROOT_POOL/$tfile 2>/dev/null
[[ $? -ne 0 ]] || \
error "$SETSTRIPE with start index outside the pool did not fail."
for c in $(seq 1 10);
do
echo "Pool $pool, iteration $c"
- create_pool_nofail $pool
- local TGT=$(for i in `seq $TGT_FIRST $step $TGT_MAX`; \
- do printf "$FSNAME-OST%04x_UUID " $i; done)
- add_pool $pool "$FSNAME-OST[$TGT_FIRST-$TGT_MAX/$step]" "$TGT"
- destroy_pool $pool
- do_facet $SINGLEMDS lctl pool_list $FSNAME
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$pool OST[$TGT_FIRST-$TGT_MAX/$step] 2>/dev/null
+ local TGT_SECOND=$(($TGT_FIRST+$step))
+ if [ "$TGT_SECOND" -le "$TGT_MAX" ]; then
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$pool OST[$TGT_SECOND-$TGT_MAX/$step]
+ fi
done
echo loop for $pool complete
}
test_22() {
local POOL_ROOT=${POOL_ROOT:-$DIR/$tdir}
- [[ $OSTCOUNT -le 1 ]] && skip "Need atleast 2 OSTs" && return
+ [[ $OSTCOUNT -le 1 ]] && skip "Need at least 2 OSTs" && return
local numfiles=100
+ create_pool_nofail $POOL
+ add_pool $POOL "OST0000" "$FSNAME-OST0000_UUID "
+ create_pool_nofail $POOL2
+ add_pool $POOL2 "OST0000" "$FSNAME-OST0000_UUID "
+
add_loop $POOL 1 &
add_loop $POOL2 2 &
sleep 5
error "createmany $POOL_ROOT/${tfile} failed!"
wait
+ destroy_pool $POOL
+ destroy_pool $POOL2
+
return 0
}
run_test 22 "Simultaneous manipulation of a pool"
for i in $(seq 10); do
create_pool_nofail pool$i
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.pool$i OST0000
stop $SINGLEMDS || return 1
- sleep 10
start $SINGLEMDS ${dev} $MDS_MOUNT_OPTS || \
- error "Failed to start $SINGLEMDS after stopping"
+ { error "Failed to start $SINGLEMDS after stopping" && break; }
+ client_df
# Veriy that the pool got created and is usable
echo "Creating a file in pool$i"
- create_file $POOL_ROOT/file$i pool$i
- check_file_in_pool $POOL_ROOT/file$i pool$i
+ create_file $POOL_ROOT/file$i pool$i || break
+ check_file_in_pool $POOL_ROOT/file$i pool$i || break
done
rm -rf $POOL_ROOT
run_test 200f "Create files in a pool ==================================="
test_200g() {
- remote_mgs_nodsh && skip "remote MGS with nodsh" && return
- TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
- res=$($LFS df --pool $FSNAME.$POOL | awk '{print $1}' | grep "$FSNAME-OST ")
- [ "$res" = "$TGT" ] || echo "Pools OSTS $TGT is not $res that lfs df reports"
+ remote_mgs_nodsh && skip "remote MGS with nodsh" && return
+ TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
+ res=$($LFS df --pool $FSNAME.$POOL | awk '{print $1}' | grep "$FSNAME-OST")
+ [ "$res" = "$TGT" ] || error "Pools OSTS '$TGT' is not '$res' that lfs df reports"
}
run_test 200g "lfs df a pool ============================================"
-test_201a() { # was 200g
+test_201a() {
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
}
run_test 201a "Remove a target from a pool ============================="
-test_201b() { # was 200h
+test_201b() {
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u)
do
done
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL" ""\
|| error "Pool $FSNAME.$POOL cannot be drained"
- # striping on an empty pool should fall back to "pool of everything"
- $SETSTRIPE -p $POOL ${POOL_FILE}/$tfile || error "failed to create file with empty pool"
+ # striping on an empty/nonexistant pool should fall back to "pool of everything"
+ touch ${POOL_DIR}/$tfile || error "failed to use fallback striping for empty pool"
+ # setstripe on an empty pool should fail
+ $SETSTRIPE -p $POOL ${POOL_FILE}/$tfile 2>/dev/null && \
+ error "expected failure when creating file with empty pool"
+ return 0
}
run_test 201b "Remove all targets from a pool =========================="
-test_201c() { # was 200i
+test_201c() {
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
do_facet mgs $LCTL pool_destroy $FSNAME.$POOL
+
+ sleep 2
+ # striping on an empty/nonexistant pool should fall back to "pool of everything"
+ touch ${POOL_DIR}/$tfile || error "failed to use fallback striping for missing pool"
+ # setstripe on an empty pool should fail
+ $SETSTRIPE -p $POOL ${POOL_FILE}/$tfile 2>/dev/null && \
+ error "expected failure when creating file with missing pool"
+
# get param should return err once pool is gone
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL 2>/dev/null ||
echo foo" "foo" && unset CLEANUP_200 && trap 0 && return 0
return $OSCFULL
}
-
destroy_pool_int() {
local ost
local OSTS=$(do_facet $SINGLEMDS lctl pool_list $1 | \
return 0;
}
-static int poolpath(char *fsname, char *pathname, char *pool_pathname);
+static int find_target_obdpath(char *fsname, char *path)
+{
+ glob_t glob_info;
+ char pattern[PATH_MAX + 1];
+ int rc;
+
+ snprintf(pattern, PATH_MAX,
+ "/proc/fs/lustre/lov/%s-*/target_obd",
+ fsname);
+ rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
+ if (rc == GLOB_NOMATCH)
+ return -ENODEV;
+ else if (rc)
+ return -EINVAL;
+
+ strcpy(path, glob_info.gl_pathv[0]);
+ globfree(&glob_info);
+ return 0;
+}
+
+static int find_poolpath(char *fsname, char *poolname, char *poolpath)
+{
+ glob_t glob_info;
+ char pattern[PATH_MAX + 1];
+ int rc;
+
+ snprintf(pattern, PATH_MAX,
+ "/proc/fs/lustre/lov/%s-*/pools/%s",
+ fsname, poolname);
+ rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
+ /* If no pools, make sure the lov is available */
+ if ((rc == GLOB_NOMATCH) &&
+ (find_target_obdpath(fsname, poolpath) == -ENODEV))
+ return -ENODEV;
+ if (rc)
+ return -EINVAL;
+
+ strcpy(poolpath, glob_info.gl_pathv[0]);
+ globfree(&glob_info);
+ return 0;
+}
+
+/*
+ * 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 llapi_search_ost(char *fsname, char *poolname, char *ostname)
+{
+ FILE *fd;
+ char buffer[PATH_MAX + 1];
+ int len = 0, rc;
+
+ if (ostname != NULL)
+ len = strlen(ostname);
+
+ if (poolname == NULL)
+ rc = find_target_obdpath(fsname, buffer);
+ else
+ rc = find_poolpath(fsname, poolname, buffer);
+ if (rc)
+ return rc;
+
+ if ((fd = fopen(buffer, "r")) == NULL)
+ return -EINVAL;
+
+ while (fgets(buffer, sizeof(buffer), fd) != NULL) {
+ if (poolname == NULL) {
+ char *ptr;
+ /* Search for an ostname in the list of OSTs
+ Line format is IDX: fsname-OSTxxxx_UUID STATUS */
+ ptr = strchr(buffer, ' ');
+ if ((ptr != NULL) &&
+ (strncmp(ptr + 1, ostname, len) == 0)) {
+ fclose(fd);
+ return 1;
+ }
+ } else {
+ /* Search for an ostname in a pool,
+ (or an existing non-empty pool if no ostname) */
+ if ((ostname == NULL) ||
+ (strncmp(buffer, ostname, len) == 0)) {
+ fclose(fd);
+ return 1;
+ }
+ }
+ }
+ fclose(fd);
+ return 0;
+}
int llapi_file_open_pool(const char *name, int flags, int mode,
unsigned long long stripe_size, int stripe_offset,
struct lov_user_md_v3 lum = { 0 };
int fd, rc = 0;
int isdir = 0;
- char fsname[MAX_OBD_NAME + 1], *ptr;
+
+ /* Make sure we have a good pool */
+ if (pool_name != NULL) {
+ char fsname[MAX_OBD_NAME + 1], *ptr;
+
+ if (llapi_search_fsname(name, fsname)) {
+ llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+ "'%s' is not on a Lustre filesystem", name);
+ return -EINVAL;
+ }
+
+ /* in case user gives the full pool name <fsname>.<poolname>,
+ * strip the fsname */
+ ptr = strchr(pool_name, '.');
+ if (ptr != NULL) {
+ *ptr = '\0';
+ if (strcmp(pool_name, fsname) != 0) {
+ *ptr = '.';
+ llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+ "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 */
+ if ((rc = llapi_search_ost(fsname, pool_name, NULL)) < 1) {
+ llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+ "pool '%s.%s' %s", fsname, pool_name,
+ rc == 0 ? "has no OSTs" : "does not exist");
+ return -EINVAL;
+ }
+ }
fd = open(name, flags | O_LOV_DELAY_CREATE, mode);
if (fd < 0 && errno == EISDIR) {
lum.lmm_stripe_size = stripe_size;
lum.lmm_stripe_count = stripe_count;
lum.lmm_stripe_offset = stripe_offset;
-
- /* in case user give the full pool name <fsname>.<poolname>, skip
- * the fsname */
if (pool_name != NULL) {
- ptr = strchr(pool_name, '.');
- if (ptr != NULL) {
- strncpy(fsname, pool_name, ptr - pool_name);
- *ptr = '\0';
- /* if fsname matches a filesystem skip it
- * if not keep the poolname as is */
- if (poolpath(fsname, NULL, NULL) == 0)
- pool_name = ptr + 1;
- }
strncpy(lum.lmm_pool_name, pool_name, LOV_MAXPOOLNAME);
} else {
/* If no pool is specified at all, use V1 request */
{
struct mntent mnt;
char buf[PATH_MAX], mntdir[PATH_MAX];
- char *name = NULL, *ptr;
+ char *ptr;
FILE *fp;
int idx = 0, len = 0, mntlen, fd;
int rc = -ENODEV;
if ((want & WANT_INDEX) && (idx++ != index))
continue;
- /* Check the fsname for a match */
+ /* Check the fsname for a match, if given */
if (!(want & WANT_FSNAME) && fsname != NULL &&
(strlen(fsname) > 0) && (strcmp(ptr, fsname) != 0))
continue;
/* If the path isn't set return the first one we find */
if (path == NULL || strlen(path) == 0) {
strcpy(mntdir, mnt.mnt_dir);
- name = ptr;
+ if ((want & WANT_FSNAME) && fsname != NULL)
+ strcpy(fsname, ptr);
rc = 0;
break;
/* Otherwise find the longest matching path */
} else if ((strlen(path) >= mntlen) && (mntlen >= len) &&
(strncmp(mnt.mnt_dir, path, mntlen) == 0)) {
strcpy(mntdir, mnt.mnt_dir);
- mntlen = len;
- name = ptr;
+ len = mntlen;
+ if ((want & WANT_FSNAME) && fsname != NULL)
+ strcpy(fsname, ptr);
rc = 0;
}
}
/* Found it */
if (rc == 0) {
- if ((want & WANT_FSNAME) && fsname != NULL)
- strcpy(fsname, name);
if ((want & WANT_PATH) && path != NULL)
strcpy(path, mntdir);
if (want & WANT_FD) {
do_disconnect(argv[0], 1);
}
-static int find_target_obdpath(char *fsname, char *path)
-{
- glob_t glob_info;
- char pattern[PATH_MAX + 1];
- int rc;
-
- snprintf(pattern, PATH_MAX,
- "/proc/fs/lustre/lov/%s-*/target_obd",
- fsname);
- rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
- if (rc == GLOB_NOMATCH)
- return -ENODEV;
- else if (rc)
- return -EINVAL;
-
- strcpy(path, glob_info.gl_pathv[0]);
- globfree(&glob_info);
- return 0;
-}
-
-static int find_poolpath(char *fsname, char *poolname, char *poolpath)
-{
- glob_t glob_info;
- char pattern[PATH_MAX + 1];
- int rc;
-
- snprintf(pattern, PATH_MAX,
- "/proc/fs/lustre/lov/%s-*/pools/%s",
- fsname, poolname);
- rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
- /* If no pools, make sure the lov is available */
- if ((rc == GLOB_NOMATCH) &&
- (find_target_obdpath(fsname, poolpath) == -ENODEV))
- return -ENODEV;
- if (rc)
- return -EINVAL;
-
- strcpy(poolpath, glob_info.gl_pathv[0]);
- globfree(&glob_info);
- return 0;
-}
-
-/*
- * if pool is NULL, search ostname in target_obd
- * if pool is no 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 llapi_search_ost(char *fsname, char *poolname, char *ostname)
-{
- FILE *fd;
- char buffer[PATH_MAX + 1];
- int len = 0, rc;
-
- if (ostname != NULL)
- len = strlen(ostname);
-
- if (poolname == NULL)
- rc = find_target_obdpath(fsname, buffer);
- else
- rc = find_poolpath(fsname, poolname, buffer);
- if (rc)
- return rc;
-
- if ((fd = fopen(buffer, "r")) == NULL)
- return -EINVAL;
-
- while (fgets(buffer, sizeof(buffer), fd) != NULL) {
- if (poolname == NULL) {
- char *ptr;
- /* Search for an ostname in the list of OSTs
- Line format is IDX: fsname-OSTxxxx_UUID STATUS */
- ptr = strchr(buffer, ' ');
- if ((ptr != NULL) &&
- (strncmp(ptr + 1, ostname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- } else {
- /* Search for an ostname in a pool,
- (or an existing non-empty pool if no ostname) */
- if ((ostname == NULL) ||
- (strncmp(buffer, ostname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- }
- }
- fclose(fd);
- return 0;
-}
-
static int check_pool_cmd(enum lcfg_command_type cmd,
char *fsname, char *poolname,
char *ostname)