Autosave/restore -- save_restore.c v3.2; dbrestore.c v3.01 This software automatically saves the values of EPICS process variables (PVs), to files on a server, and can automatically restore those values when the VME crate is rebooted. The original author is Bob Dalesio; I made a few improvements; Frank Lenkszus made some more improvements, which I folded into the version I've been maintaining. A bunch of people contributed to getting the software running on PPC hardware, including Ron Sluiter, Andrew Johnson, and Pete Jemian (APS), Markus Janousch and David Maden (SLS), and I'm not sure who else. Mark Rivers fixed some long-standing bugs in the saving of floats and doubles. Contents ======== save_restore.c -- saves PV values in files on a file server, according to preset rules. dbrestore.c -- restore PV values at boot time, using dbStaticLib initHooks.c -- call restore routines at the correct time during boot. fGetDateStr.c -- Frank Lenkszus' date-string routines save_restore.h -- header fGetDateStr.h -- header auto_settings.req -- Sample request files auto_positions.req reqInclude.tar -- collection of autosave-request files with parameterized PV names (e.g., "$(P)$(T).PREC") intended to be included in auto_settings.req. Differences from previous versions ================================== save_restore v3.2; dbrestore v3.01: ---------------------------------- Previous versions did not reliably save non-local float and double PV values under EPICS 3.14 save_restore v2.9a; dbrestore v2.7: ---------------------------------- Previously, create_data_set() would return without releasing a semaphore (causing the save_restore task to hang) if called with save_method==TRIGGERED, but no trigger channel was specified. Previously, fdbrestore() would return without releasing a semaphore (causing the save_restore task to hang) if called with the name of a save set currently being maintained, and the save list contained unconnected PV's, and the variable 'sr_restore_incomplete_sets_ok' was false. Added macro-string argument to create_xxx_set() Added argument 'verbose' to fdblist() Added second argument, 'subpath', to set_XXXfile_path(). This allows the caller to pass the path as two args to be concatenated, making it easier to build the path string using a variable set in the cdCommands file. Use logMsg() instead of epicsPrintf() for several informational messages. The variables chlist and reqFilePathList are now private. Increased ca_pend_io search timeout in connect_list() from 2 to 5 seconds. Decreased fetch timeout from num_channels/10 to 10 seconds. Decreased ca_pend_io clear-channel timeout from num_channels/10 to 10 seconds in remove_data_set(). Changed call to macParseDefns() to specify the macro-substitution handle. save_restore v2.7; dbrestore v2.7: --------------------------------- ******************************************************************************* ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ******************************************************************************* This version is incompatible in one important respect with versions of save_restore.c numbered lower than 2.6: The functions create_periodic_set() create_monitor_set() reload_periodic_set() reload_monitor_set() now take 'int' arguments to specify time periods, instead of 'double' arguments. This change was required for compatibility with PPC processors. In Frank Lenkszus' version, the calls set_pass_restoreFile() were required to specify files to be restored. In this version, if no restore files have been specified, the code specifies the default files auto_positions.sav and auto_settings.sav for you, for backward compatibility with my previous version. If you really don't want to restore any files, you now must either not load initHooks, or replace it with your own version. In Frank Lenkszus' version, set_requestfile_path() could specify only a single directory. Now that include files are a possibility, you can specify several request-file directories by calling set_requestfile_path() several times. Backup files made as part of a restore operation (i.e., files ending in ".bu", or "YYMMDD-HHMMSS") are no longer created using the VxWorks "copy" command. How to use this software ======================== This software can be used in many different ways. I'll describe what you have to do to use it as it's used at APS beamlines to save PV values periodically, and restore them on reboot. *) Create "request" files (e.g., auto_settings.req, auto_positions.req) specifying the PVs whose values you want to save and restore. The save files corresponding to these request files will have the ".req" suffix replaced by ".sav". Request files can include other request files (nested includes are allowed) and macro substitution can be performed on the included files (using William Lupton's macro library), with the following syntax: file e.g., file xx_auto_motor_settings.req P=xxx:,M=m1 I've tried to defend against forseeable variations in syntax, so that include lines with embedded whitespace and/or quotes, macro strings without commas, empty macro strings, and lines with trailing comments will be parsed as one would want. Generally, quotes are ignored, whitespace implies a comma but otherwise is ignored, and everything after the second sequence of non-whitespace characters (i.e., after the file name) and before the (optional) comment character '#' is taken as the macro-substitution string. Macro substitution is performed on the entire line, so it's possible to parameterize names of included files, as well as PV names. It is also possible to define a macro that replaces its target with nothing. *) If the request files will not be in the crate's current working directory ("current", that is, at the time the restore commands are executed -- during iocInit), specify one or more directories to be searched for request files using one or more invocations of the function set_requestfile_path(), e.g., set_requestfile_path(startup, "") set_requestfile_path(std, "stdApp/Db") set_requestfile_path(motor, "motorApp/Db") ... *) Select the directory in which you want save files to be written. If this will not be the crate's current working directory at the time the files are written, execute the function set_savefile_path(), e.g., set_savefile_path(startup, "autosave") in your startup script, before the create_xxx_set() commands, to specify the path to the directory. If you are using NFS (recommended), ensure that the path does not contain symbolic links. In my experience, VxWorks cannot write to an NFS file through a symbolic link. (I don't understand all the ins and outs of this limitation.) *) Give the "crate" write permission to the directory in which the save files are to be written. If you forget this step, autoSaveRestore may be able to write save files, but the files will be corrupted because the crate will not be able to change their lengths. autoSaveRestore attempts to detect this condition, but cannot work around it if the file length must increase. *) Specify which save files are to be restored before record initialization (pass 0) and which are to be restored after record initialization (pass 1), using the commands set_pass0_restoreFile(), and set_pass1_restoreFile(), e.g., set_pass0_restoreFile("auto_positions.sav") set_pass0_restoreFile("auto_settings.sav") set_pass1_restoreFile("auto_settings.sav") Place these commands in the startup file before iocInit. If you don't call either of these functions (or if your calls fail completely to specify any restore files) the supplied initHooks routine will attempt to restore the file "auto_positions.sav" before record init, and the file "auto_settings.sav" both before and after record init. Notes: Link fields cannot be restored (by dbStatic calls) after record initialization. If you want save/restore to work for link fields you must specify them in a pass-0 file. It is not an error to specify link fields in a pass-1 file, but this software will not try to restore them. Device support code for the motor record uses the value of the field DVAL, restored during pass 0, only if the value read from the hardware is zero. If the value from hardware is nonzero, it is used instead of the restored value. *) At boot time, the restore software writes a backup copy of the ".sav" file from which it restored PV's. This file can either be named xxx.bu, and be rewritten every reboot, or named xxxYYMMDD-HHMMSS, where "YY..." is a date. Dated backups are not overwritten. If you want dated backup files (recommended), set reboot_restoreDatedBU = 1 in the startup file before iocInit. Note: If a save file is restored in both pass 0 and pass 1, the backup file will be written only during pass 0. *) Invoke the "save" part of this software as part of the EPICS startup sequence, by adding lines of the form create_monitor_set("auto_positions.req",5,"P=xxx:") create_monitor_set("auto_settings.req",30,"P=xxx:") to the end of your EPICS startup file. You can call the files anything you want. For each "create_monitor_set(.req,