mtransition.cxx

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         mtransition.cxx
00004   Created by:   Stefan Ritt and Konstantin Olchanski
00005 
00006   Contents:     Command-line interface to run state transitions
00007 
00008   $Id: mtransition.cxx 4514 2009-06-24 16:13:20Z olchanski $
00009 
00010 \********************************************************************/
00011 
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <ctype.h>
00016 #include <assert.h>
00017 
00018 #include "midas.h"
00019 
00020 /*------------------------------------------------------------------*/
00021 
00022 int read_state(HNDLE hDB)
00023 {
00024   /* check if run is stopped */
00025   int state = STATE_STOPPED;
00026   int size = sizeof(state);
00027   int status = db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, FALSE);
00028   assert(status == DB_SUCCESS);
00029   return state;
00030 }
00031 
00032 void usage()
00033 {
00034    fprintf(stderr, "Usage: mtransition [-v] [-d debug_flag] [-f] [-h Hostname] [-e Experiment] commands...\n");
00035    fprintf(stderr, "Options:\n");
00036    fprintf(stderr, "  -v - report activity\n");
00037    fprintf(stderr, "  -d debug_flag - passed through cm_transition(debug_flag): 0=normal, 1=printf, 2=cm_msg(MINFO)\n");
00038    fprintf(stderr, "  -f - force new state regardless of current state\n");
00039    fprintf(stderr, "  -h Hostname - connect to mserver on remote host\n");
00040    fprintf(stderr, "  -e Experiment - connect to non-default experiment\n");
00041    fprintf(stderr, "Commands:\n");
00042    fprintf(stderr, "  START [runno] - start a new run\n");
00043    fprintf(stderr, "  STOP - stop the run\n");
00044    fprintf(stderr, "  PAUSE - pause the run\n");
00045    fprintf(stderr, "  RESUME - resume the run\n");
00046    fprintf(stderr, "  STARTABORT - cleanup after failed START\n");
00047    fprintf(stderr, "  DELAY 100 - sleep for 100 seconds\n");
00048    fprintf(stderr, "  DELAY \"/logger/Auto restart delay\" - sleep for time specified in ODB variable\n");
00049    fprintf(stderr, "  IF \"/logger/Auto restart\" - continue only if ODB variable is set to TRUE\n");
00050    cm_set_msg_print(MT_ERROR, 0, NULL);
00051    cm_disconnect_experiment();
00052    exit (1);
00053 }
00054 
00055 int main(int argc, char *argv[])
00056 {
00057    int status;
00058    bool verbose = false;
00059    int debug_flag = 0;
00060    bool force = false;
00061    char host_name[HOST_NAME_LENGTH], exp_name[NAME_LENGTH];
00062 
00063    /* get default from environment */
00064    cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name));
00065 
00066    /* parse command line parameters */
00067 
00068    if (argc < 2)
00069       usage(); // does not return
00070 
00071    for (int i = 1; i < argc; i++) {
00072       if (argv[i][0] == '-') {
00073          if (argv[i][1] == 'v')
00074             verbose = true;
00075          else if (argv[i][1] == 'f')
00076             force = true;
00077          else if (argv[i][1] == 'd' && i < argc-1)
00078             debug_flag = strtoul(argv[++i], NULL, 0);
00079          else if (argv[i][1] == 'e' && i < argc-1)
00080             strlcpy(exp_name, argv[++i], sizeof(exp_name));
00081          else if (argv[i][1] == 'h' && i < argc-1)
00082             strlcpy(host_name, argv[++i], sizeof(host_name));
00083          else
00084             usage(); // does not return
00085          }
00086       }
00087 
00088    if (debug_flag)
00089       verbose = true;
00090    else if (verbose)
00091       debug_flag = 1;
00092 
00093    /* do not produce a startup message */
00094    cm_set_msg_print(MT_ERROR, 0, NULL);
00095 
00096    status = cm_connect_experiment1(host_name, exp_name, "mtransition", NULL,
00097                                    DEFAULT_ODB_SIZE,
00098                                    DEFAULT_WATCHDOG_TIMEOUT);
00099    if (status != CM_SUCCESS) {
00100       fprintf(stderr,"Error: Cannot connect to experiment \'%s\' on host \'%s\', status %d\n",
00101               exp_name,
00102               host_name,
00103               status);
00104       exit(1);
00105    }
00106 
00107    if (verbose)
00108       printf("Connected to experiment \'%s\' on host \'%s\'\n", exp_name, host_name);
00109 
00110    HNDLE hDB;
00111 
00112    status = cm_get_experiment_database(&hDB, NULL);
00113    assert(status == CM_SUCCESS);
00114 
00115    for (int i=1; i<argc; i++) {
00116 
00117       if (argv[i][0] == '-') {
00118         
00119          // skip command line switches
00120 
00121          if (argv[i][1] == 'd')
00122             i++;
00123          else if (argv[i][1] == 'h')
00124             i++;
00125          if (argv[i][1] == 'e')
00126             i++;
00127 
00128          continue;
00129 
00130       } else if (strcmp(argv[i], "START") == 0) {
00131 
00132          /* start */
00133 
00134          /* check if run is already started */
00135          int state = read_state(hDB);
00136 
00137          if (!force && state == STATE_RUNNING) {
00138             printf("START: Run is already started\n");
00139             cm_set_msg_print(MT_ERROR, 0, NULL);
00140             cm_disconnect_experiment();
00141             exit(1);
00142          } else if (!force && state == STATE_PAUSED) {
00143             printf("START: Run is paused, please use \"RESUME\"\n");
00144             cm_set_msg_print(MT_ERROR, 0, NULL);
00145             cm_disconnect_experiment();
00146             exit(1);
00147          }
00148 
00149          /* get present run number */
00150          int old_run_number = 0;
00151          int size = sizeof(old_run_number);
00152          status = db_get_value(hDB, 0, "/Runinfo/Run number", &old_run_number, &size, TID_INT, FALSE);
00153          assert(status == DB_SUCCESS);
00154          assert(old_run_number >= 0);
00155 
00156          int new_run_number = old_run_number + 1;
00157 
00158          if (i+1 < argc) {
00159             if (isdigit(argv[i+1][0])) {
00160                new_run_number = atoi(argv[i+1]);
00161                i++;
00162             }
00163          }
00164 
00165          if (verbose)
00166             printf("Starting run %d\n", new_run_number);
00167 
00168          char str[256];
00169          status = cm_transition(TR_START, new_run_number, str, sizeof(str), SYNC, debug_flag);
00170          if (status != CM_SUCCESS) {
00171             /* in case of error, reset run number */
00172             status = db_set_value(hDB, 0, "/Runinfo/Run number", &old_run_number, sizeof(old_run_number), 1, TID_INT);
00173             assert(status == DB_SUCCESS);
00174 
00175             printf("START: cm_transition status %d, message \'%s\'\n", status, str);
00176          }
00177 
00178       } else if (strcmp(argv[i], "STOP") == 0) {
00179 
00180          /* check if run is stopped */
00181 
00182          int state = read_state(hDB);
00183 
00184          if (state == STATE_STOPPED) {
00185             printf("Run is already stopped, stopping again.\n");
00186          }
00187 
00188          char str[256];
00189          status = cm_transition(TR_STOP, 0, str, sizeof(str), SYNC, debug_flag);
00190 
00191          if (status != CM_SUCCESS)
00192             printf("STOP: cm_transition status %d, message \'%s\'\n", status, str);
00193 
00194       } else if (strcmp(argv[i], "PAUSE") == 0) {
00195 
00196          /* check if run is started */
00197 
00198          int state = read_state(hDB);
00199 
00200          if (!force && state == STATE_PAUSED) {
00201             printf("PAUSE: Run is already paused\n");
00202             continue;
00203          }
00204 
00205          if (state != STATE_RUNNING) {
00206             printf("PAUSE: Run is not started\n");
00207             cm_set_msg_print(MT_ERROR, 0, NULL);
00208             cm_disconnect_experiment();
00209             exit(1);
00210          }
00211 
00212          char str[256];
00213          status = cm_transition(TR_PAUSE, 0, str, sizeof(str), SYNC, debug_flag);
00214 
00215          if (status != CM_SUCCESS)
00216             printf("PAUSE: cm_transition status %d, message \'%s\'\n", status, str);
00217 
00218       } else if (strcmp(argv[i], "RESUME") == 0) {
00219 
00220          int state = read_state(hDB);
00221 
00222          if (!force && state == STATE_RUNNING) {
00223             printf("RESUME: Run is already running\n");
00224             continue;
00225          } else if (!force && state != STATE_PAUSED) {
00226             printf("RESUME: Run is not paused\n");
00227             cm_set_msg_print(MT_ERROR, 0, NULL);
00228             cm_disconnect_experiment();
00229             exit(1);
00230          }
00231 
00232          char str[256];
00233          status = cm_transition(TR_RESUME, 0, str, sizeof(str), SYNC, debug_flag);
00234          if (status != CM_SUCCESS)
00235             printf("RESUME: cm_transition status %d, message \'%s\'\n", status, str);
00236 
00237       } else if (strcmp(argv[i], "STARTABORT") == 0) {
00238 
00239          char str[256];
00240          status = cm_transition(TR_STARTABORT, 0, str, sizeof(str), SYNC, debug_flag);
00241          if (status != CM_SUCCESS)
00242             printf("STARTABORT: cm_transition status %d, message \'%s\'\n", status, str);
00243 
00244       } else if (strcmp(argv[i], "DELAY") == 0) {
00245 
00246          if (argv[i+1] == NULL) {
00247             fprintf(stderr,"Command DELAY requires an argument\n");
00248             usage(); // does not return
00249          }
00250 
00251          const char* arg = argv[++i];
00252          int delay = 0;
00253 
00254          if (isdigit(arg[0])) {
00255             delay = atoi(arg);
00256          } else if (arg[0] == '/') {
00257             int size = sizeof(delay);
00258             status = db_get_value(hDB, 0, arg, &delay, &size, TID_INT, FALSE);
00259             if (status !=  DB_SUCCESS) {
00260                fprintf(stderr,"DELAY: Cannot read ODB variable \'%s\', status %d\n", arg, status);
00261                cm_set_msg_print(MT_ERROR, 0, NULL);
00262                cm_disconnect_experiment();
00263                exit(1);
00264             }
00265          }
00266 
00267          if (verbose)
00268             printf("DELAY \'%s\' %d sec\n", arg, delay);
00269 
00270          status = ss_sleep(delay*1000);
00271          assert(status == SS_SUCCESS);
00272 
00273       } else if (strcmp(argv[i], "IF") == 0) {
00274 
00275          if (argv[i+1] == NULL) {
00276             fprintf(stderr,"Command IF requires an argument\n");
00277             usage(); // does not return
00278          }
00279 
00280          const char* arg = argv[++i];
00281          int value = 0;
00282 
00283          if (isdigit(arg[0])) {
00284             value = atoi(arg);
00285          } else if (arg[0] == '/') {
00286             int size = sizeof(value);
00287             status = db_get_value(hDB, 0, arg, &value, &size, TID_BOOL, FALSE);
00288             if (status ==  DB_TYPE_MISMATCH) {
00289                status = db_get_value(hDB, 0, arg, &value, &size, TID_INT, FALSE);
00290             }
00291             if (status !=  DB_SUCCESS) {
00292                fprintf(stderr,"IF: Cannot read ODB variable \'%s\', status %d\n", arg, status);
00293                cm_set_msg_print(MT_ERROR, 0, NULL);
00294                cm_disconnect_experiment();
00295                exit(1);
00296             }
00297          }
00298 
00299          if (verbose)
00300             printf("IF \'%s\' value %d\n", arg, value);
00301 
00302          if (!value) {
00303             cm_set_msg_print(MT_ERROR, 0, NULL);
00304             cm_disconnect_experiment();
00305             exit(0);
00306          }
00307 
00308       } else {
00309         
00310          fprintf(stderr,"Unknown command \'%s\'\n", argv[i]);
00311          usage(); // does not return
00312 
00313       }
00314    }
00315 
00316    /* do not produce a shutdown message */
00317    cm_set_msg_print(MT_ERROR, 0, NULL);
00318 
00319    cm_disconnect_experiment();
00320 
00321    return 0;
00322 }
00323 
00324 // end

Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk