lustre_createcsv.in
来自「lustre 1.6.5 source code」· IN 代码 · 共 2,102 行 · 第 1/4 页
IN
2,102 行
#!/bin/bash## lustre_createcsv - generate a csv file from a running lustre cluster## This script is used to collect lustre target informations, linux MD/LVM device# informations and HA software configurations in a lustre cluster to generate a# csv file. In reverse, the csv file could be parsed by lustre_config to # configure multiple lustre servers in parallel.## This script should be run on the MGS node.################################################################################## Usageusage() { cat >&2 <<EOFUsage: `basename $0` [-t HAtype] [-d] [-h] [-v] [-f csv_filename] This script is used to collect lustre target informations, linux MD/LVM device informations and HA software configurations from a running lustre cluster to generate a csv file. It should be run on the MGS node. -t HAtype collect High-Availability software configurations The argument following -t is used to indicate the High- Availability software type. The HA software types which are currently supported are: hbv1 (Heartbeat version 1) and hbv2 (Heartbeat version 2). -d collect linux MD/LVM device informations -h help -v verbose mode -f csv_filename designate a name for the csv file Default is lustre_config.csv.EOF exit 1}# Get the library of functions. @scriptlibdir@/lc_common#**************************** Global variables ****************************## csv fileLUSTRE_CSV_FILE=${LUSTRE_CSV_FILE:-"lustre_config.csv"}# Lustre proc filesLUSTRE_PROC=${LUSTRE_PROC:-"/proc/fs/lustre"}LUSTRE_PROC_DEVICES=${LUSTRE_PROC}/devicesLNET_PROC=${LNET_PROC:-"/proc/sys/lnet"}LNET_PROC_PEERS=${LNET_PROC}/peers# Default network module optionsDEFAULT_MOD_OPTS=${DEFAULT_MOD_OPTS:-"options lnet networks=tcp"}# Lustre target obd device typesMGS_TYPE=${MGS_TYPE:-"mgs"}MDT_TYPE=${MDT_TYPE:-"mds"}OST_TYPE=${OST_TYPE:-"obdfilter"}# The obd name of MGS target serverMGS_SVNAME=${MGS_SVNAME:-"MGS"} # Hostnames of the lustre cluster nodesdeclare -a HOST_NAMES MGS_HOSTNAME=${MGS_HOSTNAME:-"`hostname`"} # Hostname of the MGS node# Configs of lustre targets in one cluster nodedeclare -a TARGET_CONFIGS declare -a TARGET_SVNAMES TARGET_DEVNAMES TARGET_DEVSIZES TARGET_MNTPNTSdeclare -a TARGET_DEVTYPES TARGET_FSNAMES TARGET_MGSNIDS TARGET_INDEXESdeclare -a TARGET_FMTOPTS TARGET_MKFSOPTS TARGET_MNTOPTS TARGET_FAILNIDSdeclare -a HA_CONFIGSdeclare -a ALL_TARGET_SVNAMES # All the target services in the clusterdeclare -a FAILOVER_FMTOPTS # "--noformat" # Informations of linux MD/LVM devices in one cluster nodedeclare -a MD_NAME MD_LEVEL MD_DEVS # MDdeclare -a VG_NAME VG_PVNAMES # VGdeclare -a LV_NAME LV_SIZE LV_VGNAME # LV# Lustre target service typeslet "LDD_F_SV_TYPE_MDT = 0x0001"let "LDD_F_SV_TYPE_OST = 0x0002"let "LDD_F_SV_TYPE_MGS = 0x0004"# Permanent mount options for ext3 or ldiskfsALWAYS_MNTOPTS=${ALWAYS_MNTOPTS:-"errors=remount-ro"}MDT_MGS_ALWAYS_MNTOPTS=${MDT_MGS_ALWAYS_MNTOPTS:-",iopen_nopriv,user_xattr"}OST_ALWAYS_MNTOPTS=${OST_ALWAYS_MNTOPTS:-",asyncdel"}OST_DEFAULT_MNTOPTS=${OST_DEFAULT_MNTOPTS:-",extents,mballoc"}# User-settable parameter keysPARAM_MGSNODE=${PARAM_MGSNODE:-"mgsnode="}PARAM_FAILNODE=${PARAM_FAILNODE:-"failover.node="}# Block sizeL_BLOCK_SIZE=4096# Option string of mkfs.lustreOPTSTR_STRIPE_COUNT=${OPTSTR_STRIPE_COUNT:-"--stripe-count-hint="}# Get and check the positional parametersVERBOSE_OUTPUT=falseGET_MDLVM_INFO=falsewhile getopts "t:dhvf:" OPTION; do case $OPTION in t) HATYPE_OPT=$OPTARG if [ "${HATYPE_OPT}" != "${HBVER_HBV1}" ] \ && [ "${HATYPE_OPT}" != "${HBVER_HBV2}" ] \ && [ "${HATYPE_OPT}" != "${HATYPE_CLUMGR}" ]; then echo >&2 "`basename $0`: Invalid HA software type" \ "- ${HATYPE_OPT}!" usage fi ;; d) GET_MDLVM_INFO=true;; h) usage;; v) VERBOSE_OUTPUT=true;; f) LUSTRE_CSV_FILE=$OPTARG;; ?) usage esacdone# Verify the local host is the MGS nodemgs_node() { if [ ! -e ${LUSTRE_PROC_DEVICES} ]; then echo >&2 "`basename $0`: error: ${LUSTRE_PROC_DEVICES} does" \ "not exist. Lustre kernel modules may not be loaded!" return 1 fi if [ -z "`cat ${LUSTRE_PROC_DEVICES}`" ]; then echo >&2 "`basename $0`: error: ${LUSTRE_PROC_DEVICES} is" \ "empty. Lustre services may not be started!" return 1 fi if [ -z "`grep ${MGS_TYPE} ${LUSTRE_PROC_DEVICES}`" ]; then echo >&2 "`basename $0`: error: This node is not a MGS node." \ "The script should be run on the MGS node!" return 1 fi return 0}# get_hostnames# Get lustre cluster node namesget_hostnames() { declare -a HOST_NIDS declare -i idx # Index of HOST_NIDS array declare -i i # Index of HOST_NAMES array if ! mgs_node; then return 1 fi if [ ! -e ${LNET_PROC_PEERS} ]; then echo >&2 "`basename $0`: error: ${LNET_PROC_PEERS} does not" \ "exist. LNET kernel modules may not be loaded" \ "or LNET network may not be up!" return 1 fi HOST_NAMES[0]=${MGS_HOSTNAME} # MGS node HOST_NIDS[0]=${HOST_NAMES[0]} # Get the nids of the nodes which have contacted MGS idx=1 for nid in `cat ${LNET_PROC_PEERS} | awk '{print $1}'`; do if [ "${nid}" = "nid" ]; then continue fi HOST_NIDS[idx]=${nid} let "idx += 1" done if [ ${idx} -eq 1 ]; then verbose_output "Only one node running in the lustre cluster." \ "It's ${HOST_NAMES[0]}." return 0 fi # Get the hostnames of the nodes for ((idx = 1, i = 1; idx < ${#HOST_NIDS[@]}; idx++, i++)); do if [ -z "${HOST_NIDS[idx]}" ]; then echo >&2 "`basename $0`: get_hostnames() error:" \ "Invalid nid - \"${HOST_NIDS[idx]}\"!" return 1 fi HOST_NAMES[i]=$(nid2hostname ${HOST_NIDS[idx]}) if [ $? -ne 0 ]; then echo >&2 "${HOST_NAMES[i]}" return 1 fi if [ "${HOST_NAMES[i]}" = "${HOST_NAMES[0]}" ]; then unset HOST_NAMES[i] let "i -= 1" fi done return 0}#********************** Linux MD/LVM device informations **********************## get_md_configs hostname# Get all the active MD device informations from the node @hostnameget_md_configs() { declare -i i=0 declare -i j=0 local host_name=$1 local ret_line line first_item # Initialize the arrays unset MD_NAME unset MD_LEVEL unset MD_DEVS # Execute remote command to the node ${host_name} and get all the # active MD device informations. while read -r ret_line; do if is_pdsh; then set -- ${ret_line} shift line="$*" else line="${ret_line}" fi first_item=`echo "${line}" | awk '{print $1}'` # Get the MD device name and raid level if [ "${first_item}" = "ARRAY" ]; then MD_NAME[i]=`echo "${line}" | awk '{print $2}'` MD_LEVEL[i]=`echo "${line}" | awk '{print $3}' | sed -e 's/level=//'` let "j = i" let "i += 1" fi # Get the MD component devices if [ "${first_item}" != "${first_item#devices=}" ]; then MD_DEVS[j]=`echo "${line}" | sed -e 's/devices=//' -e 's/,/ /g'` fi done < <(${REMOTE} ${host_name} "${MDADM} --detail --scan --verbose") if [ $i -eq 0 ]; then verbose_output "There are no active MD devices" \ "in the host ${host_name}!" fi return 0}# get_pv_configs hostname# Get all the LVM PV informations from the node @hostnameget_pv_configs() { PV_NAMES= local host_name=$1 local cmd ret_str # Execute remote command to get all the PV informations. cmd="${EXPORT_PATH} pvdisplay -c | awk -F: '{print \$1}' | xargs" ret_str=`${REMOTE} ${host_name} "${cmd}" 2>&1` if [ $? -ne 0 ]; then if [ -n "${ret_str}" ]; then echo >&2 "`basename $0`: get_pv_configs() error:" \ "remote command to ${host_name} error: ${ret_str}" else remote_error "get_pv_configs" ${host_name} fi return 1 fi PV_NAMES=`echo "${ret_str}" | sed -e 's/^'${host_name}':[[:space:]]//'` if [ -z "${PV_NAMES}" ]; then verbose_output "There are no PVs in the host ${host_name}!" return 0 fi return 0}# get_vg_pvnames hostname vgname# Get the PVs contained in @vgname from the node @hostnameget_vg_pvnames() { local host_name=$1 local vg_name=$2 local pv_names= local cmd ret_str # Execute remote command to get the PV names. cmd="${EXPORT_PATH} vgdisplay -v ${vg_name} 2>/dev/null\ | grep \"PV Name\" | awk '{print \$3}' | xargs" ret_str=`${REMOTE} ${host_name} "${cmd}" 2>&1` if [ $? -ne 0 ]; then if [ -n "${ret_str}" ]; then echo "`basename $0`: get_vg_pvnames() error:" \ "remote command to ${host_name} error: ${ret_str}" else remote_error "get_vg_pvnames" ${host_name} fi return 1 fi pv_names=`echo "${ret_str}" | sed -e 's/^'${host_name}':[[:space:]]//'` if [ -z "${pv_names}" ]; then echo "`basename $0`: get_vg_pvnames() error:" \ "There are no PVs in VG ${vg_name} in the host ${host_name}!"\ "Or VG ${vg_name} does not exist." return 1 fi echo "${pv_names}" return 0}# get_vg_configs hostname# Get all the LVM VG informations from the node @hostnameget_vg_configs() { declare -i i=0 local host_name=$1 local cmd ret_str local vg_name # Initialize the arrays unset VG_NAME unset VG_PVNAMES # Execute remote command to get all the VG names. cmd="${EXPORT_PATH} vgdisplay \ | grep \"VG Name\" | awk '{print \$3}' | xargs" ret_str=`${REMOTE} ${host_name} "${cmd}" 2>&1` if [ $? -ne 0 ]; then if [ -n "${ret_str}" ]; then echo >&2 "`basename $0`: get_vg_configs() error:" \ "remote command to ${host_name} error: ${ret_str}" else remote_error "get_vg_configs" ${host_name} fi return 1 fi if [ -z "${ret_str}" ] \ || [ "${ret_str}" != "${ret_str#*No volume groups found*}" ]; then verbose_output "There are no VGs in the host ${host_name}!" return 0 fi # Get all the VG informations for vg_name in `echo "${ret_str}" | sed -e 's/^'${host_name}'://'`; do VG_NAME[i]=${vg_name} VG_PVNAMES[i]=$(get_vg_pvnames ${host_name} ${VG_NAME[i]}) if [ $? -ne 0 ]; then echo >&2 "${VG_PVNAMES[i]}" return 1 fi let "i += 1" done return 0}# get_lv_configs hostname# Get all the LVM LV informations from the node @hostnameget_lv_configs() { declare -i i=0 local host_name=$1 local ret_line line # Initialize the arrays unset LV_NAME unset LV_SIZE unset LV_VGNAME # Execute remote command to get all the LV informations. while read -r ret_line; do if is_pdsh; then set -- ${ret_line} shift line="$*" else line="${ret_line}" fi [ "${line}" != "${line#*volume group*}" ] && break LV_NAME[i]=`echo "${line}" | awk -F: '{print $1}' | sed -e 's/.*\///g'` LV_VGNAME[i]=`echo "${line}" | awk -F: '{print $2}'` LV_SIZE[i]=`echo "${line}" | awk -F: '{print $7}' | sed -e 's/.*/&K/'` let "i += 1" done < <(${REMOTE} ${host_name} "${EXPORT_PATH} lvdisplay -c") if [ $i -eq 0 ]; then verbose_output "There are no LVs in the host ${host_name}" fi return 0}#*************************** Network module options ***************************## last_is_backslash line# Check whether the last effective letter of @line is a backslashlast_is_backslash() { local line="$*" declare -i i declare -i length local letter last_letter length=${#line} for ((i = ${length}-1; i >= 0; i--)); do letter=${line:${i}:1} [ "x${letter}" != "x " -a "x${letter}" != "x " -a -n "${letter}" ]\ && last_letter=${letter} && break done [ "x${last_letter}" = "x\\" ] && return 0 return 1}# get_module_opts hostname# Get the network module options from the node @hostname get_module_opts() { local host_name=$1 local ret_str local MODULE_CONF KERNEL_VER local ret_line line find_options local continue_flag MODULE_OPTS=${DEFAULT_MOD_OPTS} # Execute remote command to get the kernel version ret_str=`${REMOTE} ${host_name} "uname -r" 2>&1` if [ $? -ne 0 -a -n "${ret_str}" ]; then echo >&2 "`basename $0`: get_module_opts() error:" \ "remote command error: ${ret_str}" return 1 fi remote_error "get_module_opts" ${host_name} "${ret_str}" && return 1 if is_pdsh; then KERNEL_VER=`echo ${ret_str} | awk '{print $2}'` else KERNEL_VER=`echo ${ret_str} | awk '{print $1}'` fi # Get the module configuration file name if [ "${KERNEL_VER:0:3}" = "2.4" ]; then MODULE_CONF=/etc/modules.conf else MODULE_CONF=/etc/modprobe.conf fi # Execute remote command to get the lustre network module options continue_flag=false find_options=false while read -r ret_line; do if is_pdsh; then set -- ${ret_line} shift line="$*" else line="${ret_line}" fi # Get rid of the comment line [ -z "`echo \"${line}\"|egrep -v \"^#\"`" ] && continue if [ "${line}" != "${line#*options lnet*}" ]; then if ! ${find_options}; then find_options=true MODULE_OPTS=${line} else MODULE_OPTS=${MODULE_OPTS}$" \n "${line} fi last_is_backslash "${line}" && continue_flag=true \ || continue_flag=false continue fi if ${continue_flag}; then MODULE_OPTS=${MODULE_OPTS}$" \n "${line} ! last_is_backslash "${line}" && continue_flag=false fi done < <(${REMOTE} ${host_name} "cat ${MODULE_CONF}") if [ -z "${MODULE_OPTS}" ]; then MODULE_OPTS=${DEFAULT_MOD_OPTS} fi return 0}#************************ HA software configurations ************************## is_ha_target hostname target_devname# Check whether the target @target_devname was made to be high-availableis_ha_target() { local host_name=$1 local target_svname=$2 local res_file local ret_str case "${HATYPE_OPT}" in "${HBVER_HBV1}") res_file=${HA_RES};; "${HBVER_HBV2}") res_file=${HA_CIB};; "${HATYPE_CLUMGR}") res_file=${CLUMAN_CONFIG};; esac # Execute remote command to check the resource file ret_str=`${REMOTE} ${host_name} \ "grep ${target_svname} ${res_file}" 2>&1` if [ $? -ne 0 -a -n "${ret_str}" ]; then echo >&2 "`basename $0`: is_ha_target() error:" \ "remote command error: ${ret_str}" return 1 fi
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?