NAS NetApp Data ONTAP gestion volumes

De Wiki de Romain RUDIGER
Aller à : navigation, rechercher

Commandes

Voir le status d'un snap

ssh nom_du_nas "vol status nom_du_volume"

Snapshot busy:

ssh nom_du_nas vol clone split start nom_du_volume

Désactivation quotas sur volume

ssh nom_du_nas vol options nom_du_volume fs_size_fixed off

Activation quotas sur volume

ssh nom_du_nas vol options nom_du_volume fs_size_fixed on

Voir la liste des snaps d'un volume

ssh nom_du_nas "snap list nom_du_volume"

Restaurer un snap en ligne de commande

ssh nom_du_nas "snap restore -t vol -s nom_du_snap"

Supprimer un snap

ssh nom_du_nas "snap delete nom_du_volume nom_du_snap"

Connaitre le status d'un qtree

ssh nom_du_nas "qtree status nom_du_volume"

Script de création automatique d'un volume

Il permet de créer, exporter et monter des volumes simples ou sous forme de qtree avec des quotas.

Ce script se base sur un fichier de configuration. Le nom de l’agrégat utilisé est en dur dans le script.

Script principal NAS_fs.sh :

#!/bin/bash
#
# This script can:
#  -Create a volume on an NetApp NAS
#  -Export a volume
#  -Mount a volume on a Linux/HPUX/SunOS
#
# 07/29/2009 - Romain RUDIGER - creation
# 11/25/2009 - Romain RUDIGER - add qtree support
# 12/09/2009 - Romain RUDIGER - check if the mount description already exist, if yes, it's updated

#Include common functions
Program_dir=$(dirname $0)
source $Program_dir/NAS_fs.env

###################################
# Global functions
###################################

function usage {
   echo "Usage: $0 <NAS_fs_list> [-create] [-export] [-mount] [-test]"
   echo "  -create_fs_list format: [%qtreevol%|%qtree%]<volume name>:<tete nas>:<volume data size (whitout snapshot space)>m/g/t:<snap reserve>:<dest server>:<mount path>:<user>:<group>"
   echo "     ->Required for -create:[%qtreevol%|%qtree%]<volume name>:<tete nas>:<volume data size (whitout snapshot space)>m/g/t:<snap reserve>::::"
   echo "     ->Required for -export:[%qtreevol%|%qtree%]<volume name>:<tete nas>:::<dest server>:::"
   echo "     ->Required for -mount:[%qtreevol%|%qtree%]<volume name>:<tete nas>:::<dest server>:<mount path>:<user>:<group>"
   echo "  -A ligne wich start with '#' is not processed"
   exit 1
}

function info {
   echo -e "\E[32mINFO\E[37m-\E[36m$NUMBER_OF_PROCESSED_FS\E[37m-\E[36m$VOL_NAME\E[37m-$1"
}

function test {
   echo -e "\E[35mTEST\E[37m-\E[36m$NUMBER_OF_PROCESSED_FS\E[37m-\E[36m$VOL_NAME\E[37m-$1"
}

function error {
   echo -e "\E[31mERROR\E[37m-\E[36m$NUMBER_OF_PROCESSED_FS\E[37m-\E[36m$VOL_NAME\E[37m-$1."
   NUMBER_OF_UNCREATED_FS=$NUMBER_OF_UNCREATED_FS+1
   FS_IN_ERROR="$FS_IN_ERROR \n  $NUMBER_OF_PROCESSED_FS-$VOL_NAME: $1."
}

###################################
# Test arguments
###################################
if [[ ! $# -ge 2 ]]; then
   usage
fi
if [[ ! -r $1 ]]; then
   echo "The create_fs_list argument must be a file with read right !"
   usage
fi
CREATE=
EXPORT=
MOUNT=
TEST=
for arg in $@; do
   if [[ "$arg" == "-help" ]]; then
      usage
   fi   
   if [[ "$arg" == "--help" ]]; then
      usage
   fi   
   if [[ "$arg" == "-create" ]]; then
      CREATE=true
   fi   
   if [[ "$arg" == "-export" ]]; then
      EXPORT=true
   fi   
   if [[ "$arg" == "-mount" ]]; then
      MOUNT=true
   fi   
   if [[ "$arg" == "-test" ]]; then
      echo -e "\E[31mWARNING\E[37m-The script is in TEST mode !"
      TEST=true
   fi   
done

###################################
# Global vars
###################################
CREATE_FS_LIST=$1
FS_IN_ERROR=
declare -i NUMBER_OF_PROCESSED_FS=0
declare -i NUMBER_OF_CREATED_FS=0
declare -i NUMBER_OF_UNCREATED_FS=0

###################################
# Main branch
###################################
function main {
   for database in $( cat $CREATE_FS_LIST | grep -vE ^#.*$ ); do
      NUMBER_OF_PROCESSED_FS=$NUMBER_OF_PROCESSED_FS+1
      
      get_and_check_args
      if [[ $? -ne 0 ]]; then
         info "A problem occured while get and check args in FS list."
         continue
      fi
         
      if [[ "$CREATE" == "true" ]]; then
         create
         if [[ $? -ne 0 ]]; then
            info "The creation process failed for this volume."
            continue
         fi
      fi

      if [[ "$EXPORT" == "true" ]]; then
         export
         if [[ $? -ne 0 ]]; then
            info "The export process failed for this volume."
            continue
         fi
      fi
      
      if [[ "$MOUNT" == "true" ]]; then
         mount
         if [[ $? -ne 0 ]]; then
            info "The mount process failed for this volume."
            continue
         fi
      fi
      
      # If it was a tree volume creation, we restore the EXPORT and MOUNT function state for the next FS.
      if [[ "$TREE_VOLUME" == "true" ]]; then
         EXPORT=$EXPORT_BAK
         MOUNT=$MOUNT_BAK
      fi

      NUMBER_OF_CREATED_FS=$NUMBER_OF_CREATED_FS+1
   done

   if [[ -n "$TEST" ]]; then
      echo -e "\E[31mWARNING\E[37m-The script is in TEST mode !"
   fi

   ###################################
   # Print stats and informations
   ###################################
   echo -e "\E[32mINFO\E[37m-Number of volume processed: $NUMBER_OF_PROCESSED_FS."
   echo -e "\E[32mINFO\E[37m-Number of volume created: $NUMBER_OF_CREATED_FS."
   echo -e "\E[32mINFO\E[37m-Number of volume in error: $NUMBER_OF_UNCREATED_FS."
   if [[ $NUMBER_OF_UNCREATED_FS -ne 0 ]]; then
      echo -e "ERROR-Some volume are in ERROR: $FS_IN_ERROR"
   fi
}
# end of main function

###################################
# Get and check arguments from the list file
###################################
function get_and_check_args {
   VOL_NAME=`echo $database | cut -d':' -f 1`
   TREE_VOLUME=
   TREE_NAME=
   TETE_NAS=`echo $database | cut -d':' -f 2`
   TETE_NAS_QUOTAS=

   # Is it a qtree volume to create ?
   check_regExp $VOL_NAME "^%qtreevol%"
   if [[ $? -eq 0 ]]; then
      # We don't export and mount a qtree volume, we mount only the future trees
      TREE_VOLUME=true
      EXPORT_BAK=$EXPORT
      MOUNT_BAK=$MOUNT
      EXPORT=
      MOUNT=
      VOL_NAME=$(echo "$VOL_NAME" | sed -re "s/^%qtreevol%//")
      info "This volume is for a qtree, so we don't export and/or mount it."
   fi
   # Is it a qtree to create ?
   check_regExp $VOL_NAME "^%qtree%"
   if [[ $? -eq 0 ]]; then
      VOL_NAME=$(echo "$VOL_NAME" | sed -re "s/^%qtree%//")
      check_regExp $VOL_NAME "^.+/.+$"
      if [[ $? -ne 0 ]]; then
         error "A volume name for a qtree must be: \"%qtree%vol_name/qtree_name\" not \"$VOL_NAME\"."
         return 1
      fi
      TREE_VOL_NAME=$(echo "$VOL_NAME" | sed -re "s/^%qtree%//" -e "s/\/.+$//")
      TREE_NAME=$(echo "$VOL_NAME" | sed -re "s/^%qtree%//" -e "s/^.+\///")
      #test if quotas file is accessible
      echo "$TETE_NAS" | grep -iq "nas" 2>&1 > /dev/null
      if [[ $? -eq 0 ]]; then
         TETE_NAS_QUOTAS=/Bvol0/etc/quotas
         if [[ ! -w $TETE_NAS_QUOTAS ]]; then
            /bin/mount nas:/vol/vol0 /nas-vol0/ 2>&1 > /dev/null
         fi
      fi

      if [[ -z $TETE_NAS_QUOTAS || ! -w $TETE_NAS_QUOTAS ]]; then
         error "Can't determine the emplacement of the quotas file ($TETE_NAS_QUOTAS)."
         return 1
      fi
   fi

   # Start of get_and_check_args for CREATE OR EXPORT
   if [[ "$CREATE" == "true" ]] || [[ "$EXPORT" == "true" ]]; then
      #check var TETE_NAS
      check_host_resolv $TETE_NAS
      if [[ $? -ne 0 ]]; then
         error "Can't resolve NAS server '$TETE_NAS'"
         return 1
      fi
   fi
   # End of get_and_check_args for CREATE OR EXPORT

   # Start of get_and_check_args for CREATE
   if [[ "$CREATE" == "true" ]]; then
      VOL_SIZE=`echo $database | cut -d':' -f 3`
      VOL_SNAP=`echo $database | cut -d':' -f 4`
      #check var VOL_SNAP
      if [[ ! -z $TREE_NAME ]]; then # if its a qtree, vol_snap is not used
         VOL_SNAP=0
      fi
      check_digit $VOL_SNAP 1,2
      if [[ $? -ne 0 ]]; then
         error "The snap value '$VOL_SNAP' is not correct"
         return 1
      fi
      #check var VOL_SIZE
      check_regExp $VOL_SIZE "^[[:digit:]]{1,}(m|g|t)$"
      if [[ $? -ne 0 ]]; then
         error "Volume size '$VOL_SIZE' must be '<numeric><m/g or t>'"
         return 1
      fi
      #compute total size
      VOL_SIZE_ORIG=$VOL_SIZE
      VOL_SIZE_UNIT=${VOL_SIZE##*[[:digit:]]}
      VOL_SIZE_UTIL=${VOL_SIZE/[mgt]/}
      if [[ $VOL_SIZE_UNIT == g ]]; then
         VOL_SIZE_UNIT=m
         VOL_SIZE_UTIL=$(( $VOL_SIZE_UTIL * 1024 ))
      fi
      if [[ $VOL_SIZE_UNIT == t ]]; then
         VOL_SIZE_UNIT=m
         VOL_SIZE_UTIL=$(( ( $VOL_SIZE_UTIL * 1024 ) * 1024 ))
      fi
      VOL_SIZE_TOT=`echo "(100 * $VOL_SIZE_UTIL) / (100 - $VOL_SNAP)" | bc` 
      VOL_SIZE=$VOL_SIZE_TOT$VOL_SIZE_UNIT
      #check if total size is a number greater or equal than usefull size
      check_regExp $VOL_SIZE "^[[:digit:]]{1,}(m|g|t)$"
      if [[ $? -ne 0 ]] || [[ ! $VOL_SIZE_TOT -ge $VOL_SIZE_UTIL ]]; then
         error "Can't compute the total size from the usefull size ($VOL_SIZE_UTIL$VOL_SIZE_UNIT) and the snapshot reserve ($VOL_SNAP%)"
         return 1
      fi
   fi
   # End of get_and_check_args for CREATE
   
   # Start of get_and_check_args for EXPORT OR MOUNT
   if [[ "$EXPORT" == "true" ]] || [[ "$MOUNT" == "true" ]]; then
      DEST_HOST=`echo $database | cut -d':' -f 5`
      DEST_HOST=`echo $DEST_HOST | cut -d'.' -f 1`
      if [[ -z $DEST_HOST ]]; then
         error "The dest server parameter is required to export or mount a volume !"
         return 1
      fi
   fi
   # End of get_and_check_args for EXPORT OR MOUNT

   # Start of get_and_check_args for EXPORT
   if [[ "$EXPORT" == "true" ]]; then
      #get the internal IP address
      get_internal_ip $DEST_HOST
      if [[ $? -ne 0 ]]; then
         error "Can't get the internal address of $DEST_HOST !"
         return 1
      fi
      DEST_IP_INT=$INT_IP
   fi
   # End of get_and_check_args for EXPORT
   
   # Start of get_and_check_args for MOUNT
   if [[ "$MOUNT" == "true" ]]; then
      #get the internal NAS dns name
      get_bubble $DEST_HOST
      if [[ $? -ne 0 ]]; then
         error "Can't get the buble of $DEST_HOST !"
         return 1
      fi
      TETE_NAS_INT=${TETE_NAS}.int.$BUBBLE
      MOUNT_PATH=`echo $database | cut -d':' -f 6`
      MOUNT_USER=`echo $database | cut -d':' -f 7`
      MOUNT_GROUP=`echo $database | cut -d':' -f 8`
      #check mount path
      if [[ -z $MOUNT_PATH ]]; then
         error "The mount path parameter is required to mount a volume !"
         return 1
      else
         check_regExp $MOUNT_PATH "^/[[:graph:]]+(/[[:graph:]]+)*$"
         if [[ $? -ne 0 ]]; then
            error "The mount path parameter must be of this format: /[[:graph:]]+(/[[:graph:]]+)*"
            return 1
         fi
      fi
      #check mount user
      if [[ -z $MOUNT_USER ]]; then
         error "The mount user parameter is required to mount a volume !"
         return 1
      fi
      #check mount group
      if [[ -z $MOUNT_GROUP ]]; then
         error "The mount group parameter is required to mount a volume !"
         return 1
      fi
      #get the mamangement IP address
      DEST_IP=`host $DEST_HOST | grep "has address" | cut -d' ' -f 4`
      check_regExp $DEST_IP "^([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}$"
      if [[ $? -ne 0 ]]; then
         error "Can't resolv $DEST_HOST with host command !"
         return 1
      fi
      #Test SSH
      ssh $DEST_IP echo "test" > /dev/null
      if [[ $? -ne 0 ]]; then
         error "Can't connect by ssh to $DEST_HOST/$DEST_IP (ssh $DEST_IP echo "test") !"
         return 1
      fi
      #Get OS type
      DEST_OS=`ssh $DEST_IP uname`
      check_regExp $DEST_OS "^(Linux|HP-UX|SunOS)$"
      if [[ $? -ne 0 ]]; then
         error "The OS type '$DEST_OS' is not supported !"
         return 1
      fi
      #Get mount bin
      DEST_MOUNT_BIN=$(ssh $DEST_IP "if [[ -f /bin/mount ]]; then echo "/bin/mount"; else if [[ -f /sbin/mount ]]; then echo "/sbin/mount"; else echo mount; fi fi")
   fi
   # End of get_and_check_args for MOUNT

   return 0
}
# End of the function get_and_check_args

###################################
# Create function
###################################
function create {
   #start the creation process
   if [[ -z $TREE_NAME ]]; then # if its not a qtree
      info "Create the volume $VOL_NAME of data space of $VOL_SIZE_ORIG(total space of $VOL_SIZE) on $TETE_NAS..."
      #test if the volume not already exist
      ssh $TETE_NAS vol status $VOL_NAME 2>&1 | grep -qE "No volume named"
      if [[ $? -ne 0 ]]; then
         error "The volume ${VOL_NAME} already exist on ${TETE_NAS}."
         return 1
      fi   
      if [[ -z "$TEST" ]]; then
         ssh $TETE_NAS vol create $VOL_NAME aggr0 $VOL_SIZE | grep -qE "^.*has completed\.$"
         if [[ $? -ne 0 ]]; then
            error "Can't create the volume (ssh $TETE_NAS vol create $VOL_NAME aggr0 $VOL_SIZE)"
            return 1
         else
            info "Volume $VOL_NAME of $VOL_SIZE on $TETE_NAS created."
         fi
      else
         test "ssh $TETE_NAS vol create $VOL_NAME aggr0 $VOL_SIZE"
      fi
      info "Set Security Style to Unix..."
      if [[ -z "$TEST" ]]; then
         ssh $TETE_NAS qtree security /vol/$VOL_NAME unix
         if [[ $? -ne 0 ]]; then
            error "Can't set Security Style Unix (sh $TETE_NAS qtree security /vol/$VOL_NAME unix)"
            return 1
         else
            info "Security Style has completed."
         fi
      else
         test "ssh $TETE_NAS qtree security /vol/$VOL_NAME unix"
      fi
      info "Set nosnap on..."
      if [[ -z "$TEST" ]]; then
         ssh $TETE_NAS vol options $VOL_NAME nosnap on > /dev/null
         ssh $TETE_NAS vol options $VOL_NAME | grep -qE "^.*nosnap=on.*$"
         if [[ $? -ne 0 ]]; then
            error "Can't set nosnap to on (ssh $TETE_NAS vol options $VOL_NAME nosnap on)"
            return 1
         else
            info "Option set nosnap=on has completed."
         fi
      else
         test "ssh $TETE_NAS vol options $VOL_NAME nosnap on"
      fi
      info "Set nosnapdir on..."
      if [[ -z "$TEST" ]]; then
         ssh $TETE_NAS vol options $VOL_NAME nosnapdir on > /dev/null
         ssh $TETE_NAS vol options $VOL_NAME | grep -qE "^.*nosnapdir=on.*$"
         if [[ $? -ne 0 ]]; then
            error "Can't set nosnapdir to on (ssh $TETE_NAS vol options $VOL_NAME nosnapdir on)"
            return 1
         else
            info "Option set nosnapdir=on has completed."
         fi
      else
         test "ssh $TETE_NAS vol options $VOL_NAME nosnapdir on"
      fi
      info "Set snapshot reserve to $VOL_SNAP%..."
      if [[ -z "$TEST" ]]; then
         ssh $TETE_NAS snap reserve $VOL_NAME $VOL_SNAP > /dev/null
         ssh $TETE_NAS snap reserve $VOL_NAME | grep -qE "^.*current snapshot reserve is $VOL_SNAP%.*$"
         if [[ $? -ne 0 ]]; then
            error "Can't set snap reserve to $VOL_SNAP% (ssh $TETE_NAS snap reserve $VOL_NAME $VOL_SNAP)"
            return 1
         else
            info "Set snap reserve to $VOL_SNAP% has completed."
         fi
      else
         test "ssh $TETE_NAS snap reserve $VOL_NAME $VOL_SNAP"
      fi
   else # if its a qtree
      info "Create the tree $TREE_NAME on the volume $TREE_VOL_NAME with a quota of $VOL_SIZE_ORIG on $TETE_NAS..."
      if [[ -z "$TEST" ]]; then
         #test if the volume exist
         ssh $TETE_NAS vol status $TREE_VOL_NAME 2>&1 | grep -qE "No volume named"
         if [[ $? -eq 0 ]]; then
            error "The volume ${TREE_VOL_NAME} not exist on ${TETE_NAS}, you must create this volume before creating a tree on it."
            return 1
         fi
         #create the tree
         ssh $TETE_NAS qtree create /vol/${TREE_VOL_NAME}/${TREE_NAME}
         if [[ $? -ne 0 ]]; then
            error "Can't create the tree (ssh $TETE_NAS qtree create /vol/${TREE_VOL_NAME}/${TREE_NAME})"
            return 1
         else
            info "Tree ${TREE_NAME} on volume $TREE_VOL_NAME on $TETE_NAS created."
         fi
         info "Set Security Style to Unix..."
         ssh $TETE_NAS qtree security /vol/${TREE_VOL_NAME}/${TREE_NAME} unix
         if [[ $? -ne 0 ]]; then
            error "Can't set Security Style Unix (sh $TETE_NAS qtree security /vol/${TREE_VOL_NAME}/${TREE_NAME} unix)"
            return 1
         else
            info "Security Style has completed."
         fi
      else
         test "ssh $TETE_NAS qtree create /vol/${TREE_VOL_NAME}/${TREE_NAME}"
         test "ssh $TETE_NAS qtree security /vol/${TREE_VOL_NAME}/${TREE_NAME} unix"
      fi
      info "Adding quota for /vol/${TREE_VOL_NAME}/${TREE_NAME} of $VOL_SIZE_ORIG in ${TETE_NAS_QUOTAS}"
      # Is it already in quotas file
      cat ${TETE_NAS_QUOTAS} | grep -iqE "^/vol/${TREE_VOL_NAME}/${TREE_NAME}" 2>&1 > /dev/null
      if [[ $? -ne 0 ]]; then
         if [[ -z "$TEST" ]]; then
            info "Add the quotas for /vol/${TREE_VOL_NAME}/${TREE_NAME}..."
            echo -e "/vol/${TREE_VOL_NAME}/${TREE_NAME}\ttree ${VOL_SIZE_ORIG} - - - -" >> ${TETE_NAS_QUOTAS}
            cat ${TETE_NAS_QUOTAS} | grep -iqE "^/vol/${TREE_VOL_NAME}/${TREE_NAME}" 2>&1 > /dev/null
            if [[ $? -ne 0 ]]; then
               error "Can't add the quotas in ${TETE_NAS_QUOTAS}"
               return 1
            else
               info "Enable and rezise the quotas of ${TREE_VOL_NAME}..."
               ssh $TETE_NAS quota status ${TREE_VOL_NAME} | grep -iqE "quotas are on" 2>&1 > /dev/null
               if [[ $? -eq 0 ]]; then
                  ssh $TETE_NAS quota off ${TREE_VOL_NAME}
               fi
               ssh $TETE_NAS quota on ${TREE_VOL_NAME}
               sleep 4
               for i in $(seq 1 20); do
                  ssh $TETE_NAS quota report /vol/${TREE_VOL_NAME}/${TREE_NAME} 2>&1 | grep -iqE "quotas are initializing" > /dev/null
                  if [[ $? -eq 0 ]]; then
                     echo -n "$i-waiting quotas init... "
                     sleep 2
                     continue
                  else
                     break
                  fi
               done
               if [[ $i -ne 1 ]]; then
                  echo ""
               fi
               ssh $TETE_NAS quota report /vol/${TREE_VOL_NAME}/${TREE_NAME} | grep -iqE "^tree.*${TREE_VOL_NAME}.*${TREE_NAME}" 2>&1 > /dev/null
               if [[ $? -ne 0 ]]; then
                  error "The quotas has been add in ${TETE_NAS_QUOTAS}, but can get it by \"quota report\" command: ssh $TETE_NAS quota report /vol/${TREE_VOL_NAME}/${TREE_NAME}"
                  return 1
               else
                  info "Quotas successfully added for the tree ${TREE_NAME}"
               fi
            fi
         else
            test "echo -e \"/vol/${TREE_VOL_NAME}/${TREE_NAME}\ttree ${VOL_SIZE_ORIG} - - - -\" >> ${TETE_NAS_QUOTAS}"
            test "ssh $TETE_NAS quota off ${TREE_VOL_NAME}"
            test "ssh $TETE_NAS quota on ${TREE_VOL_NAME}"
         fi
      else
         error "This tree is already declared in quotas file (${TETE_NAS_QUOTAS}), it will not be updated, content=\n\"$(cat ${TETE_NAS_QUOTAS} | grep -iE "^/vol/${TREE_VOL_NAME}/${TREE_NAME}")\""
         return 1
      fi
   fi
   return 0
}
# End of create function

###################################
# Export function
###################################
function export {
   info "Export the FS /vol/$VOL_NAME..."
   if [[ -z "$TEST" ]]; then
      ssh $TETE_NAS exportfs -p sec=sys,rw=$DEST_IP_INT,root=$DEST_IP_INT /vol/$VOL_NAME > /dev/null
      ssh $TETE_NAS exportfs -q /vol/$VOL_NAME | grep -qE "^/vol/$VOL_NAME.*rw=$DEST_IP_INT.*$"
      if [[ $? -ne 0 ]]; then
         error "Can't export the FS /vol/$VOL_NAME to $DEST_IP_INT )."
         return 1
      else
         info "Export the FS /vol/$VOL_NAME to $DEST_IP_INT has completed."
      fi
   else
      test "ssh $TETE_NAS exportfs -p sec=sys,rw=$DEST_IP_INT,root=$DEST_IP_INT /vol/$VOL_NAME"
   fi
   return 0
}
# End of export function

###################################
# Mount function
###################################
function mount {
   info "Create the mount point $MOUNT_PATH on $DEST_HOST..."
   if [[ -z "$TEST" ]]; then
      ssh $DEST_IP "mkdir -p $MOUNT_PATH"
      if [[ $? -ne 0 ]]; then
         error "Can't create the directory $MOUNT_PATH on $DEST_HOST (ssh $DEST_IP 'mkdir $MOUNT_PATH')"
         return 1
      else
         info "Create mount point $MOUNT_PATH has completed."
      fi
   else
      test "ssh $DEST_IP \"mkdir -p $MOUNT_PATH\""
   fi
   info "Insert the mount description in fstab and mount it on $DEST_HOST..."
   if [[ "$DEST_OS" == "SunOS" ]]; then
      FSTAB_FILE=/etc/vfstab
   else
      FSTAB_FILE=/etc/fstab
   fi
   if [[ "$DEST_OS" == "Linux" ]]; then
      ssh_cmd="echo $TETE_NAS_INT:/vol/$VOL_NAME   $MOUNT_PATH   nfs   rw,nolock,bg,intr,hard,timeo=600,wsize=32768,rsize=32768,vers=3,tcp >> ${FSTAB_FILE}"
   else
      if [[ "$DEST_OS" == "SunOS" ]]; then
         ssh_cmd="echo $TETE_NAS_INT:/vol/$VOL_NAME - $MOUNT_PATH nfs - yes rw,fg,nointr,hard,timeo=600,wsize=32768,rsize=32768,vers=3 >> ${FSTAB_FILE}"
      else
         ssh_cmd="echo $TETE_NAS_INT:/vol/$VOL_NAME   $MOUNT_PATH   nfs   rw,fg,nointr,hard,timeo=600,wsize=32768,rsize=32768,vers=3 0 0 >> ${FSTAB_FILE}"
      fi
   fi
   if [[ -z "$TEST" ]]; then
      ssh $DEST_IP "grep -v \"^#\" ${FSTAB_FILE} | grep \"${MOUNT_PATH}\""
      if [[ $? -eq 0 ]]; then
         info "The mount description of $MOUNT_PATH already exist in ${FSTAB_FILE}, remove it to update it..."
         ssh $DEST_IP "cp -f ${FSTAB_FILE} ${FSTAB_FILE}.backup"
         ssh $DEST_IP "cat ${FSTAB_FILE} | grep -v ${MOUNT_PATH} > ${FSTAB_FILE}.new"
         ssh $DEST_IP "mv -f ${FSTAB_FILE}.new ${FSTAB_FILE}"
      fi
      ssh $DEST_IP "$ssh_cmd"
      ssh $DEST_IP $DEST_MOUNT_BIN $MOUNT_PATH
      ssh $DEST_IP df $MOUNT_PATH | grep -q "^.*/vol/$VOL_NAME.*$"
      if [[ $? -ne 0 ]]; then
         error "Can't mount the FS /vol/$VOL_NAME on $MOUNT_PATH, informations:"
         info "\t-add in fstab: $ssh_cmd"
         info "\t-$DEST_MOUNT_BIN $MOUNT_PATH"
         info "\t-df $MOUNT_PATH return an error"
         return 1
      else
         info "Mount $MOUNT_PATH has completed."
      fi
   else
      ssh $DEST_IP "grep -v \"^#\" ${FSTAB_FILE} | grep \"${MOUNT_PATH}\""
      if [[ $? -eq 0 ]]; then
         info "The mount description of $MOUNT_PATH already exist in ${FSTAB_FILE}, it will be updated..."
         test "ssh $DEST_IP \"cp -f ${FSTAB_FILE} ${FSTAB_FILE}.backup\""
         test "ssh $DEST_IP \"cat ${FSTAB_FILE} | grep -v ${MOUNT_PATH} > ${FSTAB_FILE}.new\""
         test "ssh $DEST_IP \"mv -f ${FSTAB_FILE}.new ${FSTAB_FILE}\""
      fi
      test "ssh $DEST_IP \"$ssh_cmd\""
      test "ssh $DEST_IP $DEST_MOUNT_BIN $MOUNT_PATH"
   fi
   info "Set directory owner and group to $MOUNT_USER:$MOUNT_GROUP on $MOUNT_PATH..."
   if [[ -z "$TEST" ]]; then
      ssh $DEST_IP chown -hR $MOUNT_USER:$MOUNT_GROUP $MOUNT_PATH
      ssh $DEST_IP ls -dl $MOUNT_PATH | grep -q "^.*$MOUNT_USER.*$MOUNT_GROUP.*$"
      if [[ $? -ne 0 ]]; then
         error "Can't change the owner of the directory $MOUNT_PATH (ssh $DEST_IP chown -hR $MOUNT_USER:$MOUNT_GROUP $MOUNT_PATH)."
         return 1
      else
         info "Owner of $MOUNT_PATH has been changed."
      fi
   else
      test "ssh $DEST_IP chown $MOUNT_USER:$MOUNT_GROUP $MOUNT_PATH"
   fi
}
# End of mount function


main


Fonctions NAS_fs.env :

# -_-'Bash script'-_-
#
# Common fonctions of bash scripts
#
# 07/30/2009 - Romain RUDIGER
#

#This try to resolv a given hostname and check this is an IPv4 address
#
#Args: <host name>
function check_host_resolv {
	host $1 | grep -Eq "^.*has address ([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}$" > /dev/null
	return $?
}

#Check if a given value contain only digit
#
#Args: <The value to check> [number of digit]
function check_digit {
	if [[ -z $2 ]]; then
		lenght=+
	else
		lenght={$2}
	fi
	echo $1 | grep -Eq "^[[:digit:]]$lenght$"  > /dev/null
	return $?
}

#Check if a given value match the given regExp
#
#Args: <value> <regExp>
function check_regExp {
	echo $1 | grep -Eq $2 > /dev/null
	return $?	
}

#Get the buble of a given host
#
#Arg: the server name
#Return:BUBBLE
function get_bubble
{
   BUBBLE=`nslookup $1 | awk '/Name/ {split($2,tmp,"."); print tmp[3]}'`
   return 0
}

#Get internal IP
#
#Arg: the server name
#Return: INT_IP var
function get_internal_ip
{
   host=`nslookup $1 | awk '/Name/ {split($2,tmp,"."); print tmp[1]}'`
   get_bubble $host
   INT_IP=`host $host.int.$BUBBLE | grep -E "^.*has address ([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}$" | cut -d' ' -f 4`
   check_regExp $INT_IP "^([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}$"
   if [[ $? -ne 0 ]]; then
      error "Can't get the internal address of $host on $host.int.$BUBBLE !"
      return 1
   fi
   return 0
}

Fichier de configuration :

#This is the configuration file for NAS_fs.sh script
#-> Options to create a volume, export it and mount it (-create -export -mount):
#   <volume name>:<tete nas>:<volume data size (w/o snapshot space)>m/g/t:<snap reserve>:<dest server>:<mount path>:<user>:<group>"
#-> Options to create a volume (-create):
#   <volume name>:<tete nas>:<volume data size (whitout snapshot space)>m/g/t:<snap reserve>::::
#-> Options to export a volume (-export):
#   <volume name>:<tete nas>:::<dest server>:::
#-> Options to mount a volume (-mount):
#   <volume name>:<tete nas>:::<dest server>:<mount path>:<user>:<group>"
#
#################
# SIMPLE VOLUME #
#################
#To create a simple volume DATA of 20GB of data +20% of snapshot mounted on /data on server:
# DATA:nas-a:20g:20:server:/data:user:group
#
#Put this line whithout # and launch this to test the configuration: 
# ./NAS_fs.sh -create -export -mount -test
#The launch :
# ./NAS_fs.sh -create -export -mount
#
####################
# QTREE AND QUOTAS #
####################
#To create a qtree "XX" of 7GB of data +20% of snapshot on server with three trees: aa (5GB), bb (1GB), cc (1GB)
# %qtreevol%XX:nas-a:7g:20::::
# %qtree%XX/aa:nas-a:5g::server:/XX/aa:user:group
# %qtree%XX/bb:nas-a:1g::server:/XX/bb:user:group
# %qtree%XX/cc:nas-a:1g::server:/XX/cc:user:group
#
#Put these lines whithout # and launch this to test the configuration: 
# ./NAS_fs.sh -create -export -mount -test
#The launch :
# ./NAS_fs.sh -create -export -mount