Article
· Apr 14, 2021 3m read

Backup Freeze/Thaw batch script pitfalls for VMWare (and solutions)

Hey everyone.

I came across some issues when setting up Freeze and Thaw batch scripts for use with VMWare in a Windows ecosystem, and I wanted to share what I found in the hopes it can help others. This was undertaken in an environment using Healthconnect 2019.1.x.

IRIS not up (2)

It seems that the sample script from the documentation in my my case would tell me that the environment was not running (despite it running). To correct this, I provided the filepath to the Mgr location as so:

c:\InterSystems\HealthConnect\bin\irisdb -s"C:\InterSystems\HealthConnect\Mgr" -U%%SYS ##Class(Backup.General).ExternalFreeze() <C:\InterSystems\BackupScripts\login.scr

It could be because I had more than one installation of Healthconnect on this environment, however it persisted after an uninstall of the other instance and reboot.

Script Running

The second issue I faced was the getting the scripts to run when the backup was being taken. After some digging, I found that VMWare will run every script in the folder "C:\Program Files\VMware\VMware Tools\backupScripts.d" in alphabetical order passing in the command "freeze",  and then will run every script in reverse order using the command "thaw". In my case I needed to create this folder within the "VMWare Tools" directory.

To avoid managing multiple files and restricting what command can be run against them, I combined freeze and thaw into a single script, and added an if statement to the start of the single batch file to route to the freeze or thaw:

if "%1" == "freeze" goto doFreeze
if "%1" == "thaw" goto doThaw

Script Errorlevels

If the freeze is successful, irisdb.exe will return the errorlevel as 5. However, VMWare (and some others) will read a non-zero return as an error. Therefore, I needed to overwrite the exitcode depending on the errorlevel returned as it otherwise stops the quiescent backup running:

:FreezeOK
echo SYSTEM IS FROZEN
rem Error levels from freeze do not match standard convention, so we return 0 when successful.
EXIT /b 0

:FreezeFAIL
echo SYSTEM FREEZE FAILED
EXIT /b 1

note: I used 1 for the error purely because it was non-zero.

Final result

Putting this all together has given me the following:

@echo off
rem VMTools should pass in either freeze or thaw.
if "%1" == "freeze" goto doFreeze
if "%1" == "thaw" goto doThaw

echo Nothing Matched. Exiting...
EXIT /b

:doFreeze
rem Call external freeze and provide credential file stored in separate folder.
c:\InterSystems\HealthConnect\bin\irisdb -s"C:\InterSystems\HealthConnect\Mgr" -U%%SYS ##Class(Backup.General).ExternalFreeze() <C:\InterSystems\BackupScripts\login.scr
rem note that we need to check errorlevel from highest to lowest here....
if errorlevel 5 goto FreezeOK
if errorlevel 3 goto FreezeFAIL
rem If here, errorlevel did not match an expected output.
rem Assume Failure.
echo errorlevel returned unexpected value
goto FreezeFAIL

:FreezeOK
echo SYSTEM IS FROZEN
rem Error levels from freeze do not match standard convention, so we return 0 when successful.
EXIT /b 0

:FreezeFAIL
echo SYSTEM FREEZE FAILED
EXIT /b 1

:doThaw
c:\InterSystems\HealthConnect\bin\irisdb -s"C:\InterSystems\HealthConnect\Mgr" -U%%SYS ##Class(Backup.General).ExternalThaw()
EXIT /b 0

Improvements/Next steps

The doThaw block is pretty weak as it assumes success, and this could be a good opportunity to write to a log and record any failures. In addition, I will be adding in a call to ##Class(Backup.General).ExternalSetHistory() to ensure that the environment correctly records when backups have been taken and trigger journal purges.

Discussion (2)1
Log in or sign up to continue

Just as a little addition to this.

Be careful when implementing the ##Class(Backup.General).ExternalSetHistory() and then running the script independent to actually taking backups from your external system.

Default journal retention is usually 2 days OR 2 backups. If this is called a few times without a backup, you will have effectively deleted your journals past the point of your most recent backup.

It's been a short while since I threw this together, and I ended up adding in two important changes.

  1. OS Authentication
  2. Use of ##Class(Backup.General).ExternalSetHistory()

As Global Masters reminded me of this post, I thought I should at least update it with the latest version:

@echo off
rem VMTools should pass in either freeze or thaw.
if "%1" == "freeze" goto doFreeze
if "%1" == "thaw" goto doThaw
echo.
echo Nothing Matched. Exiting...
EXIT /b

:doFreeze
rem Call external freeze. OS Authentication negates need for login credentials.
c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalFreeze()
echo.
echo.
rem Check errorlevel from highest to lowest here.
if errorlevel 5 goto FreezeOK
if errorlevel 3 goto FreezeFAIL

rem If here, errorlevel did not match an expected output.
rem Assume Failure.
echo errorlevel returned unexpected value
goto FreezeFAIL

:FreezeOK
echo SYSTEM IS FROZEN
rem Error levels from freeze do not match standard convention, so we return 0 when successful.
EXIT /b 0

:FreezeFAIL
echo SYSTEM FREEZE FAILED
EXIT /b 1

:doThaw
c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalThaw()
echo.
echo SYSTEM IS THAWED
echo.
c:\InterSystems\HealthShare\bin\irisdb -s"C:\InterSystems\HealthShare\Mgr" -U%%SYS ##Class(Backup.General).ExternalSetHistory()
echo.
echo BACKUP RECORDED
EXIT /b 0