cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH] gfs2 init script
@ 2008-11-10 16:05 Marian Marinov
  2008-11-11 10:44 ` Marian Marinov
  0 siblings, 1 reply; 3+ messages in thread
From: Marian Marinov @ 2008-11-10 16:05 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Hello,
I revised the gfs2 init script in the hope to make it more LSB conforming.

1. I tried to make the script using only one style of codding
2. Added more secure path
3. Added permission check at the beginning
4. Changed the runlevels on which this script should be run
5. Added function check_mounted. This function is used to determine if all 
gfs2 mountpoints have been actually mounted. 
6. Cleared the case body from all code 
7. Created stop_gfs/start_gfs/status_gfs function which are then used in the 
case structure 
8. Added option in the script to load the necessary module if it is not 
already loaded. Should I add lock_dlm and lock_nolock to the checked 
modules ?
9. Added check if there is at all gfs2 mountpoint mounted on stop
10. Added check if the modprobe -r has finshed correctly 

All are written but have not been tested since I don't have gfs2 cluster 
currently running on my home cluster.

Please provide me with any feedback and possibly a ToDo for the init scripts. 
I'll be more then glad to assist with writing perl/shell scripts for GFS.

This is the patch:

diff --git a/gfs2/init.d/gfs2.in b/gfs2/init.d/gfs2.in
index 35688a0..e11184b 100644
--- a/gfs2/init.d/gfs2.in
+++ b/gfs2/init.d/gfs2.in
@@ -2,7 +2,7 @@
 #
 # gfs2 mount/unmount helper
 #
-# chkconfig: - 26 74
+# chkconfig: 2345 26 74
 # description: mount/unmount gfs2 filesystems configured in /etc/fstab

 ### BEGIN INIT INFO
@@ -15,6 +15,15 @@
 # Description:         mount/unmount gfs2 filesystems configured 
in /etc/fstab
 ### END INIT INFO

+# set secure PATH
+PATH="/bin:/usr/bin:/sbin:/usr/sbin"
+
+# Check privileges
+if [ "$1" != 'status' ] && [ "$(whoami)" != 'root' ]; then
+       echo "You are not allowed to run this script."
+       exit 4;
+fi
+
 # rpm based distros
 if [ -d /etc/sysconfig ]; then
        [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
@@ -34,14 +43,16 @@ if [ -d /etc/default ]; then
        failure=failure
 fi

-local_success()
-{
+function local_success() {
     echo -ne "[  OK  ]\r"
 }

-local_failure()
-{
+function local_failure() {
     echo -ne "[FAILED]\r"
+       # if we have exit code, use it
+       if [ "$1" = [0-9] ]; then
+               exit $1
+       fi
 }

 #
@@ -50,61 +61,87 @@ local_failure()
 GFS2FSTAB=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $4 !~ /noauto/ { print 
$2 }' /etc/fstab)
 GFS2MTAB=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" { print 
$2 }' /proc/mounts)

-# See how we were called.
-case "$1" in
-  start)
-        if [ -n "$GFS2FSTAB" ]
-       then
+function check_mounted() {
+       mounted=0
+       count=0
+       for mountpoint in $GFS2FSTAB; do
+               let count++
+               if ( grep " $mountpoint " /proc/mounts > /dev/null ); then
+                       let mounted++
+               fi
+       done
+       if [ $(($count-$mounted)) != 0 ]; then
+               return 1
+       else
+               return 0
+       fi
+}
+
+function start_gfs() {
+       # check if we have gfs2 as a module
+       if ( modprobe -l|grep gfs2 > /dev/null ); then
+               echo "Loading gfs2 module: "
+               # check if we have /proc/modules
+               if [ -f /proc/modules ]; then
+                       # check if gfs2 module is loaded
+                       if ( ! grep gfs2 /proc/modules > /dev/null ); then
+                               modprobe gfs2
+                               if [ "$?" = 0 ]; then
+                                       local_success
+                               else
+                                       local_failure 6
+                               fi
+                       else
+                               local_failure 6
+                       fi
+               else
+                       local_failure 6
+               fi
+       fi
+       if [ -n "$GFS2FSTAB" ] && ( check_mounted ); then
                echo -n "Mounting GFS2 filesystems: "
                mount -a -t gfs2
                rtrn=$?
                if [ $rtrn = 0 ]; then
-                       touch $LOCK_FILE
-                       $success
-                       echo
+                       if ( check_mounted ); then
+                               touch $LOCK_FILE
+                               local_success
+                       else
+                               local_failure 7
+                       fi
                else
-                       $failure
-                       echo
-               fi
+                       local_failure 1
+               fi
        fi
-       ;;
+       exit 0
+}

-  stop)
-       if [ -n "$GFS2MTAB" ]
-       then
+function stop_gfs() {
+       if [ -n "$GFS2MTAB" ] && ( ! check_mounted ); then
                sig=
                retry=6
-               remaining=`LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" 
{print $2}' /proc/mounts`
-               while [ -n "$remaining" -a "$retry" -gt 0 ]
-               do
+               remaining=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" 
{print $2}' /proc/mounts)
+               while [ -n "$remaining" -a "$retry" -gt 0 ]; do
                        echo -n "Unmounting GFS2 filesystems: "
                        umount -a -t gfs2
-                       rtrn=$?
-                       if [ $rtrn = 0 ]; then
-                               $success
-                               echo
+                       if [ "$?" = 0 ]; then
+                               local_success
                        else
-                               $failure
-                               echo
+                               local_failure 1
                        fi
-
-                       if [ $retry -eq 0 ]
-                       then
+                       if [ $retry -eq 0 ]; then
                                echo -n "Unmounting GFS2 filesystems (lazy): "
                                umount -l -a -t gfs2
-                               rtrn=$?
-                               if [ $rtrn = 0 ]; then
-                                       $success
-                                       echo
+                               if [ "$?" = 0 ]; then
+                                       local_success
                                else
-                                       $failure
-                                       echo
+                                       local_failure 1
                                fi
                                break
                        fi

                        sleep 2
-                       remaining=`LC_ALL=C awk '!/^#/ && $3 == "gfs2" && 
$2 != "/" {print $2}' /proc/mounts`
+                       remaining=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && 
$2 != "/" {print $2}' /proc/mounts)
                        [ -z "$remaining" ] && break
                        fuser -k -m $sig $remaining > /dev/null 2>&1
                        sleep 10
@@ -113,36 +150,55 @@ case "$1" in
                done
        fi

-       modprobe -r gfs2
-       rm -f $LOCK_FILE
-       ;;
+       if ( modprobe -r gfs2 && rm -f $LOCK_FILE ) ; then
+               exit 0
+       else
+               exit 1
+       fi
+}

-  status)
-       if [ -f /proc/mounts ]
-       then
-               [ -n "$GFS2FSTAB" ] && {
-                    echo "Configured GFS2 mountpoints: "
-                    for fs in $GFS2FSTAB; do echo $fs ; done
+function status_gfs() {
+       if [ -f /proc/mounts ]; then
+               [ -n "$GFS2FSTAB" ] && {
+                       echo "Configured GFS2 mountpoints: "
+                       for fs in $GFS2FSTAB; do echo $fs ; done
                }
                [ -n "$GFS2MTAB" ] && {
-                      echo "Active GFS2 mountpoints: "
-                     for fs in $GFS2MTAB; do echo $fs ; done
+                       echo "Active GFS2 mountpoints: "
+                       for fs in $GFS2MTAB; do echo $fs ; done
                }
+               exit 0
        else
                echo "/proc filesystem unavailable"
+               exit 4
        fi
+}
+
+# See how we were called.
+case "$1" in
+  start)
+       start_gfs
+       ;;
+
+  stop)
+       stop_gfs
+       ;;
+
+  status)
+       status_gfs
        ;;

   restart)
-       $0 stop
-       $0 start
+       stop_gfs
+       start_gfs
        ;;

   reload)
-        $0 start
+       start_gfs
        ;;
+
   *)
-       echo $"Usage: $0 {start|stop|restart|reload|status}"
+       echo "Usage: $0 {start|stop|restart|reload|status}"
        exit 1
 esac

-------------------------
If you want you could download the whole script from here:


Best regards 
Marian Marinov



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Cluster-devel] [PATCH] gfs2 init script
  2008-11-10 16:05 [Cluster-devel] [PATCH] gfs2 init script Marian Marinov
@ 2008-11-11 10:44 ` Marian Marinov
  2008-11-13  6:15   ` Fabio M. Di Nitto
  0 siblings, 1 reply; 3+ messages in thread
From: Marian Marinov @ 2008-11-11 10:44 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Hello,

My previous script was not tested at all. Today I tested it and rewrote many 
parts.

This patch now changes the output of the status option and have everything 
from the old patch tested and it should work.

Sorry for the very stupid previous patch.

diff --git a/gfs2/init.d/gfs2.in b/gfs2/init.d/gfs2.in
old mode 100644
new mode 100755
index 35688a0..cb9bee9
--- a/gfs2/init.d/gfs2.in
+++ b/gfs2/init.d/gfs2.in
@@ -2,7 +2,7 @@
 #
 # gfs2 mount/unmount helper
 #
-# chkconfig: - 26 74
+# chkconfig: 2345 26 74
 # description: mount/unmount gfs2 filesystems configured in /etc/fstab

 ### BEGIN INIT INFO
@@ -15,6 +15,15 @@
 # Description:         mount/unmount gfs2 filesystems configured 
in /etc/fstab
 ### END INIT INFO

+# set secure PATH
+PATH="/bin:/usr/bin:/sbin:/usr/sbin"
+
+# Check privileges
+if [ "$1" != 'status' ] && [ "$(whoami)" != 'root' ]; then
+       echo "You are not allowed to run this script."
+       exit 4;
+fi
+
 # rpm based distros
 if [ -d /etc/sysconfig ]; then
        [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
@@ -34,14 +43,16 @@ if [ -d /etc/default ]; then
        failure=failure
 fi

-local_success()
-{
-    echo -ne "[  OK  ]\r"
+function local_success() {
+    echo -ne "[  OK  ]\n"
 }

-local_failure()
-{
+function local_failure() {
     echo -ne "[FAILED]\r"
+       # if we have exit code, use it
+       if [ "$1" = [0-9] ]; then
+               exit $1
+       fi
 }

 #
@@ -50,61 +61,77 @@ local_failure()
 GFS2FSTAB=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $4 !~ /noauto/ { print 
$2 }' /etc/fstab)
 GFS2MTAB=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" { print 
$2 }' /proc/mounts)

-# See how we were called.
-case "$1" in
-  start)
-        if [ -n "$GFS2FSTAB" ]
-       then
+function check_mounted() {
+       mounted=0
+       count=0
+       for mountpoint in $GFS2FSTAB; do
+               let count++
+               if ( grep " $mountpoint " /proc/mounts > /dev/null ); then
+                       let mounted++
+               fi
+       done
+       if [ $(($count-$mounted)) != 0 ]; then
+               return 1
+       else
+               return 0
+       fi
+}
+
+function start_gfs() {
+       # check if we have /proc/modules
+       # check if gfs2 module is loaded
+       # check if we have gfs2 as a module
+       if [ -f /proc/modules ] &&
+               ( ! grep gfs2 /proc/modules > /dev/null ) &&
+               ( modprobe -l|grep gfs2 > /dev/null ); then
+                       echo -n "Loading gfs2 module: "
+                       if ( modprobe gfs2 ); then
+                               local_success
+                       else
+                               local_failure 6
+                       fi
+       fi
+       # check if we have gfs2 mountpoints in /etc/fstab
+       # check if these mountpoints are not mounted already
+       if [ -n "$GFS2FSTAB" ] && ( ! check_mounted ); then
                echo -n "Mounting GFS2 filesystems: "
-               mount -a -t gfs2
-               rtrn=$?
-               if [ $rtrn = 0 ]; then
-                       touch $LOCK_FILE
-                       $success
-                       echo
+               if ( mount -a -t gfs2 ); then
+                       if ( check_mounted && touch $LOCK_FILE ); then
+                               local_success
+                       else
+                               local_failure 7
+                       fi
                else
-                       $failure
-                       echo
-               fi
+                       local_failure 1
+               fi
        fi
-       ;;
+       exit 0
+}

-  stop)
-       if [ -n "$GFS2MTAB" ]
-       then
+function stop_gfs() {
+       if [ -n "$GFS2MTAB" ]; then
                sig=
                retry=6
-               remaining=`LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" 
{print $2}' /proc/mounts`
-               while [ -n "$remaining" -a "$retry" -gt 0 ]
-               do
+               remaining=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && $2 != "/" 
{print $2}' /proc/mounts)
+               while [ -n "$remaining" -a "$retry" -gt 0 ]; do
                        echo -n "Unmounting GFS2 filesystems: "
-                       umount -a -t gfs2
-                       rtrn=$?
-                       if [ $rtrn = 0 ]; then
-                               $success
-                               echo
+                       if ( umount -a -t gfs2 ); then
+                               local_success
                        else
-                               $failure
-                               echo
+                               local_failure
                        fi
-
-                       if [ $retry -eq 0 ]
-                       then
+                       if [ $retry -eq 0 ]; then
                                echo -n "Unmounting GFS2 filesystems (lazy): "
-                               umount -l -a -t gfs2
-                               rtrn=$?
-                               if [ $rtrn = 0 ]; then
-                                       $success
-                                       echo
+                               if ( umount -l -a -t gfs2 ); then
+                                       local_success
                                else
-                                       $failure
-                                       echo
+                                       local_failure 1
                                fi
                                break
                        fi

                        sleep 2
-                       remaining=`LC_ALL=C awk '!/^#/ && $3 == "gfs2" && 
$2 != "/" {print $2}' /proc/mounts`
+                       remaining=$(LC_ALL=C awk '!/^#/ && $3 == "gfs2" && 
$2 != "/" {print $2}' /proc/mounts)
                        [ -z "$remaining" ] && break
                        fuser -k -m $sig $remaining > /dev/null 2>&1
                        sleep 10
@@ -113,36 +140,67 @@ case "$1" in
                done
        fi

-       modprobe -r gfs2
-       rm -f $LOCK_FILE
-       ;;
+       if ( modprobe -r gfs2 && rm -f $LOCK_FILE ) ; then
+               exit 0
+       else
+               exit 1
+       fi
+}

-  status)
-       if [ -f /proc/mounts ]
-       then
-               [ -n "$GFS2FSTAB" ] && {
-                    echo "Configured GFS2 mountpoints: "
-                    for fs in $GFS2FSTAB; do echo $fs ; done
-               }
-               [ -n "$GFS2MTAB" ] && {
-                      echo "Active GFS2 mountpoints: "
-                     for fs in $GFS2MTAB; do echo $fs ; done
+function status_gfs() {
+       # check if we have module for gfs2
+       if [ -f /proc/modules ] && ( modprobe -l|grep gfs2 > /dev/null ); then
+               echo -ne 'GFS2 module: '
+               if ( grep gfs2 /proc/modules > /dev/null ); then
+                       echo "[   loaded   ]"
+               else
+                       echo "[ not loaded ]"
+               fi
+       fi
+       if [ -f /proc/mounts ]; then
+               [ -n "$GFS2FSTAB" ] && {
+                       echo "Configured GFS2 mountpoints: "
+                       for fs in $GFS2FSTAB; do
+                               echo -ne "\t$fs ";
+                               if ( grep "$fs" /proc/mounts > /dev/null ); 
then
+                                       echo "[   mounted   ]"
+                               else
+                                       echo "[ not mounted ]"
+                               fi
+                       done
                }
+               exit 0
        else
                echo "/proc filesystem unavailable"
+               exit 4
        fi
+}
+
+# See how we were called.
+case "$1" in
+  start)
+       start_gfs
+       ;;
+
+  stop)
+       stop_gfs
+       ;;
+
+  status)
+       status_gfs
        ;;

   restart)
-       $0 stop
-       $0 start
+       stop_gfs
+       start_gfs
        ;;

   reload)
-        $0 start
+       start_gfs
        ;;
+
   *)
-       echo $"Usage: $0 {start|stop|restart|reload|status}"
+       echo "Usage: $0 {start|stop|restart|reload|status}"
        exit 1
 esac




Best regards
Marian Marinov




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Cluster-devel] [PATCH] gfs2 init script
  2008-11-11 10:44 ` Marian Marinov
@ 2008-11-13  6:15   ` Fabio M. Di Nitto
  0 siblings, 0 replies; 3+ messages in thread
From: Fabio M. Di Nitto @ 2008-11-13  6:15 UTC (permalink / raw)
  To: cluster-devel.redhat.com


Hi Marian,

thanks for your patch. I have a few comments on it.

git-am ../init.diff
Applying gfs2 init script
fatal: corrupt patch at line 18
Patch failed at 0001.

first I can't apply the patch.. the patch is corrupted. So I can only 
comment on what I can read from it but I was not able to test it.

> diff --git a/gfs2/init.d/gfs2.in b/gfs2/init.d/gfs2.in
> old mode 100644
> new mode 100755
> index 35688a0..cb9bee9
> --- a/gfs2/init.d/gfs2.in
> +++ b/gfs2/init.d/gfs2.in
> @@ -2,7 +2,7 @@
> #
> # gfs2 mount/unmount helper
> #
> -# chkconfig: - 26 74
> +# chkconfig: 2345 26 74
> # description: mount/unmount gfs2 filesystems configured in /etc/fstab

This is a "no-no". most distribution have slightly different 
interpretations of what runlevels should do. Let them decide where they 
want to run the scripts. Running by default has also a danger of making 
the boot problematic if somebody installed an RPM without configuring the 
stack properly. Better that they enable it after testing.

>
> ### BEGIN INIT INFO
> @@ -15,6 +15,15 @@
> # Description:         mount/unmount gfs2 filesystems configured
> in /etc/fstab
> ### END INIT INFO
>
> +# set secure PATH
> +PATH="/bin:/usr/bin:/sbin:/usr/sbin"

While this is generally a good point, we might have to add $sbindir from 
the build system here. There is no guarantee that our binaries or system 
binaries are installed in those paths (/usr/local... /opt..) etc.

> +
> +# Check privileges
> +if [ "$1" != 'status' ] && [ "$(whoami)" != 'root' ]; then
> +       echo "You are not allowed to run this script."
> +       exit 4;
> +fi

This is another "no-no". It's entirely possible to delegate mounting of 
disks to unprivilged users or users that are not root. There are system 
groups like "disk" for it as well. The number of checks to do are simply 
too complex with very little benefit for an init script.

mount will simply fail if you are not allowed to do the operation.

> +
> # rpm based distros
> if [ -d /etc/sysconfig ]; then
>        [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
> @@ -34,14 +43,16 @@ if [ -d /etc/default ]; then
>        failure=failure
> fi
>
> -local_success()
> -{
> -    echo -ne "[  OK  ]\r"
> +function local_success() {
> +    echo -ne "[  OK  ]\n"
> }
>
> -local_failure()
> -{
> +function local_failure() {
>     echo -ne "[FAILED]\r"
> +       # if we have exit code, use it
> +       if [ "$1" = [0-9] ]; then
> +               exit $1
> +       fi
> }

Careful here. local_failure is the equivalent of failure in 
/etc/init.d/functions. It only performs an echo. So should this one. The 
return code should be issues after by the script and not embedded (see 
also the other comments before about using local_*

> +function start_gfs() {
> +       # check if we have /proc/modules
> +       # check if gfs2 module is loaded
> +       # check if we have gfs2 as a module
> +       if [ -f /proc/modules ] &&
> +               ( ! grep gfs2 /proc/modules > /dev/null ) &&
> +               ( modprobe -l|grep gfs2 > /dev/null ); then
> +                       echo -n "Loading gfs2 module: "
> +                       if ( modprobe gfs2 ); then
> +                               local_success
> +                       else
> +                               local_failure 6
> +                       fi

both local_success and local_failure should be $success and $failure.

We are aliasing them according to the distro we are running. rpm based 
distro have those functions embedded in /etc/init.d/functions. and they do 
"pretty output".

In case of deb based distros, then there is no such thing. So we alias 
them to the local version.

I did try to be careful not to change behaviour from system and local. I 
would prefer to respect that from this patch as well.

> +       if ( modprobe -r gfs2 && rm -f $LOCK_FILE ) ; then
> +               exit 0
> +       else
> +               exit 1
> +       fi
> +}

I really don't think you want to fail if you can't remove the LOCK_FILE or 
the module. Try to do both, but it's not a condition where you want to 
return an error.

Can you plese resend it as attachment? maybe either your or my MUA is 
corrupting it.

Thanks
Fabio

--
I'm going to make him an offer he can't refuse.



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-11-13  6:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-10 16:05 [Cluster-devel] [PATCH] gfs2 init script Marian Marinov
2008-11-11 10:44 ` Marian Marinov
2008-11-13  6:15   ` Fabio M. Di Nitto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).