Bug 986919

Summary: Test case failure: /CoreOS/mysql/Sanity/init-script-LSB
Product: Red Hat Software Collections Reporter: Karel Volný <kvolny>
Component: mysqlAssignee: Honza Horak <hhorak>
Status: CLOSED ERRATA QA Contact: Karel Volný <kvolny>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: mysql55CC: bblaskov, databases-maint, kvolny
Target Milestone: ---   
Target Release: 1.1   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: mysql55-mysql-5.5.34-2.el6 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-04 07:25:06 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Karel Volný 2013-07-22 12:32:05 UTC
Filed from caserun https://tcms.engineering.redhat.com/run/62420/

There's a problem with the initscript, it returns different exitcode than expected in case of a problem with pidfile.

Note that it *may* be a testbug rather than a problem with package itself, but at the first glance I don't see why it shouldn't work the same as on non-collection version ...

Version-Release number of selected component (if applicable):
mysql55-mysql-server-5.5.32-2.el6.x86_64


Steps to Reproduce: 
run the test


Actual results: 
:: [ 14:03:20 ] ::  >>>>>>>>> pid file
Starting mysql55-mysqld:  [  OK  ]
:: [   PASS   ] :: File /opt/rh/mysql55/root/var/run/mysqld/mysqld.pid should exist
Stopping mysql55-mysqld:  [  OK  ]
:: [   PASS   ] :: Stopping the service
:: [   PASS   ] :: Writing nonsense into the pidfile
mysql55-mysqld dead but pid file exists
:: [   PASS   ] ::  Existing pid file, but service not started 
Stopping mysql55-mysqld:  [FAILED]
:: [   FAIL   ] :: Trying to stop the service (Expected 1, got 4)
removed `/opt/rh/mysql55/root/var/run/mysqld/mysqld.pid'
:: [   PASS   ] :: Removing the possible stale pidfile


Expected results:

Comment 2 Honza Horak 2013-07-25 15:55:04 UTC
This is part of the init script:

# failed to read pidfile, probably insufficient permissions
action $"Stopping $prog: " /bin/false
ret=4

So it seems the pid file doesn't have correct permissions or SELinux is involved. According to [1] exit code 4 is correct. Would that be sufficient explanation?

[1] http://fedoraproject.org/wiki/Packaging:SysVInitScript#Exit_Codes_for_non-Status_Actions

Comment 3 Karel Volný 2013-07-30 12:38:34 UTC
(In reply to Honza Horak from comment #2)
> This is part of the init script:
> 
> # failed to read pidfile, probably insufficient permissions
> action $"Stopping $prog: " /bin/false
> ret=4
> 
> So it seems the pid file doesn't have correct permissions or SELinux is
> involved.

I've added some debug output - ls -lZ says:

-rw-r--r--. root root unconfined_u:object_r:mysqld_var_run_t:s0 /opt/rh/mysql55/root/var/run/mysqld/mysqld.pid

with selinux in permissive mode, the file should be 100% readable

> According to [1] exit code 4 is correct. Would that be sufficient
> explanation?

it would be, if ...

1) the file would be really unreadable
2) all versions would act the same

I've tried to add some debug into the initscript, like:

177a178,181
> echo $mypidfile
> ls -lZ "$mypidfile"
> cat "$mypidfile"
> echo MYSQLPID=$MYSQLPID
198c202
<               # kill command failed, probably insufficient permissions
---
>               echo "# kill command failed, probably insufficient permissions"
203c207
<           # failed to read pidfile, probably insufficient permissions
---
>           echo "# failed to read pidfile, probably insufficient permissions"


and the test output is:

:: [   PASS   ] ::  Existing pid file, but service not started  (Expected 1, got 1)
/opt/rh/mysql55/root/var/run/mysqld/mysqld.pid
-rw-r--r--. root root unconfined_u:object_r:mysqld_var_run_t:s0 /opt/rh/mysql55/root/var/run/mysqld/mysqld.pid
666666
MYSQLPID=666666
# kill command failed, probably insufficient permissions
Stopping mysql55-mysqld:                                   [FAILED]
:: [   FAIL   ] :: Trying to stop the service (Expected 1, got 4)

so it is readable, and the execution follows different code path

comparing with the old init script, there is:

            else
                action $"Stopping $prog: " /bin/false
            fi


while the new one has:

            else
                # kill command failed, probably insufficient permissions
                action $"Stopping $prog: " /bin/false
                ret=4
            fi

so there is the false assumption that it fails due to insufficient permissions and it changes the ret variable, which contained the exit code of kill, i.e. the expected 1 when there is no such process

which is also wrong and looking at that, I see the test is wrong (I'm not the author :-)) in its assumption that 1 is okay - according to the abovementioned guidelines:

"In addition to straightforward success, the following situations are also to be considered successful:

* running stop on a service already stopped or not running"


- so 0 should be returned and expected

looking into initscript functions how does the status routine handle the pidfile vs running process, I guess we may get some inspiration and not call kill at all  (and return 0) if dead already by using a test like this

[ -d /proc/$MYSQLPID ]

Comment 5 Honza Horak 2013-08-12 14:37:49 UTC
(In reply to Karel Volný from comment #3)
> so there is the false assumption that it fails due to insufficient
> permissions and it changes the ret variable, which contained the exit code
> of kill, i.e. the expected 1 when there is no such process
> 
> which is also wrong and looking at that, I see the test is wrong (I'm not
> the author :-)) in its assumption that 1 is okay - according to the
> abovementioned guidelines:
> 
> "In addition to straightforward success, the following situations are also
> to be considered successful:
> 
> * running stop on a service already stopped or not running"
> 
> - so 0 should be returned and expected

OK, agreed.

> looking into initscript functions how does the status routine handle the
> pidfile vs running process, I guess we may get some inspiration and not call
> kill at all  (and return 0) if dead already by using a test like this
> 
> [ -d /proc/$MYSQLPID ]

We can't just remove kill command itself since it actually stops daemon when running. However, additional check using proposed method [ -d /proc/$MYSQLPID ] should work fine, so this patch could help:

--- /etc/init.d/mysql55-mysqld.orig	2013-08-12 16:21:43.468917247 +0200
+++ /etc/init.d/mysql55-mysqld	2013-08-12 16:17:07.476880259 +0200
@@ -176,6 +176,11 @@ stop(){
 	fi
 	MYSQLPID=`cat "$mypidfile" 2>/dev/null`
 	if [ -n "$MYSQLPID" ]; then
+	    if ! [ -d "/proc/$MYSQLPID" ] ; then
+		# process doesn't run anymore
+		action $"Stopping $prog: " /bin/true
+		return 0
+	    fi
 	    /bin/kill "$MYSQLPID" >/dev/null 2>&1
 	    ret=$?
 	    if [ $ret -eq 0 ]; then

Comment 6 Karel Volný 2013-08-20 13:48:57 UTC
(In reply to Honza Horak from comment #5)
> (In reply to Karel Volný from comment #3)
> > looking into initscript functions how does the status routine handle the
> > pidfile vs running process, I guess we may get some inspiration and not call
> > kill at all  (and return 0) if dead already by using a test like this
> > 
> > [ -d /proc/$MYSQLPID ]
> 
> We can't just remove kill command itself
...

ahem, I haven't said to remove it but not to call it IF dead already :-)

> --- /etc/init.d/mysql55-mysqld.orig	2013-08-12 16:21:43.468917247 +0200
> +++ /etc/init.d/mysql55-mysqld	2013-08-12 16:17:07.476880259 +0200
> @@ -176,6 +176,11 @@ stop(){
>  	fi
>  	MYSQLPID=`cat "$mypidfile" 2>/dev/null`
>  	if [ -n "$MYSQLPID" ]; then
> +	    if ! [ -d "/proc/$MYSQLPID" ] ; then
> +		# process doesn't run anymore
> +		action $"Stopping $prog: " /bin/true
> +		return 0
> +	    fi
>  	    /bin/kill "$MYSQLPID" >/dev/null 2>&1
>  	    ret=$?
>  	    if [ $ret -eq 0 ]; then

looks good, IMO

Comment 11 errata-xmlrpc 2014-06-04 07:25:06 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2014-0612.html