#!/bin/sh # (C) 2006, 2007, 2008 Gluster Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301 USA _init () { # log level definitions LOG_NONE=NONE; LOG_CRITICAL=CRITICAL; LOG_ERROR=ERROR; LOG_WARNING=WARNING; LOG_INFO=INFO LOG_DEBUG=DEBUG; LOG_TRACE=TRACE; prefix="@prefix@"; exec_prefix=@exec_prefix@; cmd_line=$(echo "@sbindir@/glusterfs"); case `uname -s` in NetBSD) getinode="stat -f %i" getdev="stat -f %d" lgetinode="${getinode} -L" lgetdev="${getdev} -L" mounttab=/proc/mounts ;; Linux) getinode="stat -c %i $i" getdev="stat -c %d $d" lgetinode="${getinode} -L" lgetdev="${getdev} -L" mounttab=/etc/mtab ;; esac UPDATEDBCONF=/etc/updatedb.conf LD_LIBRARY_PATH=@libdir@:${LD_LIBRARY_PATH} export LD_LIBRARY_PATH } start_glusterfs () { # lets the comparsion be case insensitive for all strings if [ -n "$log_level_str" ]; then case "$( echo $log_level_str | tr '[a-z]' '[A-Z]')" in "ERROR") log_level=$LOG_ERROR; ;; "INFO") log_level=$LOG_INFO ;; "DEBUG") log_level=$LOG_DEBUG; ;; "CRITICAL") log_level=$LOG_CRITICAL; ;; "WARNING") log_level=$LOG_WARNING; ;; "TRACE") log_level=$LOG_TRACE; ;; "NONE") log_level=$LOG_NONE; ;; *) echo "invalid log level $log_level_str, using INFO"; log_level=$LOG_INFO; ;; esac fi if [ -n "$log_level" ]; then cmd_line=$(echo "$cmd_line --log-level=$log_level"); fi if [ -n "$read_only" ]; then cmd_line=$(echo "$cmd_line --read-only"); fi if [ -n "$acl" ]; then cmd_line=$(echo "$cmd_line --acl"); fi if [ -n "$selinux" ]; then cmd_line=$(echo "$cmd_line --selinux"); fi if [ -n "$worm" ]; then cmd_line=$(echo "$cmd_line --worm"); fi if [ -n "$log_file" ]; then cmd_line=$(echo "$cmd_line --log-file=$log_file"); fi if [ -n "$volfile_check" ]; then cmd_line=$(echo "$cmd_line --volfile-check"); fi if [ -n "$direct_io_mode" ]; then cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode"); fi if [ -n "$volume_name" ]; then cmd_line=$(echo "$cmd_line --volume-name=$volume_name"); fi # for rdma volume, we have to fetch volfile with '.rdma' added # to volume name, so that it fetches the right client vol file volume_id_rdma=""; if [ -z "$volfile_loc" ]; then if [ -n "$server_ip" ]; then if [ -n "$server_port" ]; then cmd_line=$(echo "$cmd_line --volfile-server-port=$server_port"); fi if [ -n "$transport" ]; then cmd_line=$(echo "$cmd_line --volfile-server-transport=$transport"); if [ "$transport" = "rdma" ]; then volume_id_rdma=".rdma"; fi fi if [ -n "$volume_id" ]; then if [ -n "$volume_id_rdma" ]; then volume_id="$volume_id$volume_id_rdma"; fi cmd_line=$(echo "$cmd_line --volfile-id=$volume_id"); fi if [ -n "$backupvolfile_server" ]; then cmd_line1=$(echo "$cmd_line --volfile-server=$backupvolfile_server"); fi if [ -n "$volfile_max_fetch_attempts" ]; then cmd_line=$(echo "$cmd_line --volfile-max-fetch-attempts=$volfile_max_fetch_attempts"); fi cmd_line=$(echo "$cmd_line --volfile-server=$server_ip"); fi else cmd_line=$(echo "$cmd_line --volfile=$volfile_loc"); fi cmd_line=$(echo "$cmd_line $mount_point"); err=0; $cmd_line; inode=$( ${getinode} $mount_point 2>/dev/null); # this is required if the stat returns error if [ -z "$inode" ]; then inode="0"; fi # retry the failover # if [ $? != "0" ]; then # <--- TODO: Once glusterfs returns proper error code, change it. if [ $inode -ne 1 ]; then err=1; if [ -n "$cmd_line1" ]; then cmd_line1=$(echo "$cmd_line1 $mount_point"); $cmd_line1; err=0; inode=$( ${getinode} $mount_point 2>/dev/null); # this is required if the stat returns error if [ -z "$inode" ]; then inode="0"; fi if [ $inode -ne 1 ]; then err=1; fi fi fi if [ $err -eq "1" ]; then echo "Mount failed. Please check the log file for more details." umount $mount_point > /dev/null 2>&1; exit 1; fi } usage () { echo "Usage: mount.glusterfs : -o Options: man 8 mount.glusterfs To display the version number of the mount helper: mount.glusterfs --version" } # check for recursive mounts. i.e, mounting over an existing brick check_recursive_mount () { if [ $2 = "/" ]; then echo Cannot mount over root; exit 2; fi # GFID check first # remove trailing / from mount point mnt_dir=${2%/}; export PATH; # check whether getfattr exists which getfattr > /dev/null 2>&1; if [ $? -ne 0 ]; then return; fi getfattr -n trusted.gfid $mnt_dir 2>/dev/null | grep -iq "trusted.gfid="; if [ $? -eq 0 ]; then echo "ERROR: $mnt_dir is in use as a brick of a gluster volume"; exit 2; fi # check if the mount point is a brick's parent directory GLUSTERD_WORKDIR="/var/lib/glusterd"; ls -L "$GLUSTERD_WORKDIR"/vols/*/bricks/* > /dev/null 2>&1; if [ $? -ne 0 ]; then return; fi brick_path=`grep ^path "$GLUSTERD_WORKDIR"/vols/*/bricks/* | cut -d "=" -f 2`; root_inode=`${lgetinode} /`; root_dev=`${lgetdev} /`; mnt_inode=`${lgetinode} $mnt_dir`; mnt_dev=`${lgetdev} $mnt_dir`; for brick in "$brick_path"; do # evaluate brick path to see if this is local, if non-local, skip iteration ls $brick > /dev/null 2>&1; if [ $? -ne 0 ]; then continue; fi getfattr -n trusted.gfid "$brick" 2>/dev/null | grep -iq "trusted.gfid="; if [ $? -ne 0 ]; then continue; else # brick is local while [ 1 ]; do tmp_brick="$brick"; brick="$brick"/..; brick_dev=`${lgetdev} $brick`; brick_inode=`${lgetinode} $brick`; if [ "$mnt_inode" -eq "$brick_inode" -a "$mnt_dev" -eq "$brick_dev" ]; then echo ERROR: $mnt_dir is a parent of the brick $tmp_brick; exit 2; fi [ "$root_inode" -ne "$brick_inode" -o "$root_dev" -ne "$brick_dev" ] || break; done; fi done; } main () { helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p'); in_opt="no" pos_args=0 for opt in "$@"; do if [ "$in_opt" = "yes" ]; then for pair in $(echo "$opt" | tr "," " "); do # Handle options without values. case "$pair" in "ro") read_only=1 ;; "acl") acl=1 ;; "selinux") selinux=1 ;; "worm") worm=1 ;; # "mount -t glusterfs" sends this, but it's useless. "rw") ;; *) key=$(echo "$pair" | cut -f1 -d'='); value=$(echo "$pair" | cut -f2- -d'='); # Handle options with values. case "$key" in "log-level") log_level_str=$value ;; "log-file") log_file=$value ;; "transport") transport=$value ;; "direct-io-mode") direct_io_mode=$value ;; "volume-name") volume_name=$value ;; "volume-id") volume_id=$value ;; "volfile-check") volfile_check=$value ;; "server-port") server_port=$value ;; "fetch-attempts") volfile_max_fetch_attempts=$value ;; "backupvolfile-server") backupvolfile_server=$value ;; *) echo "unknown option $key (ignored)" ;; esac esac done in_opt="no" elif [ "$opt" = "-o" ]; then in_opt="yes" else case $pos_args in 0) volfile_loc=$opt ;; 1) mount_point=$opt ;; *) echo "extra arguments at end (ignored)" ;; esac pos_args=$((pos_args+1)) fi done if [ $in_opt = "yes" -o $pos_args -lt 2 ]; then usage exit 1 fi [ -r "$volfile_loc" ] || { server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p'); test_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p'); [ -n "$test_str" ] && { volume_id="$test_str"; } volfile_loc=""; } # [ -n "$helper" ] && { cmd_line=$(echo "$cmd_line --$helper"); exec $cmd_line; exit 0; } # No need to do a ! -d test, it is taken care while initializing the # variable mount_point [ -z "$mount_point" -o ! -d "$mount_point" ] && { echo "ERROR: Mount point does not exist." usage; exit 0; } # Simple check to avoid multiple identical mounts if grep -q " ${mount_point}.*fuse" $mounttab; then echo -n "$0: according to mtab, GlusterFS is already mounted on " echo "$mount_point" exit 0; fi check_recursive_mount "$@"; # Append fuse.glusterfs to PRUNEFS variable in updatedb.conf(5). updatedb(8) # should not index files under GlusterFS, indexing will slow down GlusteFS # if the filesystem is several TB in size. test -f $UPDATEDBCONF && { if ! grep -q 'glusterfs' $UPDATEDBCONF; then sed 's/\(PRUNEFS.*\)"/\1 fuse.glusterfs"/' $UPDATEDBCONF \ > ${UPDATEDBCONF}.bak mv -f ${UPDATEDBCONF}.bak $UPDATEDBCONF fi } start_glusterfs; } _init "$@" && main "$@";