unsigned long long stripe_size,
int stripe_offset, int stripe_count,
int stripe_pattern, char *pool_name);
-extern int llapi_poollist(char *name);
+extern int llapi_poollist(const char *name);
extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
#define HAVE_LLAPI_FILE_LOOKUP
extern int llapi_file_lookup(int dirfd, const char *name);
extern int llapi_search_ost(char *fsname, char *poolname, char *ostname);
extern int llapi_search_mounts(const char *pathname, int index,
char *mntdir, char *fsname);
+extern int llapi_search_fsname(const char *pathname, char *fsname);
extern int parse_size(char *optarg, unsigned long long *size,
unsigned long long *size_units, int bytes_spec);
+
extern void llapi_ping_target(char *obd_type, char *obd_name,
char *obd_uuid, void *args);
extern int llapi_path2fid(const char *path, lustre_fid *fid);
#!/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.
SETSTRIPE=${SETSTRIPE:-"$LFS setstripe"}
GETSTRIPE=${GETSTRIPE:-"$LFS getstripe"}
+SINGLEMDS=mds
TSTUSR=${TSTUSR:-"quota_usr"}
TSTID=${TSTID:-60000}
osts_in_pool() {
local pool=$1
local res
- for i in $(do_facet mds lctl pool_list $FSNAME.$pool | grep -v "^Pool:" \
- | sed -e 's/_UUID$//;s/^.*-OST//'); do
+ for i in $(do_facet $SINGLEMDS lctl pool_list $FSNAME.$pool | \
+ grep -v "^Pool:" | sed -e 's/_UUID$//;s/^.*-OST//'); do
res="$res $(printf "%d" 0x$i)"
done
echo $res
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
}
check_dir_not_in_pool() {
local dir=$1
local pool=$2
- local res=$($GETSTRIPE -v $dir | grep "^stripe_count" | head -1 | cut -f 8 -d ' ')
+ local res=$($GETSTRIPE -v $dir | grep "^stripe_count" | head -1 | \
+ cut -f 8 -d ' ')
if [[ "$res" == "$pool" ]]; then
error "File $dir is in pool: $res"
return 1
}
create_pool() {
- do_facet mds lctl pool_new $FSNAME.$1
+ do_facet $SINGLEMDS lctl pool_new $FSNAME.$1
local RC=$?
# get param should return err until pool is created
[[ $RC -ne 0 ]] && return $RC
add_pool() {
local pool=$1
local osts=$2
- local tgt="${3}$(lctl get_param -n lov.$FSNAME-*.pools.$pool | sort -u | tr '\n' ' ')"
+ local tgt="${3}$(lctl get_param -n lov.$FSNAME-*.pools.$pool | \
+ sort -u | tr '\n' ' ')"
- do_facet mds lctl pool_add $FSNAME.$pool $osts
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$pool $osts
local RC=$?
[[ $RC -ne 0 ]] && return $RC
- wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool | sort -u | tr '\n' ' ' " "$tgt" || RC=1
+ wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool | \
+ sort -u | tr '\n' ' ' " "$tgt" || RC=1
[[ $RC -ne 0 ]] && error "pool_add failed: $1; $2"
return $RC
}
cleanup_tests() {
# Destroy pools from previous test runs
- for p in $(do_facet mds lctl pool_list $FSNAME | grep $FSNAME.pool[0-$OSTCOUNT]); do
+ for p in $(do_facet $SINGLEMDS lctl pool_list $FSNAME | \
+ grep $FSNAME.pool[0-$OSTCOUNT]); do
destroy_pool_int $p;
done
rm -rf $DIR/d0.${TESTSUITE}
create_pool_fail $NAME
echo "pool_new should fail if fs-name or poolname are missing."
- do_facet mds 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 mds 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 mds 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 mds 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 mds 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 mds 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 mds 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 mds 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."
run_test 2a "pool_add: non-existant pool"
test_2b() {
- do_facet mds lctl pool_add $FSNAME.p1234567891234567890 $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.p1234567891234567890 \
+ $FSNAME-OST0000 2>/dev/null
[[ $? -ne 0 ]] || \
error "pool_add did not fail even though pool name was invalid."
}
create_pool_nofail $POOL
# 1. OST0000
- do_facet mds lctl pool_add $FSNAME.$POOL OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL OST0000
RC=$?; [[ $RC -eq 0 ]] || \
error "pool_add failed. $FSNAME $POOL OST0000: $RC"
- do_facet mds lctl pool_remove $FSNAME.$POOL OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL OST0000
drain_pool $POOL
# 2. lustre-OST0000
- do_facet mds lctl pool_add $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000
RC=$?; [[ $RC -eq 0 ]] || \
error "pool_add failed. $FSNAME $POOL $FSNAME-OST0000: $RC"
- do_facet mds lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000
drain_pool $POOL
# 3. lustre-OST0000_UUID
- do_facet mds lctl pool_add $FSNAME.$POOL $FSNAME-OST0000_UUID
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000_UUID
RC=$?; [[ $RC -eq 0 ]] || \
error "pool_add failed. $FSNAME $POOL $FSNAME-OST0000_UUID: $RC"
- do_facet mds lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000_UUID
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000_UUID
drain_pool $POOL
# 4. lustre-OST[0,1,2,3,]
TGT="$FSNAME-OST["
for i in $TGT_LIST; do TGT=${TGT}$(printf "$i," $i); done
TGT="${TGT}]"
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT
[[ $? -eq 0 ]] || \
error "pool_add failed. $FSNAME.$POOL $TGT. $RC"
- do_facet mds lctl pool_remove $FSNAME.$POOL $TGT
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $TGT
drain_pool $POOL
# 5. lustre-OST[0-5/1]
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT_ALL
RC=$?; [[ $RC -eq 0 ]] || \
error "pool_add failed. $FSNAME $POOL" "$TGT_ALL $RC"
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | \
sort -u | tr '\n' ' ' " "$TGT_UUID" || error "Add to pool failed"
- do_facet mds lctl pool_remove $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $TGT_ALL
drain_pool $POOL
destroy_pool $POOL
create_pool_nofail $POOL
TGT=$(printf "$FSNAME-OST%04x_UUID " $OSTCOUNT)
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT
RC=$?; [[ $RC -ne 0 ]] || \
error "pool_add succeeded for an OST ($TGT) that does not exist."
create_pool_nofail $POOL
TGT="$FSNAME-OST0000_UUID "
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | \
sort -u | tr '\n' ' ' " "$TGT" || error "Add to pool failed"
- RESULT=$(do_facet mds "LOCALE=C $LCTL pool_add $FSNAME.$POOL $TGT 2>&1")
+ RESULT=$(do_facet $SINGLEMDS \
+ "LOCALE=C $LCTL pool_add $FSNAME.$POOL $TGT 2>&1")
RC=$?
echo $RESULT
[[ $? -ne 0 ]] || \
destroy_pool $POOL
- do_facet mds 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 mds 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."
}
run_test 3b "pool_remove: non-existant fsname"
test_3c() {
- do_facet mds lctl pool_remove $FSNAME.p1234567891234567890 $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.p1234567891234567890 \
+ $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
destroy_pool $POOL
create_pool_nofail $POOL
- do_facet mds lctl pool_add $FSNAME.$POOL OST0000
- do_facet mds lctl pool_remove $FSNAME.$POOL OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL OST0000
[[ $? -eq 0 ]] || \
error "pool_remove failed. $FSNAME $POOL OST0000"
drain_pool $POOL
- do_facet mds lctl pool_add $FSNAME.$POOL $FSNAME-OST0000
- do_facet mds lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000
[[ $? -eq 0 ]] || \
error "pool_remove failed. $FSNAME $POOL $FSNAME-OST0000"
drain_pool $POOL
- do_facet mds lctl pool_add $FSNAME.$POOL $FSNAME-OST0000_UUID
- do_facet mds lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000_UUID
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $FSNAME-OST0000_UUID
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST0000_UUID
[[ $? -eq 0 ]] || \
error "pool_remove failed. $FSNAME $POOL $FSNAME-OST0000_UUID"
drain_pool $POOL
add_pool $POOL $TGT_ALL "$TGT_UUID"
- do_facet mds lctl pool_remove $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $TGT_ALL
[[ $? -eq 0 ]] || \
error "pool_remove failed. $FSNAME $POOL" $TGT_ALL
drain_pool $POOL
[[ $? -ne 0 ]] || \
destroy_pool $POOL
- do_facet mds 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 mds 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."
}
create_pool_nofail $POOL
add_pool $POOL "OST0000" "$FSNAME-OST0000_UUID "
- do_facet mds lctl pool_destroy ${FSNAME}.$POOL
+ 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 failed."
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT_ALL
$LCMD pool_list $FSNAME.$POOL
[[ $? -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"
- if [[ ! $(grep mds <<< $LCMD) ]]; then
+ if [[ ! $(grep $SINGLEMDS <<< $LCMD) ]]; then
echo $LCMD pool_list $DIR
$LCMD pool_list $DIR
[[ $? -eq 0 ]] || \
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"
sub_test_5 $LFS
# Issue commands from MDS
- sub_test_5 "do_facet mds lctl"
- sub_test_5 "do_facet mds lfs"
+ sub_test_5 "do_facet $SINGLEMDS lctl"
+ sub_test_5 "do_facet $SINGLEMDS lfs"
}
run_test 5 "lfs/lctl pool_list"
create_pool_nofail $POOL
- do_facet mds lctl pool_list $FSNAME
+ do_facet $SINGLEMDS lctl pool_list $FSNAME
[[ $? -eq 0 ]] || \
error "pool_list $FSNAME failed."
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT_ALL
mkdir -p $POOL_DIR
$SETSTRIPE -c -1 -p $POOL $POOL_DIR
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."
create_pool_nofail $POOL
create_pool_nofail $POOL2
- do_facet mds lctl pool_add $FSNAME.$POOL \
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL \
$FSNAME-OST[$TGT_FIRST-$TGT_MAX/2]
local start=$((TGT_FIRST+1))
- do_facet mds lctl pool_add $FSNAME.$POOL2 \
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL2 \
$FSNAME-OST[$start-$TGT_MAX/2]
create_dir $POOL_ROOT/dir1 $POOL
create_pool_nofail $POOL
create_pool_nofail $POOL2
- do_facet mds lctl pool_add $FSNAME.$POOL \
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL \
$FSNAME-OST[$TGT_FIRST-$TGT_MAX/2]
local start=$((TGT_FIRST+1))
- do_facet mds lctl pool_add $FSNAME.$POOL2 \
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL2 \
$FSNAME-OST[$start-$TGT_MAX/2]
echo creating some files in $POOL and $POOL2
check_file_in_pool $POOL_ROOT/file2 $POOL2
echo Changing the pool membership
- do_facet mds lctl pool_remove $FSNAME.$POOL $FSNAME-OST[$TGT_FIRST]
- do_facet mds lctl pool_list $FSNAME.$POOL
- do_facet mds lctl pool_add $FSNAME.$POOL2 $FSNAME-OST[$TGT_FIRST]
- do_facet mds lctl pool_list $FSNAME.$POOL2
+ do_facet $SINGLEMDS lctl pool_remove $FSNAME.$POOL $FSNAME-OST[$TGT_FIRST]
+ do_facet $SINGLEMDS lctl pool_list $FSNAME.$POOL
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL2 $FSNAME-OST[$TGT_FIRST]
+ do_facet $SINGLEMDS lctl pool_list $FSNAME.$POOL2
echo Checking the files again
check_dir_in_pool $POOL_ROOT/dir1 $POOL
local count=3
create_pool_nofail $POOL
- do_facet mds lctl pool_add $FSNAME.$POOL $TGT_ALL
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.$POOL $TGT_ALL
create_dir $POOL_ROOT/dir1 $POOL -1
createmany -o $POOL_ROOT/dir1/$tfile $numfiles || \
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 mds 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"
mkdir -p $POOL_ROOT
for i in $(seq 10); do
- create_pool_nofail pool$i
- stop mds || return 1
- sleep 10
- start mds $MDSDEV $MDS_MOUNT_OPTS || \
- error "Failed to start MDS after stopping"
+ create_pool_nofail pool$i
+ do_facet $SINGLEMDS lctl pool_add $FSNAME.pool$i OST0000
+ stop $SINGLEMDS || return 1
+ start $SINGLEMDS $MDSDEV $MDS_MOUNT_OPTS || \
+ { 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
- done
+ echo "Creating a file in 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
for i in $(seq 10); do
- destroy_pool pool$i
+ destroy_pool pool$i
done
}
run_test 25 "Create new pool and restart MDS ======================="
#!/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.
run_test 200f "Create files in a pool ==================================="
test_200g() {
- test_pools || return 0
+ test_pools || return 0
- 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"
+ 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_pools || return 0
- TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
- do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
- wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | grep $TGT" "" || error "$TGT not removed from $FSNAME.$POOL"
+test_201a() {
+ test_pools || return 0
+
+ TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
+ do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
+ wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | grep $TGT" "" || error "$TGT not removed from $FSNAME.$POOL"
}
run_test 201a "Remove a target from a pool ============================="
-test_201b() { # was 200h
- test_pools || return 0
- for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u)
- do
- do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
- 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"
+test_201b() {
+ test_pools || return 0
+
+ for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u)
+ do
+ do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
+ done
+ wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL" ""\
+ || error "Pool $FSNAME.$POOL cannot be drained"
+ # 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_pools || return 0
- do_facet mgs $LCTL pool_destroy $FSNAME.$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
- error "Pool $FSNAME.$POOL is not destroyed"
+test_201c() {
+ test_pools || return 0
+
+ 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
+ error "Pool $FSNAME.$POOL is not destroyed"
}
run_test 201c "Remove a pool ============================================"
#include <errno.h>
#include <dirent.h>
#include <stdarg.h>
+#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/syscall.h>
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);
- fsname[ptr - pool_name] = '\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 */
return 0;
}
-
-static int print_pool_members(char *fs, char *pool_dir, char *pool_file)
+/*
+ * Find the fsname, the full path, and/or an open fd.
+ * Either the fsname or path must not be NULL
+ */
+#define WANT_PATH 0x1
+#define WANT_FSNAME 0x2
+#define WANT_FD 0x4
+#define WANT_INDEX 0x8
+#define WANT_ERROR 0x10
+static int get_root_path(int want, char *fsname, int *outfd, char *path,
+ int index)
{
- char path[MAXPATHLEN + 1];
- char buf[1024];
- FILE *fd;
+ struct mntent mnt;
+ char buf[PATH_MAX], mntdir[PATH_MAX];
+ char *ptr;
+ FILE *fp;
+ int idx = 0, len = 0, mntlen, fd;
+ int rc = -ENODEV;
- llapi_printf(LLAPI_MSG_NORMAL, "Pool: %s.%s\n", fs, pool_file);
- sprintf(path, "%s/%s", pool_dir, pool_file);
- if ((fd = fopen(path, "r")) == NULL) {
- llapi_err(LLAPI_MSG_ERROR, "Cannot open %s\n", path);
- return -EINVAL;
+ /* get the mount point */
+ fp = setmntent(MOUNTED, "r");
+ if (fp == NULL) {
+ llapi_err(LLAPI_MSG_ERROR,
+ "setmntent(%s) failed: %s:", MOUNTED,
+ strerror (errno));
+ return -EIO;
}
- while (fgets(buf, sizeof(buf), fd) != NULL)
- llapi_printf(LLAPI_MSG_NORMAL, buf);
+ while (1) {
+ if (getmntent_r(fp, &mnt, buf, sizeof(buf)) == NULL)
+ break;
- fclose(fd);
- return 0;
+ if (!llapi_is_lustre_mnt(&mnt))
+ continue;
+
+ mntlen = strlen(mnt.mnt_dir);
+ ptr = strrchr(mnt.mnt_fsname, '/');
+ if (!ptr && !len) {
+ rc = -EINVAL;
+ break;
+ }
+ ptr++;
+
+ if ((want & WANT_INDEX) && (idx++ != index))
+ continue;
+
+ /* 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);
+ 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);
+ len = mntlen;
+ if ((want & WANT_FSNAME) && fsname != NULL)
+ strcpy(fsname, ptr);
+ rc = 0;
+ }
+ }
+ endmntent(fp);
+
+ /* Found it */
+ if (rc == 0) {
+ if ((want & WANT_PATH) && path != NULL)
+ strcpy(path, mntdir);
+ if (want & WANT_FD) {
+ fd = open(mntdir, O_RDONLY | O_DIRECTORY | O_NONBLOCK);
+ if (fd < 0) {
+ perror("open");
+ rc = -errno;
+ } else {
+ *outfd = fd;
+ }
+ }
+ } else if (want & WANT_ERROR)
+ llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+ "can't find fs root for '%s': %d",
+ (want & WANT_PATH) ? fsname : path, rc);
+ return rc;
}
/*
* The user inputs are pathname and index. If the pathname is supplied then
* the value of the index will be ignored. The pathname will return data if
* the pathname is located on a lustre mount. Index is used to pick which
- * mount point you want in the case of multiple mounted lustre file systems.
+ * mount point you want in the case of multiple mounted lustre file systems.
* See function lfs_osts in lfs.c for a example of the index use.
*/
-int llapi_search_mounts(const char *pathname, int index, char *mntdir,
+int llapi_search_mounts(const char *pathname, int index, char *mntdir,
char *fsname)
{
- int len = 0, idx = 0, rc = -ENOENT;
- char *ptr;
- FILE *fp;
- struct mntent *mnt = NULL;
+ int want = WANT_PATH, idx = -1;
- /* get the mount point */
- fp = setmntent(MOUNTED, "r");
- if (fp == NULL) {
- llapi_err(LLAPI_MSG_ERROR,
- "setmntent(%s) failed: %s:", MOUNTED,
- strerror (errno));
- return -EIO;
- }
- mnt = getmntent(fp);
- while ((feof(fp) == 0) && ferror(fp) == 0) {
- if (llapi_is_lustre_mnt(mnt)) {
- int mntlen = strlen(mnt->mnt_dir);
+ if (!pathname) {
+ want |= WANT_INDEX;
+ idx = index;
+ } else
+ strcpy(mntdir, pathname);
- ptr = strchr(mnt->mnt_fsname, '/');
- if (ptr == NULL && !len) {
- rc = -EINVAL;
- continue;
- }
+ if (fsname)
+ want |= WANT_FSNAME;
+ return get_root_path(want, fsname, NULL, mntdir, idx);
+}
- /* search by pathname */
- if (pathname) {
- if ((mntlen >= len) && (strncmp(mnt->mnt_dir,
- pathname, mntlen) == 0)) {
- strcpy(mntdir, mnt->mnt_dir);
- if (fsname)
- strcpy(fsname, ++ptr);
- len = mntlen;
- rc = 0;
- }
- } else if (idx == index) {
- strcpy(mntdir, mnt->mnt_dir);
- if (fsname)
- strcpy(fsname, ++ptr);
- rc = 0;
- break;
- }
- idx++;
- }
- mnt = getmntent(fp);
+int llapi_search_fsname(const char *pathname, char *fsname)
+{
+ return get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL,
+ (char *)pathname, -1);
+}
+
+/* return the first file matching this pattern */
+static int first_match(char *pattern, char *buffer)
+{
+ glob_t glob_info;
+
+ if (glob(pattern, GLOB_BRACE, NULL, &glob_info))
+ return -ENOENT;
+
+ if (glob_info.gl_pathc < 1) {
+ globfree(&glob_info);
+ return -ENOENT;
}
- endmntent(fp);
- return rc;
+ strcpy(buffer, glob_info.gl_pathv[0]);
+
+ globfree(&glob_info);
+ return 0;
}
/*
static int poolpath(char *fsname, char *pathname, char *pool_pathname)
{
int rc = 0;
- glob_t glob_info;
- char pattern[MAXPATHLEN + 1];
- char buffer[MAXPATHLEN];
+ char pattern[PATH_MAX + 1];
+ char buffer[PATH_MAX];
if (fsname == NULL) {
- rc = llapi_search_mounts(pathname, 0, pattern, buffer);
+ rc = llapi_search_fsname(pathname, buffer);
if (rc != 0)
return rc;
fsname = buffer;
strcpy(pathname, fsname);
}
- snprintf(pattern, MAXPATHLEN,
- "/proc/fs/lustre/lov/%s-*/pools",
- fsname);
- rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
+ snprintf(pattern, PATH_MAX, "/proc/fs/lustre/lov/%s-*/pools", fsname);
+ rc = first_match(pattern, buffer);
if (rc)
- return -ENOENT;
-
- if (glob_info.gl_pathc == 0) {
- globfree(&glob_info);
- return -ENOENT;
- }
+ return rc;
/* in fsname test mode, pool_pathname is NULL */
if (pool_pathname != NULL)
- strcpy(pool_pathname, glob_info.gl_pathv[0]);
+ strcpy(pool_pathname, buffer);
return 0;
}
-int llapi_poollist(char *name)
+/**
+ * Get the list of pool members.
+ * \param poolname string of format \<fsname\>.\<poolname\>
+ * \param members caller-allocated array of char*
+ * \param list_size size of the members array
+ * \param buffer caller-allocated buffer for storing OST names
+ * \param buffer_size size of the buffer
+ *
+ * \return number of members retrieved for this pool
+ * \retval -error failure
+ */
+int llapi_get_poolmembers(const char *poolname, char **members,
+ int list_size, char *buffer, int buffer_size)
+{
+ char fsname[PATH_MAX + 1];
+ char *pool, *tmp;
+ char pathname[PATH_MAX + 1];
+ char path[PATH_MAX + 1];
+ char buf[1024];
+ FILE *fd;
+ int rc = 0;
+ int nb_entries = 0;
+ int used = 0;
+
+ /* name is FSNAME.POOLNAME */
+ if (strlen(poolname) > PATH_MAX)
+ return -EOVERFLOW;
+ strcpy(fsname, poolname);
+ pool = strchr(fsname, '.');
+ if (pool == NULL)
+ return -EINVAL;
+
+ *pool = '\0';
+ pool++;
+
+ rc = poolpath(fsname, NULL, pathname);
+ if (rc != 0) {
+ errno = -rc;
+ llapi_err(LLAPI_MSG_ERROR, "Lustre filesystem '%s' not found",
+ fsname);
+ return rc;
+ }
+
+ llapi_printf(LLAPI_MSG_NORMAL, "Pool: %s.%s\n", fsname, pool);
+ sprintf(path, "%s/%s", pathname, pool);
+ if ((fd = fopen(path, "r")) == NULL) {
+ llapi_err(LLAPI_MSG_ERROR, "Cannot open %s", path);
+ return -EINVAL;
+ }
+
+ rc = 0;
+ while (fgets(buf, sizeof(buf), fd) != NULL) {
+ if (nb_entries >= list_size) {
+ rc = -EOVERFLOW;
+ break;
+ }
+ /* remove '\n' */
+ if ((tmp = strchr(buf, '\n')) != NULL)
+ *tmp='\0';
+ if (used + strlen(buf) + 1 > buffer_size) {
+ rc = -EOVERFLOW;
+ break;
+ }
+
+ strcpy(buffer + used, buf);
+ members[nb_entries] = buffer + used;
+ used += strlen(buf) + 1;
+ nb_entries++;
+ rc = nb_entries;
+ }
+
+ fclose(fd);
+ return rc;
+}
+
+/**
+ * Get the list of pools in a filesystem.
+ * \param name filesystem name or path
+ * \param poollist caller-allocated array of char*
+ * \param list_size size of the poollist array
+ * \param buffer caller-allocated buffer for storing pool names
+ * \param buffer_size size of the buffer
+ *
+ * \return number of pools retrieved for this filesystem
+ * \retval -error failure
+ */
+int llapi_get_poollist(const char *name, char **poollist, int list_size,
+ char *buffer, int buffer_size)
{
- char *poolname;
- char *fsname;
- char rname[MAXPATHLEN + 1], pathname[MAXPATHLEN + 1];
+ char fsname[PATH_MAX + 1], rname[PATH_MAX + 1], pathname[PATH_MAX + 1];
char *ptr;
+ DIR *dir;
+ struct dirent pool;
+ struct dirent *cookie = NULL;
int rc = 0;
+ unsigned int nb_entries = 0;
+ unsigned int used = 0;
+ unsigned int i;
+
+ /* initilize output array */
+ for (i = 0; i < list_size; i++)
+ poollist[i] = NULL;
/* is name a pathname ? */
ptr = strchr(name, '/');
return -EINVAL;
if (!realpath(name, rname)) {
rc = -errno;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: invalid path '%s'",
- name);
+ llapi_err(LLAPI_MSG_ERROR, "invalid path '%s'", name);
return rc;
}
rc = poolpath(NULL, rname, pathname);
if (rc != 0) {
errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: '%s' is not"
- " a Lustre filesystem",
- name);
+ llapi_err(LLAPI_MSG_ERROR, "'%s' is not"
+ " a Lustre filesystem", name);
return rc;
}
- fsname = rname;
- poolname = NULL;
+ strcpy(fsname, rname);
} else {
- /* name is FSNAME[.POOLNAME] */
- fsname = name;
- poolname = strchr(name, '.');
- if (poolname != NULL) {
- *poolname = '\0';
- poolname++;
- }
+ /* name is FSNAME */
+ strcpy(fsname, name);
rc = poolpath(fsname, NULL, pathname);
- if (rc != 0) {
- errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: Lustre filesystem '%s'"
- " not found", name);
- return rc;
- }
}
if (rc != 0) {
errno = -rc;
- llapi_err(LLAPI_MSG_ERROR,
- "llapi_poollist: Lustre filesystem '%s' not found",
+ llapi_err(LLAPI_MSG_ERROR, "Lustre filesystem '%s' not found",
name);
return rc;
}
- if (poolname != NULL) {
- rc = print_pool_members(fsname, pathname, poolname);
- poolname--;
- *poolname = '.';
- } else {
- DIR *dir;
- struct dirent *pool;
+ llapi_printf(LLAPI_MSG_NORMAL, "Pools from %s:\n", fsname);
+ if ((dir = opendir(pathname)) == NULL) {
+ llapi_err(LLAPI_MSG_ERROR, "Could not open pool list for '%s'",
+ name);
+ return -errno;
+ }
- llapi_printf(LLAPI_MSG_NORMAL, "Pools from %s:\n", fsname);
- if ((dir = opendir(pathname)) == NULL) {
- return -EINVAL;
- }
- while ((pool = readdir(dir)) != NULL) {
- if (!((pool->d_name[0] == '.') &&
- (pool->d_name[1] == '\0')) &&
- !((pool->d_name[0] == '.') &&
- (pool->d_name[1] == '.') &&
- (pool->d_name[2] == '\0')))
- llapi_printf(LLAPI_MSG_NORMAL, " %s.%s\n",
- fsname, pool->d_name);
- }
- closedir(dir);
+ while(1) {
+ rc = readdir_r(dir, &pool, &cookie);
+
+ if (rc != 0) {
+ llapi_err(LLAPI_MSG_ERROR,
+ "Error reading pool list for '%s'", name);
+ return -errno;
+ } else if ((rc == 0) && (cookie == NULL))
+ /* end of directory */
+ break;
+
+ /* ignore . and .. */
+ if (!strcmp(pool.d_name, ".") || !strcmp(pool.d_name, ".."))
+ continue;
+
+ /* check output bounds */
+ if (nb_entries >= list_size)
+ return -EOVERFLOW;
+
+ /* +2 for '.' and final '\0' */
+ if (used + strlen(pool.d_name) + strlen(fsname) + 2
+ > buffer_size)
+ return -EOVERFLOW;
+
+ sprintf(buffer + used, "%s.%s", fsname, pool.d_name);
+ poollist[nb_entries] = buffer + used;
+ used += strlen(pool.d_name) + strlen(fsname) + 2;
+ nb_entries++;
}
- return rc;
+
+ closedir(dir);
+ return nb_entries;
+}
+
+/* wrapper for lfs.c and obd.c */
+int llapi_poollist(const char *name)
+{
+ /* list of pool names (assume that pool count is smaller
+ than OST count) */
+ char *list[FIND_MAX_OSTS];
+ char *buffer;
+ /* fsname-OST0000_UUID < 32 char, 1 per OST */
+ int bufsize = FIND_MAX_OSTS * 32;
+ int i, nb;
+
+ buffer = malloc(bufsize);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ if ((name[0] == '/') || (strchr(name, '.') == NULL))
+ /* name is a path or fsname */
+ nb = llapi_get_poollist(name, list, FIND_MAX_OSTS, buffer,
+ bufsize);
+ else
+ /* name is a pool name (<fsname>.<poolname>) */
+ nb = llapi_get_poolmembers(name, list, FIND_MAX_OSTS, buffer,
+ bufsize);
+
+ for (i = 0; i < nb; i++)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s\n", list[i]);
+
+ free(buffer);
+ return (nb < 0 ? nb : 0);
}
typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d,
return rc;
}
+/* Check if user specified value matches a real uuid. Ignore _UUID,
+ * -osc-4ba41334, other trailing gunk in comparison.
+ * @param real_uuid ends in "_UUID"
+ * @param search_uuid may or may not end in "_UUID"
+ */
+int llapi_uuid_match(char *real_uuid, char *search_uuid)
+{
+ int cmplen = strlen(real_uuid) - 5;
+
+ if ((strlen(search_uuid) > cmplen) && isxdigit(search_uuid[cmplen])) {
+ /* OST00000003 doesn't match OST0000 */
+ llapi_err(LLAPI_MSG_ERROR, "Bad UUID format '%s'", search_uuid);
+ return 0;
+ }
+
+ return (strncmp(search_uuid, real_uuid, cmplen) == 0);
+}
+
/* Here, param->obduuid points to a single obduuid, the index of which is
* returned in param->obdindex */
static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
break;
if (param->obduuid) {
- if (strncmp((char *)param->obduuid->uuid, uuid,
- sizeof(uuid)) == 0) {
+ if (llapi_uuid_match(uuid, param->obduuid->uuid)) {
param->obdindex = index;
break;
}
if (!param->quiet && param->obduuid &&
(param->obdindex == OBD_NOT_FOUND)) {
- llapi_err_noerrno(LLAPI_MSG_ERROR,
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
"error: %s: unknown obduuid: %s",
__FUNCTION__, param->obduuid->uuid);
- //rc = EINVAL;
+ rc = -EINVAL;
}
return (rc);
return -ENOMEM;
for (obdnum = 0; obdnum < param->num_obds; obdnum++) {
- for (i = 0; i <= obdcount; i++) {
- if (strcmp((char *)¶m->obduuid[obdnum].uuid,
- (char *)&uuids[i]) == 0) {
+ for (i = 0; i < obdcount; i++) {
+ if (llapi_uuid_match(uuids[i].uuid,
+ param->obduuid[obdnum].uuid)) {
param->obdindexes[obdnum] = i;
obd_valid++;
break;
}
}
- if (i == obdcount)
+ if (i >= obdcount) {
param->obdindexes[obdnum] = OBD_NOT_FOUND;
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error: %s: unknown obduuid: %s",
+ __FUNCTION__,
+ param->obduuid[obdnum].uuid);
+ ret = -EINVAL;
+ }
}
if (obd_valid == 0)
param->got_uuids = 1;
- return 0;
+ return ret;
}
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
fname = (fname == NULL ? path : fname + 1);
/* retrieve needed file info */
- strncpy((char *)lmd, fname, lov_mds_md_size(MAX_LOV_UUID_COUNT,
- LOV_MAGIC));
+ strncpy((char *)lmd, fname,
+ lov_mds_md_size(MAX_LOV_UUID_COUNT, LOV_MAGIC));
ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd);
if (ret) {
int rc;
rc = llapi_ping(obd_type_name, obd_name);
- if (rc) {
+ if (rc == ENOTCONN) {
+ llapi_printf(LLAPI_MSG_NORMAL, "%s inactive.\n", obd_name);
+ } else if (rc) {
llapi_err(LLAPI_MSG_ERROR, "error: check '%s'", obd_name);
} else {
llapi_printf(LLAPI_MSG_NORMAL, "%s active.\n", obd_name);
do_disconnect(argv[0], 1);
}
-static int find_target_obdpath(char *fsname, char *path)
-{
- glob_t glob_info;
- char pattern[MAXPATHLEN + 1];
- int rc;
-
- snprintf(pattern, MAXPATHLEN,
- "/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[MAXPATHLEN + 1];
- int rc;
-
- snprintf(pattern, MAXPATHLEN,
- "/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[MAXPATHLEN + 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)
{
int rc;
- rc = llapi_search_ost(fsname, poolname, NULL);
+ rc = llapi_search_ost(fsname, poolname, ostname);
if (rc < 0 && (cmd != LCFG_POOL_NEW)) {
fprintf(stderr, "Pool %s.%s not found\n",
fsname, poolname);
int jt_pool_cmd(int argc, char **argv)
{
enum lcfg_command_type cmd;
- char fsname[MAXPATHLEN + 1];
+ char fsname[PATH_MAX + 1];
char poolname[LOV_MAXPOOLNAME + 1];
char *ostnames_buf = NULL;
int i, rc;