Whamcloud - gitweb
b=19919
authornathan <nathan>
Mon, 9 Nov 2009 23:20:09 +0000 (23:20 +0000)
committernathan <nathan>
Mon, 9 Nov 2009 23:20:09 +0000 (23:20 +0000)
i=manoj
i=adilger
Make sure there is a valid pool when creating a new file with llapi
Fixes for 19406
Various pools test cleanups and fixes

b=19027
i=brian
i=rread
Don't be so anal about using _UUID in user interface; e.g. accept
lustre-OST0000, lustre-OST0000-osc-4ba41334 as well as lustre-OST0000_UUID.

lustre/include/lustre/liblustreapi.h
lustre/tests/ost-pools.sh
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c
lustre/utils/obd.c

index 4594968..59f4216 100644 (file)
@@ -81,7 +81,7 @@ extern int llapi_file_open_pool(const char *name, int flags, int mode,
                                 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);
@@ -164,8 +164,10 @@ extern int llapi_is_lustre_mnttype(const char *type);
 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);
index 3f3a1e9..47b6973 100644 (file)
@@ -1,4 +1,6 @@
 #!/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.
@@ -40,6 +42,7 @@ LCTL=${LCTL:-lctl}
 SETSTRIPE=${SETSTRIPE:-"$LFS setstripe"}
 GETSTRIPE=${GETSTRIPE:-"$LFS getstripe"}
 
+SINGLEMDS=mds
 
 TSTUSR=${TSTUSR:-"quota_usr"}
 TSTID=${TSTID:-60000}
@@ -95,8 +98,8 @@ create_file() {
 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
@@ -140,7 +143,7 @@ check_file_in_osts() {
 
         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
 }
@@ -160,7 +163,8 @@ check_file_not_in_pool() {
 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
@@ -170,7 +174,7 @@ check_dir_not_in_pool() {
 }
 
 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
@@ -190,13 +194,15 @@ drain_pool() {
 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
 }
@@ -219,7 +225,8 @@ create_pool_fail() {
 
 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}
@@ -258,27 +265,27 @@ test_1() {
     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
@@ -289,7 +296,7 @@ run_test 1 "Test lctl pool_new  ========================================="
 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."
@@ -297,7 +304,8 @@ test_2a() {
 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."
 }
@@ -315,43 +323,43 @@ test_2c() {
     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
@@ -369,7 +377,7 @@ test_2d() {
     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."
 
@@ -389,10 +397,11 @@ test_2e() {
     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
 
@@ -411,28 +420,27 @@ test_3a() {
     [[ $? -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
@@ -440,26 +448,26 @@ test_3d() {
         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
@@ -473,14 +481,14 @@ test_4a() {
     [[ $? -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."
 }
@@ -490,9 +498,9 @@ test_4c() {
     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 ==============================="
@@ -500,12 +508,12 @@ 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
@@ -513,21 +521,21 @@ sub_test_5() {
     [[ $? -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 ]] || \
@@ -540,7 +548,7 @@ sub_test_5() {
     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"
 
@@ -554,8 +562,8 @@ test_5() {
     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"
@@ -567,11 +575,11 @@ test_6() {
 
     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
@@ -580,14 +588,14 @@ test_6() {
     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
@@ -601,7 +609,7 @@ test_6() {
     # 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."
 
@@ -618,10 +626,10 @@ test_11() {
     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
@@ -660,10 +668,10 @@ test_12() {
     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
@@ -680,10 +688,10 @@ test_12() {
     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
@@ -716,7 +724,7 @@ test_13() {
     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 || \
@@ -1106,22 +1114,26 @@ add_loop() {
     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
@@ -1130,6 +1142,9 @@ test_22() {
           error "createmany $POOL_ROOT/${tfile} failed!"
     wait
 
+    destroy_pool $POOL
+    destroy_pool $POOL2
+
     return 0
 }
 run_test 22 "Simultaneous manipulation of a pool"
@@ -1293,21 +1308,22 @@ test_25() {
     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 ======================="
index d070ba1..ad6a1f7 100644 (file)
@@ -1,4 +1,6 @@
 #!/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.
@@ -6352,43 +6354,56 @@ test_200f() {
 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 ============================================"
 
index 9653cfe..5dcc68b 100644 (file)
@@ -55,6 +55,7 @@
 #include <errno.h>
 #include <dirent.h>
 #include <stdarg.h>
+#include <ctype.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/syscall.h>
@@ -262,7 +263,98 @@ int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
         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,
@@ -271,7 +363,40 @@ int llapi_file_open_pool(const char *name, int flags, int mode,
         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) {
@@ -297,19 +422,7 @@ int llapi_file_open_pool(const char *name, int flags, int mode,
         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 */
@@ -375,24 +488,93 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
         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;
 }
 
 /*
@@ -404,60 +586,48 @@ static int print_pool_members(char *fs, char *pool_dir, char *pool_file)
  * 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;
 }
 
 /*
@@ -467,44 +637,131 @@ int llapi_search_mounts(const char *pathname, int index, char *mntdir,
 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, '/');
@@ -514,72 +771,100 @@ int llapi_poollist(char *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,
@@ -686,6 +971,24 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
         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)
@@ -729,8 +1032,7 @@ 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;
                         }
@@ -745,10 +1047,10 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
 
         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);
@@ -792,16 +1094,22 @@ retry_get_uuids:
                 return -ENOMEM;
 
         for (obdnum = 0; obdnum < param->num_obds; obdnum++) {
-                for (i = 0; i <= obdcount; i++) {
-                        if (strcmp((char *)&param->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)
@@ -811,7 +1119,7 @@ retry_get_uuids:
 
         param->got_uuids = 1;
 
-        return 0;
+        return ret;
 }
 
 static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
@@ -1117,8 +1425,8 @@ int llapi_mds_getfileinfo(char *path, DIR *parent,
 
         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) {
@@ -1874,7 +2182,9 @@ static void do_target_check(char *obd_type_name, char *obd_name,
         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);
index 96783ca..0479315 100644 (file)
@@ -2537,106 +2537,13 @@ void obd_finalize(int argc, char **argv)
         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);
@@ -3017,7 +2924,7 @@ err:
 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;