From d908fe9686bc1e583da7434856d9c06e6cbbc4fd Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Sun, 22 Sep 2019 20:06:07 +0800 Subject: [PATCH] LU-11743 utils: allow lctl pool_list on separate MGS Change lctl pool_list command to parse the configuration log directly when run on a standalone MGS node. This also allows the pool commands to be run when only the MGS is started. Also, those test scripts from the patch of LU-9899 to mount a client on the standalone MGS to allow OST pools to work properly are cleared. Change-Id: Ic25931d49c2cf747da2a3f2ac3c25a21f6878991 Test-Parameters: standalonemgs=true testlist=ost-pools.sh,sanity.sh,conf-sanity.sh Signed-off-by: Emoly Liu Signed-off-by: Vladimir Saveliev Reviewed-on: https://review.whamcloud.com/35895 Tested-by: jenkins Reviewed-by: Li Xi Reviewed-by: Andreas Dilger Tested-by: Maloo --- lustre/include/uapi/linux/lustre/lustre_cfg.h | 51 ++++ lustre/obdclass/obd_config.c | 49 ---- lustre/tests/conf-sanity.sh | 40 --- lustre/tests/ost-pools.sh | 7 +- lustre/tests/replay-single.sh | 8 - lustre/tests/sanity.sh | 52 +--- lustre/tests/test-framework.sh | 13 - lustre/utils/obd.c | 376 +++++++++++++++++++++----- 8 files changed, 378 insertions(+), 218 deletions(-) mode change 100755 => 100644 lustre/tests/sanity.sh diff --git a/lustre/include/uapi/linux/lustre/lustre_cfg.h b/lustre/include/uapi/linux/lustre/lustre_cfg.h index af78b57..93884d7 100644 --- a/lustre/include/uapi/linux/lustre/lustre_cfg.h +++ b/lustre/include/uapi/linux/lustre/lustre_cfg.h @@ -172,6 +172,57 @@ struct lustre_cfg { __u32 lcfg_buflens[0]; }; +struct lcfg_type_data { + __u32 ltd_type; + char *ltd_name; + char *ltd_bufs[4]; +}; + +static struct lcfg_type_data lcfg_data_table[] = { + { LCFG_ATTACH, "attach", { "type", "UUID", "3", "4" } }, + { LCFG_DETACH, "detach", { "1", "2", "3", "4" } }, + { LCFG_SETUP, "setup", { "UUID", "node", "options", "failout" } }, + { LCFG_CLEANUP, "cleanup", { "1", "2", "3", "4" } }, + { LCFG_ADD_UUID, "add_uuid", { "node", "2", "3", "4" } }, + { LCFG_DEL_UUID, "del_uuid", { "1", "2", "3", "4" } }, + { LCFG_MOUNTOPT, "new_profile", { "name", "lov", "lmv", "4" } }, + { LCFG_DEL_MOUNTOPT, "del_mountopt", { "1", "2", "3", "4" } }, + { LCFG_SET_TIMEOUT, "set_timeout", { "parameter", "2", "3", "4" } }, + { LCFG_SET_UPCALL, "set_upcall", { "1", "2", "3", "4" } }, + { LCFG_ADD_CONN, "add_conn", { "node", "2", "3", "4" } }, + { LCFG_DEL_CONN, "del_conn", { "1", "2", "3", "4" } }, + { LCFG_LOV_ADD_OBD, "add_osc", { "ost", "index", "gen", "UUID" } }, + { LCFG_LOV_DEL_OBD, "del_osc", { "1", "2", "3", "4" } }, + { LCFG_PARAM, "conf_param", { "parameter", "value", "3", "4" } }, + { LCFG_MARKER, "marker", { "1", "2", "3", "4" } }, + { LCFG_LOG_START, "log_start", { "1", "2", "3", "4" } }, + { LCFG_LOG_END, "log_end", { "1", "2", "3", "4" } }, + { LCFG_LOV_ADD_INA, "add_osc_inactive", { "1", "2", "3", "4" } }, + { LCFG_ADD_MDC, "add_mdc", { "mdt", "index", "gen", "UUID" } }, + { LCFG_DEL_MDC, "del_mdc", { "1", "2", "3", "4" } }, + { LCFG_SPTLRPC_CONF, "security", { "parameter", "2", "3", "4" } }, + { LCFG_POOL_NEW, "new_pool", { "fsname", "pool", "3", "4" } }, + { LCFG_POOL_ADD, "add_pool", { "fsname", "pool", "ost", "4" } }, + { LCFG_POOL_REM, "remove_pool", { "fsname", "pool", "ost", "4" } }, + { LCFG_POOL_DEL, "del_pool", { "fsname", "pool", "3", "4" } }, + { LCFG_SET_LDLM_TIMEOUT, "set_ldlm_timeout", + { "parameter", "2", "3", "4" } }, + { LCFG_SET_PARAM, "set_param", { "parameter", "value", "3", "4" } }, + { 0, NULL, { NULL, NULL, NULL, NULL } } +}; + +static inline struct lcfg_type_data *lcfg_cmd2data(__u32 cmd) +{ + int i = 0; + + while (lcfg_data_table[i].ltd_type != 0) { + if (lcfg_data_table[i].ltd_type == cmd) + return &lcfg_data_table[i]; + i++; + } + return NULL; +} + enum cfg_record_type { PORTALS_CFG_TYPE = 1, LUSTRE_CFG_TYPE = 123, diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 5cb44e7..a54308d 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -1854,55 +1854,6 @@ parse_out: } EXPORT_SYMBOL(class_config_parse_llog); -static struct lcfg_type_data { - __u32 ltd_type; - char *ltd_name; - char *ltd_bufs[4]; -} lcfg_data_table[] = { - { LCFG_ATTACH, "attach", { "type", "UUID", "3", "4" } }, - { LCFG_DETACH, "detach", { "1", "2", "3", "4" } }, - { LCFG_SETUP, "setup", { "UUID", "node", "options", "failout" } }, - { LCFG_CLEANUP, "cleanup", { "1", "2", "3", "4" } }, - { LCFG_ADD_UUID, "add_uuid", { "node", "2", "3", "4" } }, - { LCFG_DEL_UUID, "del_uuid", { "1", "2", "3", "4" } }, - { LCFG_MOUNTOPT, "new_profile", { "name", "lov", "lmv", "4" } }, - { LCFG_DEL_MOUNTOPT, "del_mountopt", { "1", "2", "3", "4" } , }, - { LCFG_SET_TIMEOUT, "set_timeout", { "parameter", "2", "3", "4" } }, - { LCFG_SET_UPCALL, "set_upcall", { "1", "2", "3", "4" } }, - { LCFG_ADD_CONN, "add_conn", { "node", "2", "3", "4" } }, - { LCFG_DEL_CONN, "del_conn", { "1", "2", "3", "4" } }, - { LCFG_LOV_ADD_OBD, "add_osc", { "ost", "index", "gen", "UUID" } }, - { LCFG_LOV_DEL_OBD, "del_osc", { "1", "2", "3", "4" } }, - { LCFG_PARAM, "conf_param", { "parameter", "value", "3", "4" } }, - { LCFG_MARKER, "marker", { "1", "2", "3", "4" } }, - { LCFG_LOG_START, "log_start", { "1", "2", "3", "4" } }, - { LCFG_LOG_END, "log_end", { "1", "2", "3", "4" } }, - { LCFG_LOV_ADD_INA, "add_osc_inactive", { "1", "2", "3", "4" } }, - { LCFG_ADD_MDC, "add_mdc", { "mdt", "index", "gen", "UUID" } }, - { LCFG_DEL_MDC, "del_mdc", { "1", "2", "3", "4" } }, - { LCFG_SPTLRPC_CONF, "security", { "parameter", "2", "3", "4" } }, - { LCFG_POOL_NEW, "new_pool", { "fsname", "pool", "3", "4" } }, - { LCFG_POOL_ADD, "add_pool", { "fsname", "pool", "ost", "4" } }, - { LCFG_POOL_REM, "remove_pool", { "fsname", "pool", "ost", "4" } }, - { LCFG_POOL_DEL, "del_pool", { "fsname", "pool", "3", "4" } }, - { LCFG_SET_LDLM_TIMEOUT, "set_ldlm_timeout", - { "parameter", "2", "3", "4" } }, - { LCFG_SET_PARAM, "set_param", { "parameter", "value", "3", "4" } }, - { 0, NULL, { NULL, NULL, NULL, NULL } } -}; - -static struct lcfg_type_data *lcfg_cmd2data(__u32 cmd) -{ - int i = 0; - - while (lcfg_data_table[i].ltd_type != 0) { - if (lcfg_data_table[i].ltd_type == cmd) - return &lcfg_data_table[i]; - i++; - } - return NULL; -} - /** * Parse config record and output dump in supplied buffer. * diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 898c7ca..7b3f25a 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -6012,9 +6012,6 @@ cleanup_82b() { # Remove OSTs from a pool and destroy the pool. destroy_pool $ost_pool || true - if ! combined_mgs_mds ; then - umount_mgs_client - fi restore_ostindex } @@ -6054,9 +6051,6 @@ test_82b() { # LU-4665 done mount_client $MOUNT || error "mount client $MOUNT failed" - if ! combined_mgs_mds ; then - mount_mgs_client - fi wait_osts_up $LFS df $MOUNT || error "$LFS df $MOUNT failed" @@ -7485,9 +7479,6 @@ test_103() { cp $LUSTRE/tests/test-framework.sh $DIR/$tdir || error "(2) Fail to copy test-framework.sh" - if ! combined_mgs_mds ; then - mount_mgs_client - fi do_facet mgs $LCTL pool_new $FSNAME.pool1 || error "(3) Fail to create $FSNAME.pool1" # name the pool name as the fsname @@ -7499,9 +7490,6 @@ test_103() { $LFS setstripe -p $FSNAME $DIR/$tdir/d0 || error "(6) Fail to setstripe on $DIR/$tdir/d0" - if ! combined_mgs_mds ; then - umount_mgs_client - fi KEEP_ZPOOL=true stopall @@ -7511,9 +7499,6 @@ test_103() { FSNAME="mylustre" setupall - if ! combined_mgs_mds ; then - mount_mgs_client - fi test_103_check_pool $save_fsname 7 if [ $OSTCOUNT -ge 2 ]; then @@ -7522,9 +7507,6 @@ test_103() { $LFS setstripe -p $save_fsname $DIR/$tdir/f0 || error "(16) Fail to setstripe on $DIR/$tdir/f0" - if ! combined_mgs_mds ; then - umount_mgs_client - fi stopall @@ -7533,14 +7515,8 @@ test_103() { FSNAME="tfs" setupall - if ! combined_mgs_mds ; then - mount_mgs_client - fi test_103_check_pool $save_fsname 17 - if ! combined_mgs_mds ; then - umount_mgs_client - fi stopall test_renamefs $save_fsname @@ -8014,18 +7990,12 @@ test_109a() reformat setup_noconfig client_up || error "client_up failed" - #pool commands requires a client on MGS for procfs interfaces - if ! combined_mgs_mds ; then - mount_mgs_client - stack_trap umount_mgs_client EXIT - fi # # set number of permanent parameters # test_109_set_params $FSNAME - combined_mgs_mds || umount_mgs_client umount_client $MOUNT || error "umount_client failed" stop_ost || error "stop_ost failed" stop_mds || error "stop_mds failed" @@ -8040,7 +8010,6 @@ test_109a() error "failed to clear client config" setup_noconfig - combined_mgs_mds || mount_mgs_client # # check that configurations are intact @@ -8052,7 +8021,6 @@ test_109a() # destroy_test_pools || error "destroy test pools failed" - combined_mgs_mds || umount_mgs_client cleanup } run_test 109a "test lctl clear_conf fsname" @@ -8068,18 +8036,12 @@ test_109b() reformat setup_noconfig client_up || error "client_up failed" - #pool commands requires a client on MGS for procfs interfaces - if ! combined_mgs_mds ; then - mount_mgs_client - stack_trap umount_mgs_client EXIT - fi # # set number of permanent parameters # test_109_set_params $FSNAME - combined_mgs_mds || umount_mgs_client umount_client $MOUNT || error "umount_client failed" stop_ost || error "stop_ost failed" stop_mds || error "stop_mds failed" @@ -8094,7 +8056,6 @@ test_109b() error "failed to clear client config" setup_noconfig - combined_mgs_mds || mount_mgs_client # # check that configurations are intact # @@ -8105,7 +8066,6 @@ test_109b() # destroy_test_pools || error "destroy test pools failed" - combined_mgs_mds || umount_mgs_client cleanup } run_test 109b "test lctl clear_conf one config" diff --git a/lustre/tests/ost-pools.sh b/lustre/tests/ost-pools.sh index b77c639..bdfe65e 100755 --- a/lustre/tests/ost-pools.sh +++ b/lustre/tests/ost-pools.sh @@ -415,10 +415,11 @@ test_2e() { create_pool_nofail $POOL - TGT="$FSNAME-OST0000_UUID " + TGT="$FSNAME-OST0000_UUID" do_facet mgs 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" + wait_update_facet $SINGLEMDS \ + "lctl pool_list $FSNAME.$POOL | sed '1d'" "$TGT" || + error "Add $TGT to $FSNAME.$POOL failed" RESULT=$(do_facet mgs \ "LOCALE=C $LCTL pool_add $FSNAME.$POOL $TGT 2>&1") RC=$? diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index 69cda14..d588042 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -3110,10 +3110,6 @@ test_85b() { #bug 16774 lctl set_param -n ldlm.cancel_unused_locks_before_replay "1" - if ! combined_mgs_mds ; then - mount_mgs_client - fi - $LFS setstripe -c 1 -i 0 $DIR/$tdir for i in $(seq 100); do @@ -3141,10 +3137,6 @@ test_85b() { #bug 16774 -n ldlm.namespaces.*OST0000*$addr.lock_unused_count) echo "after recovery: unused locks count = $count2" - if ! combined_mgs_mds ; then - umount_mgs_client - fi - if [ $count2 -ge $count ]; then error "unused locks are not canceled" fi diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh old mode 100755 new mode 100644 index 46ae2a1..fe7c46d --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -2458,10 +2458,6 @@ test_27D() { local ost_list=$(seq $first_ost $ost_step $last_ost) local ost_range="$first_ost $last_ost $ost_step" - if ! combined_mgs_mds ; then - mount_mgs_client - fi - test_mkdir $DIR/$tdir pool_add $POOL || error "pool_add failed" pool_add_targets $POOL $ost_range || error "pool_add_targets failed" @@ -2481,10 +2477,6 @@ test_27D() { error "llapi_layout_test failed" destroy_test_pools || error "destroy test pools failed" - - if ! combined_mgs_mds ; then - umount_mgs_client - fi } run_test 27D "validate llapi_layout API" @@ -2815,11 +2807,6 @@ test_27L() { local POOL=${POOL:-$TESTNAME} - if ! combined_mgs_mds ; then - mount_mgs_client - trap umount_mgs_client EXIT - fi - pool_add $POOL || error "pool_add failed" lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" || @@ -2964,6 +2951,16 @@ test_27M() { } run_test 27M "test O_APPEND striping" +test_27N() { + combined_mgs_mds && skip "needs separate MGS/MDT" + + pool_add $TESTNAME || error "pool_add failed" + do_facet mgs "$LCTL pool_list $FSNAME" | + grep -Fx "${FSNAME}.${TESTNAME}" || + error "lctl pool_list on MGS failed" +} +run_test 27N "lctl pool_list on separate MGS gives correct pool name" + # createtest also checks that device nodes are created and # then visible correctly (#2091) test_28() { # bug 2091 @@ -15113,10 +15110,6 @@ test_200() { local subdir=$test_path/subdir local rc=0 - if ! combined_mgs_mds ; then - mount_mgs_client - fi - while : ; do # former test_200a test_200b pool_add $POOL || { rc=$? ; break; } @@ -15150,9 +15143,6 @@ test_200() { destroy_test_pools - if ! combined_mgs_mds ; then - umount_mgs_client - fi return $rc } run_test 200 "OST pools" @@ -15834,10 +15824,6 @@ test_220() { #LU-325 $LFS df -i - if ! combined_mgs_mds ; then - mount_mgs_client - fi - do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1 #define OBD_FAIL_OST_ENOINO 0x229 do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229 @@ -15874,10 +15860,6 @@ test_220() { #LU-325 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed" echo "unlink $MDSOBJS files @$next_id..." unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed" - - if ! combined_mgs_mds ; then - umount_mgs_client - fi } run_test 220 "preallocated MDS objects still used if ENOSPC from OST" @@ -17558,9 +17540,6 @@ test_253() { wait_delete_completed mkdir $DIR/$tdir - if ! combined_mgs_mds ; then - mount_mgs_client - fi pool_add $TESTNAME || error "Pool creation failed" pool_add_targets $TESTNAME 0 || error "Pool add targets failed" @@ -17606,10 +17585,6 @@ test_253() { if (( oa_status != 0 )); then error "Object allocation still disable after rm" fi - - if ! combined_mgs_mds ; then - umount_mgs_client - fi } run_test 253 "Check object allocation limit" @@ -20532,9 +20507,6 @@ test_406() { local def_stripe_size=$($LFS getstripe -S $MOUNT) local test_pool=$TESTNAME - if ! combined_mgs_mds ; then - mount_mgs_client - fi pool_add $test_pool || error "pool_add failed" pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 || error "pool_add_targets failed" @@ -20587,10 +20559,6 @@ test_406() { local f=$DIR/$tdir/$tfile pool_remove_all_targets $test_pool $f pool_remove $test_pool $f - - if ! combined_mgs_mds ; then - umount_mgs_client - fi } run_test 406 "DNE support fs default striping" diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 9b78323..17274af 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -2320,19 +2320,6 @@ zconf_umount() { fi } -# Mount the file system on the MGS -mount_mgs_client() { - do_facet mgs "mkdir -p $MOUNT" - zconf_mount $mgs_HOST $MOUNT $MOUNT_OPTS || - error "unable to mount $MOUNT on MGS" -} - -# Unmount the file system on the MGS -umount_mgs_client() { - zconf_umount $mgs_HOST $MOUNT - do_facet mgs "rm -rf $MOUNT" -} - # nodes is comma list sanity_mount_check_nodes () { local nodes=$1 diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index e82bdf7..123a5f9 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -3216,6 +3216,37 @@ static long llog_last_index(char *logname) return rc; } +static char *get_llog_event_name(__u32 cmd) +{ + struct lcfg_type_data *data; + + data = lcfg_cmd2data(cmd); + if (data) + return data->ltd_name; + return NULL; +} + +static char *get_event_filter(__u32 cmd) +{ + char *event_name; + char *filter = NULL; + int len; + + event_name = get_llog_event_name(cmd); + if (event_name) { + /* 9 bytes for "event: , " */ + len = 9 + strlen(event_name); + filter = malloc(len + 1); + if (!filter) + return NULL; + memset(filter, 0, len + 1); + snprintf(filter, len, "event: %s, ", event_name); + return filter; + } + + return NULL; +} + /** * Callback to search ostname in llog * - { index: 23, event: attach, device: lustre-OST0000-osc, type: osc, @@ -3236,19 +3267,30 @@ static int llog_search_ost_cb(const char *record, void *data) { char *ostname = data; char ost_filter[MAX_STRING_SIZE] = {'\0'}; + char *add_osc, *del_osc, *setup, *cleanup; + + add_osc = get_event_filter(LCFG_LOV_ADD_OBD); + del_osc = get_event_filter(LCFG_LOV_DEL_OBD); + setup = get_event_filter(LCFG_SETUP); + cleanup = get_event_filter(LCFG_CLEANUP); + if (!add_osc || !del_osc || !setup || !cleanup) + return -ENOMEM; if (ostname && ostname[0]) snprintf(ost_filter, sizeof(ost_filter), " %s,", ostname); if (strstr(record, ost_filter)) { - if (strstr(record, "event: add_osc, ") || - strstr(record, "event: setup, ")) + if (strstr(record, add_osc) || strstr(record, setup)) return 1; - if (strstr(record, "event: del_osc, ") || - strstr(record, "event: cleanup, ")) + if (strstr(record, del_osc) || strstr(record, cleanup)) return -ENOENT; } + free(add_osc); + free(del_osc); + free(setup); + free(cleanup); + return 0; } @@ -3308,8 +3350,18 @@ static int llog_search_pool_cb(const char *record, void *data) { struct llog_pool_data *lpd = data; char pool_filter[MAX_STRING_SIZE] = ""; + char *new_pool, *del_pool, *add_pool, *rem_pool; char *found = NULL; - int fs_pool_len = 0; + int fs_pool_len = 0, rc = 0; + + new_pool = get_event_filter(LCFG_POOL_NEW); + del_pool = get_event_filter(LCFG_POOL_DEL); + add_pool = get_event_filter(LCFG_POOL_ADD); + rem_pool = get_event_filter(LCFG_POOL_REM); + if (!new_pool || !del_pool || !add_pool || !rem_pool) { + rc = -ENOMEM; + goto out; + } fs_pool_len = 16 + strlen(lpd->lpd_fsname) + strlen(lpd->lpd_poolname); snprintf(pool_filter, fs_pool_len + 1, "fsname: %s, pool: %s", @@ -3319,37 +3371,50 @@ static int llog_search_pool_cb(const char *record, void *data) found = strstr(record, pool_filter); if (found && (found[fs_pool_len] == ' ' || found[fs_pool_len] == ',')) { - if (strstr(record, "event: new_pool,")) { + if (strstr(record, new_pool)) { lpd->lpd_pool_exists = true; - return 1; + rc = 1; + goto out; } - if (strstr(record, "event: del_pool,")) { + if (strstr(record, del_pool)) { lpd->lpd_pool_exists = false; - return -ENOENT; + rc = -ENOENT; + goto out; } if (lpd->lpd_cmd_type == LCFG_POOL_NEW || lpd->lpd_cmd_type == LCFG_POOL_DEL) { - if (strstr(record, "event: add_pool,")) + if (strstr(record, add_pool)) lpd->lpd_ost_num++; - if (strstr(record, "event: remove_pool,")) + if (strstr(record, rem_pool)) lpd->lpd_ost_num--; } else if (lpd->lpd_ostname && lpd->lpd_ostname[0]) { if (strstr(record, lpd->lpd_ostname)) { lpd->lpd_pool_exists = true; - if (strstr(record, "event: add_pool,")) { + if (strstr(record, add_pool)) { lpd->lpd_ost_num = 1; - return 1; + rc = 1; + goto out; } - if (strstr(record, "event: remove_pool,")) { + if (strstr(record, rem_pool)) { lpd->lpd_ost_num = 0; - return -ENOENT; + rc = -ENOENT; + goto out; } } } } +out: + if (new_pool) + free(new_pool); + if (del_pool) + free(del_pool); + if (add_pool) + free(add_pool); + if (rem_pool) + free(rem_pool); - return 0; + return rc; } /* Search pool and its ost in llog @@ -4546,15 +4611,192 @@ err: return 0; } -static int extract_fsname_poolname(const char *arg, char *fsname, +struct llog_pool_name { + char lpn_name[UUID_MAX]; + struct list_head lpn_list; +}; + +struct llog_pool_list_data { + char lpld_fsname[LUSTRE_MAXFSNAME + 1]; + char lpld_poolname[LOV_MAXPOOLNAME + 1]; + bool lpld_exists; + struct list_head lpld_list_head; +}; + +/** + * Callback to list pool information in llog + * - { index: 74, event: new_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * - { index: 77, event: add_pool, device: tfs-clilov, fsname: tfs, pool: tmp, + * ost: tfs-OST0000_UUID } + * - { index: 224, event: remove_pool, device: tfs-clilov, fsname: tfs, + * pool: tmp, ost: tfs-OST0003_UUID } + * - { index: 227, event: del_pool, device: tfs-clilov, fsname: tfs, pool: tmp } + * + * \param record[in] pointer to llog record + * \param data[in] pointer to struct llog_pool_list_data + * + * \retval 0 on success + * <0 on error + */ +static int llog_poollist_cb(const char *record, void *data) +{ + struct llog_pool_list_data *lpld = data; + char pool_filter[MAX_STRING_SIZE] = ""; + char *new_record, *del_record, *del_pool, *found; + char type[10] = ""; + int filter_len, rc = 0; + + filter_len = snprintf(pool_filter, sizeof(pool_filter), " fsname: %s,", + lpld->lpld_fsname); + if (lpld->lpld_poolname[0] == '\0') { + new_record = get_event_filter(LCFG_POOL_NEW); + del_record = get_event_filter(LCFG_POOL_DEL); + strncpy(type, " pool: ", sizeof(type)); + } else { + filter_len += snprintf(pool_filter + filter_len, + sizeof(pool_filter) - filter_len, + " pool: %s", lpld->lpld_poolname); + new_record = get_event_filter(LCFG_POOL_ADD); + del_record = get_event_filter(LCFG_POOL_REM); + strncpy(type, " ost: ", sizeof(type)); + } + del_pool = get_event_filter(LCFG_POOL_DEL); + + if (!new_record || !del_record || !del_pool) { + rc = -ENOMEM; + goto out; + } + + found = strstr(record, pool_filter); + if (found && + (found[filter_len] == ' ' || found[filter_len] == ',')) { + struct llog_pool_name *tmp = NULL; + struct list_head *head = &lpld->lpld_list_head; + char *name; + int name_len, type_len = strlen(type); + + lpld->lpld_exists = true; + if (strstr(record, new_record)) { + name = strstr(record, type); + /* 2 bytes for " }" */ + name_len = strlen(name) - type_len - 2; + if (name_len <= 0 || name_len > sizeof(tmp->lpn_name)) + return -EINVAL; + tmp = malloc(sizeof(struct llog_pool_name)); + if (tmp == NULL) { + rc = -ENOMEM; + goto out; + } + memset(tmp, 0, sizeof(struct llog_pool_name)); + strncpy(tmp->lpn_name, name + type_len, name_len); + list_add_tail(&tmp->lpn_list, &lpld->lpld_list_head); + } else if (strstr(record, del_record)) { + name = strstr(record, type); + name_len = strlen(name) - type_len - 2; + list_for_each_entry(tmp, head, lpn_list) { + if (strncmp(tmp->lpn_name, name + type_len, + name_len) == 0 && + tmp->lpn_name[name_len] == '\0') { + list_del(&tmp->lpn_list); + free(tmp); + break; + } + } + } + /* verify if the specified pool still exists */ + if (lpld->lpld_poolname[0] && strstr(record, del_pool)) + lpld->lpld_exists = false; + } +out: + if (new_record) + free(new_record); + if (del_record) + free(del_record); + if (del_pool) + free(del_pool); + + return rc; +} + +/** + * List pool information by config log + * + * \param fsname[in] pointer to filesystem name + * \param poolname[in] pointer to pool name + * + * \retval 0 on success + * < 0 on error + */ +int llog_poollist(char *fsname, char *poolname) +{ + char logname[MAX_OBD_NAME] = {'\0'}; + struct llog_pool_list_data lpld; + struct llog_pool_name *tmp; + struct list_head *head; + int rc = 0; + + if (fsname && fsname[0] == '\0') + fsname = NULL; + if (!fsname) + return -EINVAL; + + memset(&lpld, 0, sizeof(lpld)); + INIT_LIST_HEAD(&lpld.lpld_list_head); + lpld.lpld_exists = false; + strncpy(lpld.lpld_fsname, fsname, sizeof(lpld.lpld_fsname) - 1); + if (poolname && poolname[0]) + strncpy(lpld.lpld_poolname, poolname, + sizeof(lpld.lpld_poolname) - 1); + snprintf(logname, sizeof(logname), "%s-client", fsname); + rc = jt_llog_print_iter(logname, 0, -1, llog_poollist_cb, &lpld, false); + + if (poolname && poolname[0]) + printf("Pool: %s.%s\n", fsname, poolname); + else + printf("Pools from %s:\n", fsname); + + head = &lpld.lpld_list_head; + if (poolname && poolname[0] && !lpld.lpld_exists && list_empty(head)) + return -ENOENT; + + list_for_each_entry(tmp, head, lpn_list) { + if (poolname && poolname[0]) + printf("%s\n", tmp->lpn_name); + else + printf("%s.%s\n", fsname, tmp->lpn_name); + list_del(&tmp->lpn_list); + free(tmp); + } + + return rc; +} + +static bool get_pools_path(char *fsname) +{ + glob_t path; + int rc; + + rc = cfs_get_param_paths(&path, "lov/%s-*/pools", fsname); + if (!rc) + cfs_free_param_data(&path); + + return (rc == 0); +} + +static int extract_fsname_poolname(char **argv, char *fsname, char *poolname) { + char *cmd = argv[0], *param = argv[1]; char *ptr; int rc; - snprintf(fsname, PATH_MAX + 1, "%s", arg); + snprintf(fsname, PATH_MAX + 1, "%s", param); ptr = strchr(fsname, '.'); if (ptr == NULL) { + if (strcmp(cmd, "pool_list") == 0) { + poolname = NULL; + goto out; + } fprintf(stderr, ". is missing in %s\n", fsname); rc = -EINVAL; goto err; @@ -4582,63 +4824,71 @@ static int extract_fsname_poolname(const char *arg, char *fsname, fprintf(stderr, "poolname cannot be 'none'\n"); return -EINVAL; } +out: return 0; err: - fprintf(stderr, "argument %s must be .\n", arg); + fprintf(stderr, "argument %s must be .\n", param); return rc; } int jt_pool_cmd(int argc, char **argv) { - enum lcfg_command_type cmd; - char fsname[PATH_MAX + 1]; - char poolname[LOV_MAXPOOLNAME + 1]; - char *ostnames_buf = NULL; - int i, rc; - int *array = NULL, array_sz; - struct { - int rc; - char *ostname; - } *cmds = NULL; - - switch (argc) { - case 0: - case 1: return CMD_HELP; - case 2: { - if (strcmp("pool_new", argv[0]) == 0) - cmd = LCFG_POOL_NEW; - else if (strcmp("pool_destroy", argv[0]) == 0) - cmd = LCFG_POOL_DEL; - else if (strcmp("pool_list", argv[0]) == 0) - return llapi_poollist(argv[1]); - else return CMD_HELP; - - rc = extract_fsname_poolname(argv[1], fsname, poolname); - if (rc) - break; + enum lcfg_command_type cmd; + char fsname[PATH_MAX + 1]; + char poolname[LOV_MAXPOOLNAME + 1]; + char *ostnames_buf = NULL; + int i, rc; + int *array = NULL, array_sz; + struct { + int rc; + char *ostname; + } *cmds = NULL; + + switch (argc) { + case 0: + case 1: return CMD_HELP; + case 2: { + rc = extract_fsname_poolname(argv, fsname, poolname); + if (rc) + break; - rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); - if (rc) - break; + if (strcmp("pool_new", argv[0]) == 0) { + cmd = LCFG_POOL_NEW; + } else if (strcmp("pool_destroy", argv[0]) == 0) { + cmd = LCFG_POOL_DEL; + } else if (strcmp("pool_list", argv[0]) == 0) { + if (get_pools_path(fsname)) + return llapi_poollist(argv[1]); + if (get_mgs_device() > 0) + return llog_poollist(fsname, poolname); + fprintf(stderr, "Cannot run pool_list command " + "since there is no local MGS/MDT or client\n"); + return CMD_HELP; + } else { + return CMD_HELP; + } - check_pool_cmd_result(cmd, fsname, poolname, NULL); - break; - } - default: { - char format[2*MAX_OBD_NAME]; + rc = pool_cmd(cmd, argv[0], argv[1], fsname, poolname, NULL); + if (rc) + break; - if (strcmp("pool_remove", argv[0]) == 0) { - cmd = LCFG_POOL_REM; - } else if (strcmp("pool_add", argv[0]) == 0) { - cmd = LCFG_POOL_ADD; - } else { - return CMD_HELP; - } + check_pool_cmd_result(cmd, fsname, poolname, NULL); + break; + } + default: { + char format[2 * MAX_OBD_NAME]; - rc = extract_fsname_poolname(argv[1], fsname, poolname); - if (rc) - break; + if (strcmp("pool_remove", argv[0]) == 0) + cmd = LCFG_POOL_REM; + else if (strcmp("pool_add", argv[0]) == 0) + cmd = LCFG_POOL_ADD; + else + return CMD_HELP; + + rc = extract_fsname_poolname(argv, fsname, poolname); + if (rc) + break; for (i = 2; i < argc; i++) { int j; -- 1.8.3.1