Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / utils / lwizard
diff --git a/lustre/utils/lwizard b/lustre/utils/lwizard
new file mode 100755 (executable)
index 0000000..4938f95
--- /dev/null
@@ -0,0 +1,398 @@
+#!/bin/sh
+# Copyright (C) 2003  Cluster File Systems, Inc.
+# Create a Lustre configuration file
+#
+# Usage: lwizard
+#
+# Jerrifer <jerrifer@clusterfs.com>
+# wangdi <wangdi@clusterfs.com>
+
+# fatal error to exit
+fatal()
+{
+    if [ "$#" -gt "1" ]; then
+       echo
+       echo "$2"
+       exit 1
+    fi
+
+    exit 1
+}
+
+#print usage and exit 
+usage()
+{
+    cat <<EOF
+Usage: ${0##*/} [OPTIONS]...
+
+${0##*/} asks the user questions about their cluster configuration,
+and writes an appropriate configuration file to config.xml.
+
+Options:
+    --batch=FILE
+       save lmc batch commands to FILE
+    -o, --file=FILE
+       write Lustre configuration to FILE (default: lwizard.xml)
+    -f, --force
+       force existing files to be overwritten
+    --help
+       to get this help
+    --stripe_size=SIZE
+       size (in KB) of each stripe on an OST (default: 64)
+    --stripe_count=COUNT
+       the number of OSTs files are striped to (default: 1)
+EOF
+
+    exit 0     
+}
+
+# check if $1 is a number
+check_number()
+{
+    local num=$(expr "$1" : "[0-9]*$")
+    if [ $num -gt "0" ]; then 
+       return 0 
+    fi
+
+    return 1
+}
+
+# parse options of this shell
+LMC_BATCH_FILE=
+RM_BATCH_FILE=1
+FORCE=0
+get_option()
+{
+    local long_options="batch:,file:,force:,help,stripe_size:,stripe_count:"
+    local options
+
+    options=$(getopt -o o:hf --long "$long_options" -- "$@")
+
+    if [ $? -ne 0 ] ; then
+       usage
+    fi
+    eval set -- "$options"
+
+    while true ; do
+       case "$1" in
+           --batch)
+               LMC_BATCH_FILE=$2
+               RM_BATCH_FILE=0
+               shift 2
+               ;;
+           -o | --file)
+               CONFIG_FILE=$2
+               shift 2
+               ;;
+           -f | --force)
+               FORCE=1
+               shift
+               ;;
+           --stripe_count)
+               STRIPE_CNT=$2
+               check_number $STRIPE_CNT || \
+                   fatal 1 "Stripe count should be a number."
+               shift 2
+               ;;
+           --stripe_size)
+               STRIPE_SIZE=$(($2 * 1024))
+               check_number $STRIPE_SIZE || \
+                   fatal 1 "Stripe size should be a number."
+               shift 2
+               ;;
+           -h | --help)
+               usage
+               ;;
+           --)
+               shift 1
+               break
+       esac
+    done 
+}
+
+# if $1 in $2
+in_list()
+{
+    local node
+
+    for node in $2 ; do
+       [ "$1" = "$node" ] && return 0
+       done
+       return 1
+    }
+
+# read device size from user and check devive size and convert device
+# size to *K
+
+get_device_size()
+{
+    local size 
+    local tail
+
+    read size 
+    if [ -z $size ]; then 
+       device_size="0"
+       return 0
+    fi 
+
+    device_size=$(echo $size | awk -F[a-z,A-Z] '{print $1; }')
+    [ -z $device_size ] && return 1
+    tail=$(echo $size | awk -F$device_size '{print $2; }')
+    [ -z $tail ] && return 0
+    case $tail in
+       k | K)
+           ;;
+        m | M)
+           (( device_size *= 1024 ))
+           ;;
+       t | T)
+           (( device_size *= (1024 * 1024) ))
+           ;;
+       *)
+           return 1
+           ;;
+       esac
+
+    return 0
+}
+
+# ask user some questions to add a device 
+add_device()
+{
+    local hostnames
+    local device
+    local device_size
+
+    echo "Creating $1 \"$1$2\"..."
+    if [ "$2" -gt "1" ]; then 
+       echo -n "Please enter the hostname(s) for $1$2, or just hit enter to finish: "
+    else
+       echo -n "Please enter the hostname(s) for $1$2: "
+    fi
+    read hostnames
+
+    if [ -z "$hostnames" ] ; then
+       return 1
+    fi
+
+    for hostname in $hostnames ; do
+       device=
+       while [ -z "$device" ] ; do
+           echo -n "Please enter the device or loop file name for $1$2 on ${hostname}: "
+           read device
+           echo -n "Please enter the device size or 0 to use entire device: "
+           while ! get_device_size ; do
+              echo -n "Please enter the device size or 0 to use entire device: "
+           done
+       done
+       newdev="$hostname:$device:$2:$1$2:$CURRENT_MDS:$CURRENT_LOV:$device_size"
+       DEVICE_LIST="$DEVICE_LIST $newdev"
+    done
+
+    return 0 
+}
+
+cur_mds_id=1
+
+# get mds information
+add_mds()
+{
+    CURRENT_LOV=
+    CURRENT_MDS=
+    add_device "mds" "$cur_mds_id" || return 1 
+    CURRENT_LOV="lov$cur_mds_id"
+    CURRENT_MDS="mds$cur_mds_id"
+
+    DEVICE_LIST="$DEVICE_LIST *:*:lov:$CURRENT_LOV:$CURRENT_MDS:*:"
+
+    (( cur_mds_id++ ))
+    return 0
+}
+
+cur_ost_id=1
+
+# ask user to add ost 
+add_ost()
+{
+    # We have to add one...
+    while ! add_device "ost" "$cur_ost_id" ; do
+       true
+    done
+
+    (( cur_ost_id++ ))
+
+    # ...and maybe more
+    while add_device "ost" "$cur_ost_id" ; do
+           (( cur_ost_id++ ))
+    done
+    return 0
+}
+
+cur_cli_id=1
+
+# ask user to add client to lustre
+add_client()
+{
+    echo -n "Please enter the clients' mountpoint (/mnt/lustre): "
+    read mtpt
+    [ -z "$mtpt" ] && mtpt="/mnt/lustre"
+    newdev="*:$mtpt:client:client:$CURRENT_MDS:$CURRENT_LOV"
+    DEVICE_LIST="$DEVICE_LIST $newdev"
+    (( cur_cli_id++ ))
+    return 0
+}
+
+# save node config into config file 
+add_node()
+{
+    local node=$1
+    local nettype=$DEFAULT_NETTYPE
+
+    in_list "$node" "$NODE_LIST" && return 0 
+    NODE_LIST="$NODE_LIST $node" 
+
+    run_lmc --add node --node "$node"
+    run_lmc --add net --node "$node" --nid "$node"  \
+       --nettype "$nettype"
+
+    return 0 
+} 
+
+# get hostname, device , device_id and device name 
+# from mds node 
+get_name_in_list()
+{
+    HOST_NAME=$(echo $1 | awk -F: '{ print $1 }')
+    DEVICE=$(echo $1 | awk -F: '{ print $2 }')
+    DEVICE_ID=$(echo $1 | awk -F: '{ print $3 }')
+    DEVICE_NAME=$(echo $1 | awk -F: '{ print $4 }')
+    DEVICE_MDS=$(echo $1 | awk -F: '{ print $5 }')
+    DEVICE_LOV=$(echo $1 | awk -F: '{ print $6 }')
+    DEVICE_SIZE=$(echo $1 | awk -F: '{ print $7 }')
+}
+
+# save command to file and do the command 
+run_lmc()
+{
+    echo "$@" >> "$LMC_BATCH_FILE"
+}
+
+# following user input to create xml config file 
+create_config()
+{
+    for device in $DEVICE_LIST ; do
+       get_name_in_list $device
+       echo -n " $DEVICE_NAME"
+       case $DEVICE_NAME in
+           mds*)
+               add_node "$HOST_NAME"
+               run_lmc --add mds \
+                   --node "$HOST_NAME" \
+                   --mds "$DEVICE_NAME" \
+                   --fstype "$DEFAULT_FSTYPE" \
+                   --dev "$DEVICE" \
+                   --size "$DEVICE_SIZE"
+               ;;
+           lov*)
+               run_lmc --add lov \
+                   --lov "$DEVICE_NAME" \
+                   --mds "$DEVICE_MDS" \
+                   --stripe_sz "$STRIPE_SIZE" \
+                   --stripe_cnt "$STRIPE_CNT" \
+                   --stripe_pattern "$STRIPE_PATTERN"
+               ;;
+           ost*)
+               add_node "$HOST_NAME"
+               run_lmc --add ost \
+                   --node "$HOST_NAME" \
+                   --lov "$DEVICE_LOV" \
+                   --fstype "$DEFAULT_FSTYPE" \
+                   --dev "$DEVICE" \
+                   --size "$DEVICE_SIZE"
+               ;;
+           client*)
+               add_node "$DEVICE_NAME"
+               run_lmc --add mtpt \
+                   --node "$DEVICE_NAME" \
+                   --mds "$DEVICE_MDS" \
+                   --lov "$DEVICE_LOV" \
+                   --path "$DEVICE"
+               ;;
+       esac
+    done
+    echo
+    return 0
+}
+
+maybe_clean()
+{
+    [ -f "$1" ] || return 0
+    if ! (( $FORCE )) ; then
+       echo -n "${0##*/}: overwrite existing $2 \"$1\"? "
+       read answer
+       if ! [ "${answer:0:1}" = "y" -o "${answer:0:1}" = "Y" ] ; then
+           echo "(${0##*/}: (Exiting.)"
+           exit 0
+       fi
+    fi
+    rm -f "$1"
+}
+
+# parse options 
+get_option "$@"
+
+# some default definitions
+LMC=${LMC:-"/usr/sbin/lmc"}
+
+CONFIG_FILE=${CONFIG_FILE:-"lwizard.xml"}
+
+# Remove exiting files.
+
+maybe_clean "$CONFIG_FILE" "Lustre configuration file"
+if [ "$LMC_BATCH_FILE" ] ; then
+    maybe_clean "$LMC_BATCH_FILE" "lmc batch file"
+else
+    LMC_BATCH_FILE=$(mktemp -q "/tmp/${CONFIG_FILE##*/}.XXXXXX")
+    [ $? -eq 0 ] || fatal 1 "Couldn't create temporary batch file."
+fi
+
+DEFAULT_FSTYPE=${DEFAULT_FSTYPE:-"ext3"}
+DEFAULT_NETTYPE=${DEFAULT_NETTYPE:-"tcp"}
+DEFAULT_MNTPT=${DEFAULT_MNTPT:-"/mnt/lustre"}
+
+STRIPE_SIZE=${STRIPE_SIZE:-$((1 * 1024 * 1024))}
+STRIPE_CNT=${STRIPE_CNT:-1}
+STRIPE_PATTERN=${STRIPE_PATTERN:-0}
+
+ANSWER="yes no"
+
+CURRENT_LOV=
+MDS_LIST=
+OST_LIST=
+CLIENT_LIST=
+
+# print program information
+cat <<EOF
+${0##*/} will help you create a Lustre configuration file.
+
+EOF
+while add_mds ; do
+    add_ost
+    add_client
+done
+
+create_config
+$LMC --batch "$LMC_BATCH_FILE" -o "$CONFIG_FILE"
+if [ $? -ne 0 ] ; then
+    fatal 1 "lmc returned an error; Please check above for more details."
+fi
+
+echo "The Lustre configuration has been written to $CONFIG_FILE."
+
+if (( $RM_BATCH_FILE )) ; then
+    rm -f "$LMC_BATCH_FILE"
+else
+    echo "The lmc batch file has been written to $LMC_BATCH_FILE."
+fi
+
+exit 0