Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gbak isn't returning exit code about errors when using service manager (-se) [CORE5520] #5789

Open
firebird-automations opened this issue Apr 13, 2017 · 10 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Beto Neto (betoneto.tbo)

Votes: 2

I'm trying to restore a corrupted backup file.
My shell script takes care about this process using the gbak, and analyzes the exit code from it.

Without using the "-se" option, everything goes ok!

gbak \-c corrupted\.fbk restore\.fdb \-user sysdba \-password masterkey \-v
echo %errorcode%

This command will print "2".

But, when I run the restore with the service manager option it doesn't returns the error code:

gbak \-c corrupted\.fbk restore\.fdb \-user sysdba \-password masterkey \-v \-se 127\.0\.0\.1/3050:service\_mgr
echo %errorcode%

This command will print "0"

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Works for me - may be it's windows specific issue?

localhost bin #⁠ ./gbak -rep `pwd`/gbak.corr tmp -user sysdba -password masterkey -v -se 127.0.0.1/3050:service_mgr
gbak:opened file /opt/firebird.CS.2.5/bin/gbak.corr
gbak:transportable backup -- data in XDR format
gbak: backup file is compressed
gbak:created database tmp, page_size 4096 bytes
gbak:started transaction
gbak:restoring domain FIRSTNAME
...........
gbak:restoring domain DEPTNO
gbak: ERROR:do not recognize record type 0
gbak: ERROR: Exiting before completion due to errors
gbak:Exiting before completion due to errors
localhost bin #⁠ echo $?
1
localhost bin #⁠ ./gbak -z
gbak:gbak version LI-V2.5.7.27037 Firebird 2.5

@firebird-automations
Copy link
Collaborator Author

Commented by: Beto Neto (betoneto.tbo)

Try to simulate with this backup:

https://drive.google.com/drive/folders/0B-qEIYAtH5uPcW9OV3RzMTlPc28?usp=sharing

@firebird-automations
Copy link
Collaborator Author

Commented by: Hans Thielen (hansthielen)

If you restore a database and deny access to the restore.log, you got the same behaviour, i.e.:

e:\Dbs>"C:\Program Files\Firebird\Firebird_2_5\bin\GBAK" -REP -v -y Restore.log -user sysdba -pas masterkey WORK.GBK WORK.GDB -se service_mgr
gbak:cannot open status and error output file .\Restore.log
e:\Dbs>echo %errorlevel%
0

e:\Dbs>"C:\Program Files\Firebird\Firebird_2_5\bin\GBAK" -REP -v -y Restore.log -user sysdba -pas masterkey WORK.GBK WORK.GDB
gbak:cannot open status and error output file .\Restore.log
e:\Dbs>echo %errorlevel%
1

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

> If you restore a database and deny access to the restore.log ...

OFFTOP.

IMO it is wrong way to assume that logs for storing STDOUT & STDERR results should be always avaliable.
At least one of them can be opened by some viewer (for example, in Far Manager, open any file by pressing F3 key) - and you will not be able to drop this file for new writing in it.

So, the first thing your script (.bat) should do is get ensurance that both logs can be:
1) created
2) dropped.

One may to do that by using following scratch:

@echo off
setlocal enabledelayedexpansion enableextensions

set logdir=c:\temp\gbak-results
set logname=tmpc5520.log
set errname=tmpc5520.err

if exist %logdir%\nul (

@rem Dir "%logdir%" DOES exist\.

set fc=0
set fd=0

for /f %%a in \('copy %\~dp0\\nul %logdir%\\%errname% 2^\>nul ^\| findstr /c:"1"'\) do \(
    set fc=1
\)
if \!fc\! equ 0 \(
    echo Can not CREATE empty "%logdir%\\%errname%" \- file for storing STDERR results\.
    echo Perhaps it is opened by another process or you have access rghts problem\.
    goto final
\)

if \!fc\! equ 1 \(
    del %logdir%\\%errname%
    if NOT exist %logdir%\\%errname% set fd=1
\)

if \!fd\! equ 0 \(
    echo Can not REMOVE "%logdir%\\%errname%" \- file for storing STDOUT results\.
    echo Perhaps it is opened by another process or you have access rghts problem\.
    goto final
\)


set fc=0
set fd=0

for /f %%a in \('copy %\~dp0\\nul %logdir%\\%logname% 2^\>nul ^\| findstr /c:"1"'\) do \(
    set fc=1
\)
if \!fc\! equ 0 \(
    echo Can not CREATE empty "%logdir%\\%logname%" \- file for storing STDOUT results\.
    echo Perhaps it is opened by another process or you have access rghts problem\.
    goto final
\)

if \!fc\! equ 1 \(
    del %logdir%\\%logname%
    if NOT exist %logdir%\\%logname% set fd=1
\)

if \!fd\! equ 0 \(
    echo Can not REMOVE "%logdir%\\%logname%" \- file for storing STDOUT results\.
    echo Perhaps it is opened by another process or you have access rghts problem\.
    goto final
\)

) else (
echo Dir "%logdir%" does NOT exist. Can not proceeed anything.
goto final
)

echo Check access to directory and STDOUT and STDERR logs passed OK.

@Rem -------------- here we can start gbak ---------------------------

:final

As of gbak results you may need redirect BOTH stdout and stderr to the same file.
After backup/restore will finish, you can open this log and look there for string "gbak: ERROR:".
If this text will be found then your backup failed:

set host=localhost
set port=3400
set srcfdb=C:\temp\some_broken_database.fdb
set tgtfbk=C:\temp\foo.fbk

gbak -se %host%/%port%:service_mgr -rep %srcfdb% %tgtfbk% 1>c:\temp\backup-results.log 2>&1
findstr /m /b /i /c:"gbak: ERROR:" c:\temp\backup-results.log >nul
if NOT errorlevel 1 (
echo . . . ACHTUNG. . . BACKUP FINISHED ABNORMALLY . . . CHECK ITS LOG. . .
) else (
echo Backup finished without errors.
)

@firebird-automations
Copy link
Collaborator Author

Commented by: Hans Thielen (hansthielen)

>> If you restore a database and deny access to the restore.log ...
>
>OFFTOP.

I just wanted to create a reproduceable error.

> ...After backup/restore will finish, you can open this log and look there for string "gbak: ERROR:".

Ahh, that was cool 1982... (maybe)
I expect an exe to behave like this:
"All right" -> %errorlevel% = 0
"Something failed" -> %errorlevel% != 0
The -se switch must not have any influence on that behaviour.

@firebird-automations
Copy link
Collaborator Author

Commented by: Beto Neto (betoneto.tbo)

> I expect an exe to behave like this:
> "All right" -> %errorlevel% = 0
> "Something failed" -> %errorlevel% != 0
> The -se switch must not have any influence on that behaviour.

+1

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

Still can't understand: why priority of this ticket is "Critical" ? IMO workaround (check access rights for logs and parse them after gbak will finish) is not too hard to be implemented...

@firebird-automations
Copy link
Collaborator Author

Commented by: Hans Thielen (hansthielen)

A "global" try catch is also not too hard to implement?!

Maybe it is not a critical bug, I did not prioritize this ticket. Anyway I think it is critical to suggest workarounds to cover up the deficiency of the software instead of just fixing it.

@firebird-automations
Copy link
Collaborator Author

Modified by: @dyemanov

priority: Critical [ 2 ] => Major [ 3 ]

@firebird-automations
Copy link
Collaborator Author

Commented by: Beto Neto (betoneto.tbo)

I think this maybe isn't critical, but is out of standars.

I have created an updater for my application, as it primary step it executes an backup and restore of the database to garantee database consistence.

I was assuming blindly that the gbak exit code was following the standards, "a utility must return an exit code different of zero when errors occurs".

As a workaround I must now catch the syserr and everything printed on it will signal an "exit error code". I hope with this solution I do not have any new surprises, like "error messages printed in sysout".

Please fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant