MIDAS
Loading...
Searching...
No Matches
lazylogger.cxx
Go to the documentation of this file.
1/********************************************************************\
2Name: lazylogger.c
3Created by: Pierre-Andre Amaudruz
4
5Contents: Disk to Tape copier for background job.
6
7$Id$
8
9\********************************************************************/
10
11#undef NDEBUG // midas required assert() to be always enabled
12
13#include "midas.h"
14#include "msystem.h"
15#include "mstrlcpy.h"
16
17#ifdef HAVE_FTPLIB
18
19#include "ftplib.h"
20
21#endif
22
23#include <libgen.h> // basename()
24#include <mutex>
25#include <iostream>
26
27#ifdef HAVE_CURL
28#include <curl/curl.h>
29#endif
30
31#define URL_SIZE 256
32
33#include "mdsupport.h"
34#include <assert.h>
35
36#include <vector>
37#include <string>
38#include <algorithm>
39
40#define NOTHING_TODO 0
41#define FORCE_EXIT 1
42#define EXIT_REQUEST 2
43#define TRY_LATER 3
44
45#define NEW_FILE 1
46#define REMOVE_FILE 2
47#define REMOVE_ENTRY 3
48#define MAX_LAZY_CHANNEL 100
49#define TRACE
50#define LOG_TYPE_SCRIPT (-1)
51#define DONTOPENZIP 0
52
55
56typedef struct {
57 std::string filename;
59 double size;
60} DIRLOG;
61
62typedef std::vector<DIRLOG> DIRLOGLIST;
63
64bool cmp_dirlog1(const DIRLOG &a, const DIRLOG &b) {
65 if (a.runno < b.runno)
66 return true;
67
68 if (a.runno > b.runno)
69 return false;
70
71 const char *sa = a.filename.c_str();
72 const char *sb = b.filename.c_str();
73
74 while (1) {
75 if (*sa == 0) // sa is shorter
76 return true;
77
78 if (*sb == 0) // sb is shorter
79 return false;
80
81 //printf("cmp char %c %c\n", *sa, *sb);
82
83 if (*sa < *sb)
84 return true;
85
86 if (*sa > *sb)
87 return false;
88
89 // at this point, *sa == *sb
90
91 if (isdigit(*sa)) {
92 int ia = strtoul(sa, (char **) &sa, 10);
93 int ib = strtoul(sb, (char **) &sb, 10);
94
95 //printf("cmp int %d %d\n", ia, ib);
96
97 if (ia < ib)
98 return true;
99
100 if (ia > ib)
101 return false;
102
103 // at this point, ia == ib
104 continue;
105 }
106
107 sa++;
108 sb++;
109 }
110}
111
112bool cmp_dirlog(const DIRLOG &a, const DIRLOG &b) {
113 bool r = cmp_dirlog1(a, b);
114 //printf("compare %s %s yields %d\n", a.filename.c_str(), b.filename.c_str(), r);
115 return r;
116}
117
118#ifndef MAX_FILE_PATH
119#define MAX_FILE_PATH 128 // must match value of 128 in LAZY_SETTINGS_STRING
120#endif
121
122#define LAZY_SETTINGS_STRING "\
123Period = INT : 10\n\
124Maintain free space (%) = INT : 0\n\
125Stay behind = INT : 0\n\
126Alarm Class = STRING : [32]\n\
127Running condition = STRING : [128] ALWAYS\n\
128Data dir = STRING : [256] \n\
129Data format = STRING : [8] MIDAS\n\
130Filename format = STRING : [128] run%05d.mid\n\
131Backup type = STRING : [8] Tape\n\
132Execute after rewind = STRING : [64]\n\
133Path = STRING : [128] \n\
134Capacity (Bytes) = FLOAT : 5e9\n\
135List label= STRING : [128] \n\
136Execute before writing file = STRING : [64]\n\
137Execute after writing file = STRING : [64]\n\
138Modulo.Position = STRING : [8]\n\
139Copy Delay = INT : 0\n\
140Tape Data Append = BOOL : y\n\
141"
142#define LAZY_STATISTICS_STRING "\
143Backup file = STRING : [128] none \n\
144File size (Bytes) = DOUBLE : 0.0\n\
145KBytes copied = DOUBLE : 0.0\n\
146Total Bytes copied = DOUBLE : 0.0\n\
147Copy progress (%) = DOUBLE : 0\n\
148Copy Rate (Bytes per s) = DOUBLE : 0\n\
149Backup status (%) = DOUBLE : 0\n\
150Number of Files = INT : 0\n\
151Current Lazy run = INT : 0\n\
152"
153
154typedef struct {
155 INT period; /* time dela in lazy_main */
156 INT pupercent; /* 0:100 % of disk space to keep free */
157 INT staybehind; /* keep x run file between current Acq and backup
158 -x same as x but starting from oldest */
159 char alarm[32]; /* Alarm Class */
160 char condition[128]; /* key condition */
161 char dir[256]; /* path to the data dir */
162 char format[8]; /* Data format (MIDAS) */
163 char backfmt[MAX_FILE_PATH]; /* format for the run files run%05d.mid */
164 char type[8]; /* Backup device type (Disk, Tape, Ftp, Script) */
165 char command[64]; /* command to run after rewind */
166 char path[MAX_FILE_PATH]; /* backup device name */
167 float capacity; /* backup device max byte size */
168 char backlabel[MAX_FILE_PATH]; /* label of the array in ~/list. if empty like active = 0 */
169 char commandBefore[64]; /* command to run Before writing a file */
170 char commandAfter[64]; /* command to run After writing a file */
171 char modulo[8]; /* Modulo for multiple lazy client */
172 INT copy_delay; /* Delay copy after STOP transition in seconds */
173 BOOL tapeAppend; /* Flag for appending data to the Tape */
176
177typedef struct {
178 char backfile[MAX_FILE_PATH]; /* current or last lazy file done (for info only) */
179 double file_size; /* file size in bytes */
180 double cur_size; /* current bytes copied */
181 double cur_dev_size; /* Total bytes backup on device */
182 double progress; /* copy % */
183 double copy_rate; /* copy rate Kb/s */
184 double bckfill; /* backup fill % */
185 INT nfiles; /* # of backuped files */
186 INT cur_run; /* current or last lazy run number done (for info only) */
189
190typedef struct {
193 char name[32];
194} LAZY_INFO;
195
197
199
200/* Globals */
203double lastsz;
216
217#define WATCHDOG_TIMEOUT 60000 /* 60 sec for tape access */
218
219/* prototypes */
221
222BOOL lazy_file_exists(char *dir, char *file);
223
225
226INT lazy_copy(char *dev, char *file, int max_event_size);
227
229
230INT build_log_list(const char *fmt, const char *dir, DIRLOGLIST *plog);
231
233
235
237
239 for (unsigned i = 0; i < dirlog->size(); i++)
240 printf("%d: %s, run %d, size %12.0f\n",
241 i,
242 (*dirlog)[i].filename.c_str(),
243 (*dirlog)[i].runno,
244 (*dirlog)[i].size);
245};
246
247// STOP Transition callback
248INT lazy_trstop(INT rn, char *error) {
249 printf("lazy has detected a STOP transition\n");
251 return CM_SUCCESS;
252}
253
254/*------------------------------------------------------------------*/
256/********************************************************************\
257Routine: lazy_run_extract
258Purpose: extract the contigious digit at the right side from the
259string to make up a run number.
260Input:
261char * name string to search
262Output:
263Function value:
264INT run number
2650 if no extraction
266\********************************************************************/
267{
268#if 0
269 char run_str[256];
270 int j;
271
272 mstrlcpy(run_str, name, sizeof(run_str));
273 if (strlen(run_str) < 2)
274 return 0;
275
276 for (j = strlen(run_str) - 1; j >= 0 && !isdigit(run_str[j]); j--)
277 run_str[j] = 0;
278
279 for (j = strlen(run_str) - 1; j >= 0 && isdigit(run_str[j]); j--);
280
281 return atoi(run_str + j + 1);
282#endif
283
284 while (*name && !isdigit(*name))
285 name++;
286
287 if (*name == 0)
288 return 0;
289
290 return atoi(name);
291}
292
293/*------------------------------------------------------------------*/
296
297 if (nodelete) {
298 printf("lazy_file_remove: running in nodelete mode (-n switch), will not remove \'%s\'\n", pufile);
299 return !SS_SUCCESS;
300 }
301
302 /* open device */
303 fHandle = open(pufile, O_RDONLY, 0644);
304 if (fHandle == -1)
305 return SS_INVALID_NAME;
306
307 close(fHandle);
308
309 status = ss_file_remove((char *) pufile);
310 if (status != 0)
311 return SS_FILE_ERROR;
312 return SS_SUCCESS;
313}
314
315/*------------------------------------------------------------------*/
316INT lazy_log_update(INT action, INT run, const char *label, const char *file, DWORD perf_time) {
317 char str[1024];
318
319 strcpy(str, "no action");
320
321 /* log Lazy logger to midas.log only */
322 if (action == NEW_FILE) {
323 /* keep track of number of file on that channel */
324 lazyst.nfiles++;
325
326 if (equal_ustring(lazy.type, "FTP"))
327 sprintf(str, "%s[%i]: (cp:%.1fs) %s %1.3lfMB file COPIED",
328 label, lazyst.nfiles, (double) perf_time / 1000., lazyst.backfile, lazyst.file_size / 1024.0 / 1024.0);
329 else if (equal_ustring(lazy.type, "SFTP"))
330 sprintf(str, "%s[%i]: (cp:%.1fs) %s %1.3lfMB file COPIED",
331 label, lazyst.nfiles, (double) perf_time / 1000., lazyst.backfile, lazyst.file_size / 1024.0 / 1024.0);
332 else if (equal_ustring(lazy.type, "Script")) {
333 sprintf(str, "%s[%i]: (cp:%.1fs) %s %1.3lfMB file NEW",
334 label, lazyst.nfiles, (double) perf_time / 1000., lazyst.backfile, lazyst.file_size / 1024.0 / 1024.0);
335 } else if (equal_ustring(lazy.type, "Disk")) {
336 if (lazy.path[0] != 0)
337 if (lazy.path[strlen(lazy.path) - 1] != DIR_SEPARATOR)
339 sprintf(str, "%s[%i]: (cp:%.1fs) %s%s %1.3lfMB file NEW",
340 label, lazyst.nfiles, (double) perf_time / 1000.,
341 lazy.path, lazyst.backfile, lazyst.file_size / 1024.0 / 1024.0);
342 } else if (equal_ustring(lazy.type, "Tape")) {
343 /* June 2002, use variable blockn from the real tape position */
344 sprintf(str, "%s[%i]: (cp:%.1fs) %s/%s %1.3lfMB file NEW (position at block %d)",
345 label, lazyst.nfiles, (double) perf_time / 1000.,
346 lazy.path, lazyst.backfile, lazyst.file_size / 1024.0 / 1024.0, blockn);
347 if (lazy.commandAfter[0]) {
348 char cmd[1024];
349 sprintf(cmd, "%s %s %i %s/%s %1.3lf %d", lazy.commandAfter,
351 lazyst.file_size / 1024.0 / 1024.0, blockn);
352 cm_msg(MINFO, "Lazy", "Exec post file write script:%s", cmd);
353 ss_system(cmd);
354 }
355 }
356 } else if (action == REMOVE_FILE)
357 sprintf(str, "%i (rm:%dms) %s file REMOVED", run, perf_time, file);
358
359 else if (action == REMOVE_ENTRY)
360 sprintf(str, "%s run#%i entry REMOVED", label, run);
361
362 /* Now add this info to a special log file */
363 cm_msg1(MINFO, "lazy", "lazy_log_update", "%s", str);
364
365 return 0;
366}
367
368/*------------------------------------------------------------------*/
370/********************************************************************\
371Routine: moduleCheck
372Purpose: return valid run number in case of Modulo function enabled
373or zero if not.
374Input:
375lModulo : number of lazy channel
376lPosition : Position of the current channel
377lrun : current run to test
378Function value:
379valid run number (0=skip run)
380\********************************************************************/
381{
382 if (lModulo) {
383 if ((lrun % lModulo) == lPosition)
384 return lrun;
385 else
386 return 0;
387 } else
388 return lrun;
389}
390
391/*------------------------------------------------------------------*/
392INT build_log_list(const char *fmt, const char *xdir, DIRLOGLIST *dlist)
393/********************************************************************\
394Routine: build_log_list
395Purpose: build an internal directory file list from the disk directory
396Input:
397* fmt format of the file to search for (ie:run%05d.ybs)
398* dir path to the directory for the search
399Output:
400**plog internal file list struct
401Function value:
402number of elements
403\********************************************************************/
404{
405 char str[MAX_FILE_PATH];
406 char dir[MAX_FILE_PATH];
407 char *dot;
408 int lModulo = 0, lPosition = 0;
409
410 mstrlcpy(dir, xdir, sizeof(dir));
411
412 while (fmt) {
413 /* substitue %xx by * */
414 mstrlcpy(str, fmt, sizeof(str));
415
416 fmt = strchr(fmt, ',');
417 if (fmt)
418 fmt++;
419
420 char *s = strchr(str, ',');
421 if (s)
422 *s = 0;
423
424 if (strchr(str, '%')) {
425 *strchr(str, '%') = '*';
426 if (strchr(str, '.'))
427 strcpy((strchr(str, '*') + 1), strchr(str, '.'));
428 }
429
430 char *list = NULL;
431
432 /* create dir listing with given criteria */
433 int nfile = ss_file_find(dir, str, &list);
434
435 /* check */
436 /*
437 for (j=0;j<nfile;j++)
438 printf ("list[%i]:%s\n",j, list+j*MAX_STRING_LENGTH);
439 */
440
441 std::vector<std::string> flist;
442 for (int j = 0; j < nfile; j++)
443 flist.push_back(list + j * MAX_STRING_LENGTH);
444
445 free(list);
446
447 /* Check Modulo option */
448 if (lazy.modulo[0]) {
449 /* Modulo enabled, extract modulo and position */
450 dot = strchr(lazy.modulo, '.');
451 if (dot) {
452 *dot = '\0';
454 lPosition = atoi(dot + 1);
455 *dot = '.';
456 }
457 }
458
459 /* fill structure */
460 for (unsigned j = 0 ; j < flist.size(); j++) {
461 INT lrun;
462 /* extract run number */
463 lrun = lazy_run_extract((char *) flist[j].c_str());
464 /* apply the modulo if enabled */
466 /* if modulo enable skip */
467 if (lrun == 0)
468 continue;
469
470 std::string s = dir;
471 s += flist[j];
472
473 DIRLOG d;
474 d.filename = flist[j];
475 d.runno = lrun;
476 d.size = ss_file_size((char *) s.c_str());
477
478 dlist->push_back(d);
479 }
480 }
481
482 sort(dlist->begin(), dlist->end(), cmp_dirlog);
483
484 return dlist->size();
485}
486
487/*------------------------------------------------------------------*/
489/********************************************************************\
490Routine: build_done_list
491Purpose: build a sorted internal /lazy/list list (pdo) tree.
492Input:
493HNDLE Key of the Lazy channel
494**pdo /lazy_xxx/list run listing
495Output:
496**pdo /lazy_xxx/list run listing
497Function value: number of elements
498\********************************************************************/
499{
501 KEY key;
502 INT i, j, size, tot_nelement, nelement, temp;
503
504 if (db_find_key(hDB, hLch, "List", &hKey) != DB_SUCCESS) {
505 return 0;
506 }
507
508 tot_nelement = 0;
509 for (i = 0;; i++) {
511 if (!hSubkey)
512 break;
515 *pdo = (INT *) realloc(*pdo, sizeof(INT) * (tot_nelement + nelement));
516 size = nelement * sizeof(INT);
517 db_get_data(hDB, hSubkey, (char *) (*pdo + tot_nelement), &size, TID_INT);
519 }
520
521 if (0) {
522 printf("read pdo: %d\n", tot_nelement);
523 for (i = 0; i < tot_nelement; i++)
524 printf("%d: %d\n", i, (*pdo)[i]);
525 }
526
527 /* expand compressed run numbers */
528 for (i = 0; i < tot_nelement; i++)
529 if ((*pdo)[i] < 0) {
530 int first = (*pdo)[i - 1];
531 int last = -(*pdo)[i];
532 int nruns = last - first + 1;
533 assert(nruns > 1);
534
535 *pdo = (INT *) realloc(*pdo, sizeof(INT) * (tot_nelement + nruns - 2));
536 assert(*pdo != NULL);
537
538 memmove((*pdo) + i + nruns - 1, (*pdo) + i + 1, sizeof(INT) * (tot_nelement - i - 1));
539
540 for (j = 1; j < nruns; j++)
541 (*pdo)[i + j - 1] = first + j;
542
543 tot_nelement += nruns - 2;
544 }
545
546 if (0) {
547 printf("uncompressed pdo: %d\n", tot_nelement);
548 for (i = 0; i < tot_nelement; i++)
549 printf("%d: %d\n", i, (*pdo)[i]);
550 }
551
552 /* sort array of integers */
553 for (j = 0; j < tot_nelement - 1; j++) {
554 for (i = j + 1; i < tot_nelement; i++) {
555 if (*(*pdo + j) > *(*pdo + i)) {
556 memcpy(&temp, (*pdo + i), sizeof(INT));
557 memcpy((*pdo + i), (*pdo + j), sizeof(INT));
558 memcpy((*pdo + j), &temp, sizeof(INT));
559 }
560 }
561 }
562
563 if (0) {
564 printf("sorted pdo: %d\n", tot_nelement);
565 for (i = 0; i < tot_nelement; i++)
566 printf(" %d\n", (*pdo)[i]);
567 }
568
569 return tot_nelement;
570}
571
572std::string list_filename(const char *lazyname, const char *listname) {
573 std::string s(cm_get_path());
574 s += ".Lazy_";
575 s += lazyname;
576 s += ".";
577 s += listname;
578 return s;
579}
580
582 FILE *fp = fopen(list_filename(lazyname, "donelist").c_str(), "r");
583 if (!fp)
584 return;
585
586 while (1) {
587 char str[256];
588 char *s = fgets(str, sizeof(str), fp);
589 if (!s)
590 break;
591
592 DIRLOG d;
593
594 char *p = strchr(s, ' ');
595
596 if (p) {
597 *p = 0;
598 p++;
599 }
600
601 d.filename = s;
602 d.runno = strtoul(p, &p, 0);
603 d.size = strtod(p, &p);
604
605 bool found = false;
606 if (dirlist) {
607 for (unsigned i = 0; i < dirlist->size(); i++)
608 if ((*dirlist)[i].filename == d.filename) {
609 found = true;
610 break;
611 }
612 } else
613 found = true;
614
615 if (found)
616 dlist->push_back(d);
617 }
618
619 fclose(fp);
620
621 sort(dlist->begin(), dlist->end(), cmp_dirlog);
622}
623
624int save_list(const char *lazyname, const char *listname, const DIRLOGLIST *dlist) {
625 std::string fname = list_filename(lazyname, listname);
626 std::string tmpname = fname + ".tmp";
627
628 FILE *fp = fopen(tmpname.c_str(), "w");
629 if (!fp) {
630 cm_msg(MERROR, "save_list", "Cannot write to \'%s\', errno %d (%s)",
631 tmpname.c_str(),
632 errno,
633 strerror(errno));
634 return !SUCCESS;
635 }
636
637 for (unsigned i = 0; i < dlist->size(); i++) {
638 const char *s = (*dlist)[i].filename.c_str();
639 const char *p;
640 while ((p = strchr(s, DIR_SEPARATOR)))
641 s = p + 1;
642 fprintf(fp, "%s %d %12.0f\n",
643 s,
644 (*dlist)[i].runno,
645 (*dlist)[i].size);
646 }
647
648 fclose(fp);
649
650 int status = rename(tmpname.c_str(), fname.c_str());
651 if (status) {
652 cm_msg(MERROR, "save_list", "Cannot rename \'%s\' to \'%s\', errno %d (%s)",
653 tmpname.c_str(),
654 fname.c_str(),
655 errno,
656 strerror(errno));
657 return !SUCCESS;
658 }
659
660 return SUCCESS;
661}
662
663/*------------------------------------------------------------------*/
665/********************************************************************\
666Routine: convert_done_list
667Purpose: build a sorted internal /lazy/list list (pdo) tree.
668Input:
669HNDLE Key of the Lazy channel
670**pdo /lazy_xxx/list run listing
671Output:
672**pdo /lazy_xxx/list run listing
673Function value: number of elements
674\********************************************************************/
675{
677
679
680 KEY key;
681 int status = db_get_key(hDB, hLch, &key);
682 assert(status == DB_SUCCESS);
683
684 HNDLE hKey;
685 status = db_find_key(hDB, hLch, "List", &hKey);
686
687 if (status != DB_SUCCESS) {
688 cm_msg(MERROR, "convert_done_list", "Cannot find \'/Lazy/%s/List\' db_find_key() status %d", key.name, status);
690 exit(1);
691 }
692
693 INT *pdo = NULL;
694 int n = build_done_list_odb(hLch, &pdo);
695
697
698 for (int i = 0; i < n; i++)
699 for (unsigned j = 0; j < dlist.size(); j++)
700 if (dlist[j].runno == pdo[i])
701 done.push_back(dlist[j]);
702
703 free(pdo);
704
705 save_list(key.name, "donelist", &done);
706
707 status = db_rename_key(hDB, hKey, "List.converted");
708 assert(status == DB_SUCCESS);
709
710 cm_msg(MINFO, "convert_done_list",
711 "Done list converted from old ODB \'/Lazy/%s/List\' format to new file-based format. ODB \'List\' renamed to \'List.converted\'",
712 key.name);
713
715 exit(1);
716}
717
718/*------------------------------------------------------------------*/
720/********************************************************************\
721Routine: build_done_list
722Purpose: build a sorted internal /lazy/list list (pdo) tree.
723Input:
724HNDLE Key of the Lazy channel
725**pdo /lazy_xxx/list run listing
726Output:
727**pdo /lazy_xxx/list run listing
728Function value: number of elements
729\********************************************************************/
730{
731 HNDLE hKey;
732 KEY key;
733 int status = db_get_key(hDB, hLch, &key);
734 assert(status == DB_SUCCESS);
735
736 if (db_find_key(hDB, hLch, "List", &hKey) == DB_SUCCESS) {
737 cm_msg(MERROR, "build_done_list",
738 "lazylogger cannot continue: found old-style done list in ODB \'/Lazy/%s/List\'. Please convert to new done list format using \'lazylogger -C\'",
739 key.name);
741 exit(1);
742 }
743
745
746 return pdone->size();
747}
748
749/*------------------------------------------------------------------*/
751/********************************************************************\
752Routine: save_done_list
753Purpose: save a sorted internal /lazy/list list (pdo) tree.
754Input:
755HNDLE Key of the Lazy channel
756**pdo /lazy_xxx/list run listing
757Output:
758**pdo /lazy_xxx/list run listing
759Function value: number of elements
760\********************************************************************/
761{
762 KEY key;
763 int status = db_get_key(hDB, hLch, &key);
764 assert(status == DB_SUCCESS);
765 sort(pdone->begin(), pdone->end(), cmp_dirlog);
766 save_list(key.name, "donelist", pdone);
767 return SUCCESS;
768}
769
770/*------------------------------------------------------------------*/
772/********************************************************************\
773Routine: find_next_file
774Purpose: find next file to be backed up and return it's index in plog
775Input:
776*plog : disk file listing
777*pdone : list of files already backed up
778Output:
779Function value:
780index into plog
781-1 : no files
782
783\********************************************************************/
784{
785 for (unsigned j = 0; j < plog->size(); j++) {
786 bool found = false;
787 for (unsigned i = 0; i < pdone->size(); i++) {
788 if ((*plog)[j].filename == (*pdone)[i].filename)
789 found = true;
790 }
791
792 if (!found)
793 if ((*plog)[j].size > 0)
794 return j;
795 }
796
797 return -1;
798}
799
800/*------------------------------------------------------------------*/
801INT lazy_select_purge(HNDLE hKey, INT channel, LAZY_INFO *pLall, const char *fmt, const char *dir, DIRLOG *f)
802/********************************************************************\
803Routine: lazy_select_purge
804Purpose: Search oldest run number which can be purged
805condition : oldest run# in (pdo AND present in plog)
806AND scan all the other channels based on the following
807conditions:
808"data dir" && "filename format" are the same &&
809the /list/run_number exists in all the above condition.
810Input:
811hKey : Current channel key
812channel : Current channel number
813*pLall : Pointer to all channels
814fmt : Format string
815dir : Directory string
816Output:
817fpufile : file to purge
818run : corresponding run# to be purged
819Function value:
8200 success
821-1 run not found
822\********************************************************************/
823{
824 int size;
825 char ddir[256], ff[128], strmodulo[8];
826
827 /* Scan donelist from first element (oldest)
828 check if run exists in dirlog
829 if yes return file and run number */
830
831 while (1) {
832 /* try to find the oldest matching run present in the list AND on disk */
833 /* build current done list */
834
837
838 /* build matching dir and file format (ff) */
839 for (int i = 0; i < MAX_LAZY_CHANNEL; i++) {
840 /* Check if key present && key different than currrent
841 and if modulo is off */
842 if (((pLall + i)->hKey)) {
843 /* extract dir and ff */
844 size = sizeof(strmodulo);
845 db_get_value(hDB, (pLall + i)->hKey, "Settings/Modulo.Position", strmodulo, &size, TID_STRING, TRUE);
846 if (strmodulo[0]) {
847 /* Modulo enabled, skip this channel */
848 if (debug)
849 printf("purge: skipping channel \'%s\' which uses modulo \'%s\'\n", lazyinfo[i].name, strmodulo);
850 continue;
851 }
852
853 size = sizeof(ddir);
854 db_get_value(hDB, (pLall + i)->hKey, "Settings/Data dir", ddir, &size, TID_STRING, TRUE);
855 size = sizeof(ff);
856 db_get_value(hDB, (pLall + i)->hKey, "Settings/filename format", ff, &size, TID_STRING, TRUE);
857
858 // monkey about with trailing '/' characters
859
860 int len = strlen(ddir);
861 if (ddir[len - 1] != '/') {
862 ddir[len] = '/';
863 ddir[len + 1] = 0;
864 }
865
866 /* if same dir && same ff => mark lazy channel */
867 if (strcmp(ddir, dir) != 0) {
868 if (debug)
869 printf("purge: skipping channel \'%s\' which uses different data dir \'%s\', we use \'%s\'\n",
870 lazyinfo[i].name, ddir, dir);
871 continue;
872 }
873
874 if (debug)
875 printf("Loading file lists for channel \'%s\', data dir \'%s\', format \'%s\'\n", lazyinfo[i].name, ddir,
876 ff);
877
878 /* load file list and done list for matching channels */
881 }
882 } /* end of loop over channels */
883
884 /* search for files to delete */
885 for (unsigned k = 0; k < dirlists[channel].size(); k++) {
886 bool can_delete = true;
887
888 if (debug)
889 printf("purge: consider file \'%s\'\n", dirlists[channel][k].filename.c_str());
890
891 for (int i = 0; i < MAX_LAZY_CHANNEL; i++)
892 if (((pLall + i)->hKey)) {
893 bool in_dir_list = false;
894 bool in_done_list = false;
895
896 for (unsigned j = 0; j < dirlists[i].size(); j++)
897 if (dirlists[i][j].filename == dirlists[channel][k].filename) {
898 in_dir_list = true;
899 break;
900 }
901
902 if (!in_dir_list) {
903 if (debug)
904 printf("channel \'%s\': file is not in dir list, ok to delete\n", lazyinfo[i].name);
905 continue;
906 }
907
908 for (unsigned j = 0; j < donelists[i].size(); j++)
909 if (donelists[i][j].filename == dirlists[channel][k].filename) {
910 in_done_list = true;
911 break;
912 }
913
914 if (!in_done_list) {
915 if (debug)
916 printf("channel \'%s\': file is in dirlist but not in done list, cannot delete\n",
917 lazyinfo[i].name);
918 can_delete = false;
919 break;
920 }
921
922 if (debug)
923 printf("channel \'%s\': file is in dirlist and in done list, ok to delete\n", lazyinfo[i].name);
924 }
925
926 if (can_delete) {
927 if (debug)
928 printf("purge: file \'%s\' is done by all channels\n", dirlists[channel][k].filename.c_str());
929 *f = dirlists[channel][k];
930 return SUCCESS;
931 }
932 }
933
934 /* nothing to remove */
935 return !SUCCESS;
936 }
937}
938
939/*------------------------------------------------------------------*/
941/********************************************************************\
942Routine: lazy_maintain_check
943Purpose: Check if the "maintain free space" of any of the other matching
944channels is != 0. matching correspond to the condition:
945"data dir" && "filename format"
946if found != 0 then set to 0 and inform
947Input:
948hKey : Current lazy channel key
949*pLall : Pointer to all channels
950\********************************************************************/
951{
952 INT size;
953 INT i, maintain;
954 char dir[256], ff[128];
955 char cdir[256], cff[128];
956 char cmodulostr[8], modulostr[8];
957
958 /* do test only if maintain has been touched */
959 if (!maintain_touched)
960 return;
962
963 /* check is Maintain free is enabled */
964 size = sizeof(maintain);
965 db_get_value(hDB, hKey, "Settings/Maintain free space (%)", &maintain, &size, TID_INT, TRUE);
966 if (maintain != 0) {
967 /* scan other channels */
968
969 /* get current specification */
970 size = sizeof(cdir);
971 db_get_value(hDB, hKey, "Settings/Data dir", cdir, &size, TID_STRING, TRUE);
972 size = sizeof(cff);
973 db_get_value(hDB, hKey, "Settings/filename format", cff, &size, TID_STRING, TRUE);
974 size = sizeof(modulostr);
975 db_get_value(hDB, hKey, "Settings/Modulo.Position", cmodulostr, &size, TID_STRING, TRUE);
976
977 /* build matching dir and ff */
978 for (i = 0; i < MAX_LAZY_CHANNEL; i++) {
979 if (((pLall + i)->hKey) && (hKey != (pLall + i)->hKey)) { /* valid channel */
980 size = sizeof(dir);
981 db_get_value(hDB, (pLall + i)->hKey, "Settings/Data dir", dir, &size, TID_STRING, TRUE);
982 size = sizeof(ff);
983 db_get_value(hDB, (pLall + i)->hKey, "Settings/filename format", ff, &size, TID_STRING, TRUE);
984 size = sizeof(modulostr);
985 db_get_value(hDB, (pLall + i)->hKey, "Settings/Modulo.Position", modulostr, &size, TID_STRING, TRUE);
986
987 if ((strcmp(dir, cdir) == 0) && (strcmp(ff, cff) == 0) && !cmodulostr[0] && !modulostr[0]) {
988 /* check "maintain free space" */
989 size = sizeof(maintain);
990 db_get_value(hDB, (pLall + i)->hKey, "Settings/Maintain free space (%)",
991 &maintain, &size, TID_INT, TRUE);
992 if (maintain) {
993 /* disable and inform */
994 size = sizeof(maintain);
995 maintain = 0;
996 db_set_value(hDB, (pLall + i)->hKey, "Settings/Maintain free space (%)", &maintain, size, 1, TID_INT);
997 cm_msg(MINFO, "lazy_maintain_check",
998 "Maintain free space on channel %s has been disable", (pLall + i)->name);
999 }
1000 }
1001 }
1002 }
1003 }
1004}
1005
1006/*------------------------------------------------------------------*/
1008/********************************************************************\
1009Routine: lazy_statistics_update
1010Purpose: update the /lazy/statistics
1011Input:
1012INT cploop_time : time of the last call
1013Output:
1014Function value:
10150 success
1016\********************************************************************/
1017{
1018
1019 if (debug) {
1020 printf("file.size:%f - ", lazyst.file_size);
1021 printf("file.curr:%f - ", lazyst.cur_size);
1022 printf("lastsz:%f - ", lastsz);
1023 printf("nfiles:%i\n", lazyst.nfiles);
1024 }
1025 /* update rate [kb/s] statistics */
1026 if (cploop_time == 0) // special function: set copy_rate to zero at end of copy
1027 lazyst.copy_rate = 0.0;
1028 if ((ss_millitime() - cploop_time) > 100)
1030 if (lazyst.copy_rate < 0.0)
1031 lazyst.copy_rate = 0.0;
1032
1033 /* update % statistics */
1034 if (lazyst.file_size != 0.0f)
1035 lazyst.progress = (100.0f * (lazyst.cur_size / lazyst.file_size));
1036 else
1037 lazyst.progress = 0.0f;
1038
1039 /* update backup % statistics */
1040 if (lazy.capacity > 0.0f)
1042 else
1043 lazyst.bckfill = 0.0f;
1044
1046 /* udate ODB statistics */
1048}
1049
1050/*------------------------------------------------------------------*/
1052/********************************************************************\
1053Routine: condition_check
1054Purpose: return TRUE or FALSE depending if condition is satisfied
1055I expect a statement of the following form:
1056<key> <operator> <value>
1057with <key> : either link or key[index] or key(index)
1058<operator> : either: = < >
1059<value> : [+/-][digits]
1060Input: char * string to decode and test
1061Output:
1062Function value:
1063TRUE condition TRUE (carry on the copy)
1064FALSE condition FALSE (hold the copy)
1065\********************************************************************/
1066{
1067 KEY key;
1068 double value;
1069 double lcond_value;
1070 INT size, index, status;
1071 char left[64], right[64];
1072 char *p = NULL, *pp, *ppl, *pc, *lp;
1073
1074 index = 0;
1075 p = string;
1076 if (p) {
1077 while (isspace(*p))
1078 p++;
1079
1080 pc = strpbrk(p, "<=>");
1081 if (pc) {
1082 strncpy(left, p, pc - p);
1083 lp = left + (pc - p - 1);
1084 while (isspace(*lp))
1085 lp--;
1086 *(lp + 1) = '\0';
1087 strncpy(right, pc + 1, (strlen(p) - strlen(left)));
1088 right[strlen(p) - strlen(left) - 1] = '\0';
1089 }
1090
1091 if ((pp = strpbrk(left, "[(")) != NULL) {
1092 if ((ppl = strpbrk(left, "])")) != NULL) {
1093 *pp = '\0';
1094 *ppl = '\0';
1095 index = atoi(pp + 1);
1096 }
1097 *pp = '\0';
1098 }
1099
1100 /* convert value */
1101 value = (double) (atoi(right));
1102
1103 status = db_find_key(hDB, 0, left, &hKey);
1104 if (status != DB_SUCCESS) {
1105 cm_msg(MINFO, "condition_check", "Key %s not found", left);
1106 return FALSE;
1107 }
1109 if ((status == DB_SUCCESS) && (key.type <= TID_DOUBLE)) {
1110 /* get value of the condition */
1111 size = sizeof(lcond_value);
1113 std::string s = db_sprintf(&lcond_value, key.item_size, 0, key.type);
1114 lcond_value = std::stof(s);
1115 }
1116
1117 /* printf("string:%s\n condition: %s %f %c %f \n"
1118 , string, left, lcond_value, *pc, value);
1119 */
1120 /*
1121 if (pv == NULL)
1122 return TRUE;
1123 */
1124 /* perform condition check */
1125 if (((*pc == '>') && ((double) lcond_value > value)) || ((*pc == '=') && ((double) lcond_value == value)) ||
1126 ((*pc == '<') && ((double) lcond_value < value)))
1127 return TRUE;
1128 else
1129 return FALSE;
1130 }
1131 /* catch wrong argument in the condition as TRUE */
1132 return TRUE;
1133}
1134
1135/*------------------------------------------------------------------*/
1137/********************************************************************\
1138Routine: lazy_condition_check
1139Purpose: Check if the copy should continue.
1140The condition can have the following setting:
1141ALWAYS, NEVER, WHILE_NO_ACQ_RUNNING, key<=>value
1142Input:
1143Output:
1144Function value:
1145BOOL : new copy condition
1146\********************************************************************/
1147{
1148 /* Get condition */
1149 if (equal_ustring(lazy.condition, "ALWAYS"))
1150 return TRUE;
1151 else if (equal_ustring(lazy.condition, "NEVER"))
1152 return FALSE;
1153 else if (equal_ustring(lazy.condition, "WHILE_ACQ_NOT_RUNNING")) {
1154 if (run_state == STATE_RUNNING)
1155 return FALSE;
1156 else
1157 return TRUE;
1158 } else
1159 return (condition_test(lazy.condition));
1160}
1161
1162/*------------------------------------------------------------------*/
1164/********************************************************************\
1165Routine: lazy_copy
1166Purpose: backup file to backup device
1167every 2 second will update the statistics and yield
1168if condition requires no copy, every 5 second will yield
1169Input:
1170char * outfile backup destination file
1171char * infile source file to be backed up
1172Output:
1173Function value:
11740 success
1175\********************************************************************/
1176{
1177 void *plazy = NULL;
1178 DWORD szlazy;
1181 DWORD watchdog_timeout;
1182 static INT last_error = 0;
1183 //char *pext;
1185 char filename[256];
1186
1187 if (debug)
1188 printf("lazy_copy %s to %s\n", infile, outfile);
1189
1190 /* init copy variables */
1191 lazyst.cur_size = 0.0f;
1192
1193 /* open any logging file (output) */
1194 mstrlcpy(filename, outfile, sizeof(filename)); // ftp modifies filename
1195 if ((status = md_file_wopen(dev_type, data_fmt, filename, &hDev)) != 1) {
1196 if ((ss_time() - last_error) > 60) {
1197 last_error = ss_time();
1198 cm_msg(MTALK, "Lazy_copy", "cannot open %s, error %d", outfile, status);
1199 }
1200 return (FORCE_EXIT);
1201 }
1202
1203 /* New lazy copy if TAPE & append required force a mv to EOD */
1204 if ((dev_type == LOG_TYPE_TAPE) && lazy.tapeAppend) {
1205 /* Position Tape to end of Data */
1206 cm_msg(MINFO, "Lazy", "Positioning Tape to EOD");
1207
1208 cm_get_watchdog_params(&watchdog_flag, &watchdog_timeout);
1209 cm_set_watchdog_params(watchdog_flag, 300000); /* 5 min for tape rewind */
1211 cm_set_watchdog_params(watchdog_flag, watchdog_timeout);
1212 if (status != SS_SUCCESS) {
1213 cm_msg(MINFO, "Lazy", "Error while Positioning Tape to EOD (%d)", status);
1215 return (FORCE_EXIT);
1216 }
1217 }
1218
1219 /* reset error message */
1220 last_error = 0;
1221
1222 /* open input data file */
1224 return (FORCE_EXIT);
1225
1226 /* run shell command if available */
1227 if (equal_ustring(lazy.type, "Tape")) {
1228 /* get the block number. If -1 it probably means that the tape
1229 is not ready. Wait for a while */
1230 blockn = -1;
1231 while (blockn < 0) {
1233 if (blockn >= 0)
1234 break;
1235 cm_msg(MINFO, "Lazy", "Tape is not ready");
1236 cm_yield(3000);
1237 }
1238 if (lazy.commandBefore[0]) {
1239 char cmd[256];
1240 sprintf(cmd, "%s %s %s %d %s %i", lazy.commandBefore, infile, outfile, blockn, lazy.backlabel, lazyst.nfiles);
1241 cm_msg(MINFO, "Lazy", "Exec pre file write script:%s", cmd);
1242 ss_system(cmd);
1243 }
1244 }
1245
1246 /* force a statistics update on the first loop */
1247 cpy_loop_time = -2000;
1248 if (dev_type == LOG_TYPE_TAPE) {
1249 char str[256];
1250 sprintf(str, "Starting lazy job on %s at block %d", lazyst.backfile, blockn);
1251 if (msg_flag)
1252 cm_msg(MTALK, "Lazy", "%s", str);
1253 cm_msg1(MINFO, "lazy_copy", "lazy", "%s", str);
1254 }
1255
1256 /* infinite loop while copying */
1257 while (1) {
1258 if (copy_continue) {
1261 if (status != SS_SUCCESS) {
1262 /* close source file */
1264 /* close output data file */
1266 /* szlazy is the requested block size. Why is it copied to cm_msg?
1267 cm_msg(MERROR,"lazy_copy","Write error %i",szlazy); */
1268 cm_msg(MERROR, "lazy_copy", "Write error ");
1269 if (status == SS_NO_SPACE)
1270 return status;
1271 return (FORCE_EXIT);
1272 }
1275 if ((ss_millitime() - cpy_loop_time) > 2000) {
1276 /* update statistics */
1278
1279 /* check conditions */
1281
1282 /* update check loop */
1284
1285 /* yield quickly */
1286 status = cm_yield(1);
1288 cm_msg(MINFO, "Lazy", "Abort postponed until end of copy of %s %1.0lf[%%]",
1289 infile, (double) lazyst.progress);
1291 }
1292 }
1293 } /* get physrec */
1294 else
1295 break;
1296 } /* copy_continue */
1297 else { /* !copy_continue */
1298 status = cm_yield(1000);
1299 if (status == RPC_SHUTDOWN || status == SS_ABORT)
1300 return (FORCE_EXIT);
1301 if ((ss_millitime() - no_cpy_last_time) > 5000) {
1304 }
1305 } /* !copy_continue */
1306 } /* while forever */
1307
1308 /* update for last the statistics */
1310
1311 /* close input log device */
1313
1314 /* close output data file */
1315 if (equal_ustring(lazy.type, "Tape")) {
1317 }
1319 if (status != SS_SUCCESS) {
1320 if (status == SS_NO_SPACE)
1321 return status;
1322 return (FORCE_EXIT);
1323 }
1324
1325 /* request exit */
1326 if (exit_request)
1327 return (EXIT_REQUEST);
1328 return 0;
1329}
1330
1331//
1332//
1333int lazy_disk_copy_loop(const char *outfile, const char *infile, FILE *fpout, FILE *fpin) {
1334 int status;
1335 int no_cpy_last_time = 0;
1336
1337 /* force a statistics update on the first loop */
1338 int cpy_loop_time = -2000;
1339
1340 /* infinite loop while copying */
1341 while (1) {
1342 if (copy_continue) {
1343 const int kBufSize = 1 * 1024 * 1024;
1344 char buf[kBufSize];
1345 int rd = fread(buf, 1, kBufSize, fpin);
1346 if (rd > 0) {
1347 int wr = fwrite(buf, 1, rd, fpout);
1348 if (wr != rd) {
1349 cm_msg(MERROR, "Lazy_disk_copy", "Cannot write to \'%s\', errno %d (%s)", outfile, errno,
1350 strerror(errno));
1351 //if (status == SS_NO_SPACE)
1352 // return status;
1353 return TRY_LATER;
1354 }
1355
1356 lazyst.cur_size += (double) wr;
1358 if ((ss_millitime() - cpy_loop_time) > 2000) {
1359 /* update statistics */
1361
1362 /* check conditions */
1364
1365 /* update check loop */
1367
1368 /* yield quickly */
1369 status = cm_yield(1);
1370 if (status == RPC_SHUTDOWN || status == SS_ABORT) {
1371 cm_msg(MINFO, "Lazy", "Copy aborted by cm_yield() status %d", status);
1372 return FORCE_EXIT;
1373 }
1374 }
1375 } else if (rd == 0) {
1376 // end of input file
1377 break;
1378 } else {
1379 // read error
1380 cm_msg(MERROR, "Lazy_disk_copy", "Cannot read from \'%s\', errno %d (%s)", infile, errno, strerror(errno));
1381 return FORCE_EXIT;
1382 }
1383 } /* copy_continue */
1384 else { /* !copy_continue */
1385 status = cm_yield(1000);
1386 if (status == RPC_SHUTDOWN || status == SS_ABORT) {
1387 return FORCE_EXIT;
1388 }
1389 if ((ss_millitime() - no_cpy_last_time) > 5000) {
1392 }
1393 } /* !copy_continue */
1394 } /* while forever */
1395
1396 return 0;
1397}
1398
1399#ifdef HAVE_CURL
1400//
1401// function to read the data file
1403
1404static size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
1405 FILE *f = (FILE *) stream;
1406 size_t n;
1407 if (ferror(f))
1408 return CURL_READFUNC_ABORT;
1409
1410 n = fread(ptr, size, nmemb, f) * size;
1411 lastsz = n;
1414 if ((ss_millitime() - cpy_sftp_loop_time) > 2000) {
1415 if (debug)
1416 printf("readfunc (CURL) size:%ld nmemb:%ld n:%li total:%f\n", size, nmemb, n, lastsz);
1417 // update statistics
1420 cm_yield(10);
1421 }
1422 return n;
1423}
1424
1425//
1426// global for the SFTP
1427long int port_number = 22;
1428
1429// get the remote file size in byte; -1 on error or if file not existent
1430static long int get_remote_file_size(const char *remote_file) {
1431 CURLcode result;
1432 long int remote_file_size_byte = -1;
1433
1435
1436 // print metainfos if in debug mode
1437 if (debug) {
1439 }
1440 // url/file to transfer
1442 // set the port number to use for socket
1444 // get user and password from protected file
1445 // curl_easy_setopt(curlhandle, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
1446 // switch off the progress meter
1448 // don't transfer the file body
1450 // transfer the file header
1452 // get the modification time
1454
1455 // perform the transfer with all options
1456 result = curl_easy_perform(curlhandle);
1457 if (result == CURLE_OK) {
1458 // get the file size from the header info
1459
1460#if LIBCURL_VERSION_NUM < 0x073700
1462#else
1464#endif
1465 if (result) {
1466 return -1;
1467 }
1468 if (debug) {
1469 printf("[%s] Remote file size: %ld byte \n", __FUNCTION__, remote_file_size_byte);
1470 }
1471 } else if (result == CURLE_REMOTE_FILE_NOT_FOUND) {
1472 if (debug) {
1473 printf("[%s] Remote file %s not existent \n", __FUNCTION__, remote_file);
1474 }
1475 return -1;
1476 }
1477
1479
1480 return remote_file_size_byte;
1481}
1482
1483//
1484//
1485int lazy_sftp_copy_loop(const char *outfile, const char *infile, FILE *fpin) {
1486 //
1487 // Initialize curl
1488 CURL *curlhandle = NULL;
1491 CURLcode result;
1492
1493 lastsz = 0;
1495 // set transfer mode to upload
1497 // define the upload url
1499 // set the port number to use for socket
1501 // get user and password from protected netrc file
1502 // could also be set with curl_easy_setopt(curlhandle, CURLOPT_USERPWD, "user:password") but this is even less save
1503 // best way to do is generate a RSA-keypair (or similar) and don't set it here at all, this is not allowed for some dataservers though
1504 //result = curl_easy_setopt(curlhandle, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
1505 // use a custom read function instead of the default fread()
1507 // define the file to read
1509 // define the file size to upload (2 GB limit for regular size)
1510 if (lazyst.file_size < 2147483648)
1512 else
1514
1515 result = curl_easy_perform(curlhandle);
1516 if (result) {
1517 cm_msg(MERROR, "SFTP_copy", "Failed to upload due to CURL errror %d", result);
1518 printf("Failed to upload file '%s' with error code %d \n", infile, result);
1519 } else {
1520 printf("File '%s' successfully uploaded \n", infile);
1521 }
1522
1525
1526 return result;
1527}
1528
1529//
1530// SFTP copy
1531int lazy_sftp_copy(const char *outfile, const char *infile) {
1532
1533 DWORD watchdog_timeout;
1535
1536 if (debug)
1537 printf("lazy_sftp_copy %s to %s\n", infile, outfile);
1538
1539 double MiB = 1024 * 1024;
1540 //double disk_size = ss_disk_size((char*)outfile);
1541 //double disk_free = ss_disk_free((char*)outfile);
1542 //printf("output disk size %.1f MiB, free %.1f MiB\n", disk_size/MiB, disk_free/MiB);
1543
1544 /* init copy variables */
1545 lazyst.cur_size = 0.0f;
1546
1547 /* run shell command if available */
1548 if (lazy.commandBefore[0]) {
1549 char cmd[256];
1550 sprintf(cmd, "%s %s %i", lazy.commandBefore, infile, lazyst.nfiles);
1551 cm_msg(MINFO, "Lazy", "Exec pre file write script:%s", cmd);
1552 ss_system(cmd);
1553 }
1554
1555 FILE *fpin = fopen(infile, "rb");
1556 if (!fpin) {
1557 cm_msg(MERROR, "Lazy_sftp_copy", "Cannot read from \'%s\', errno %d (%s)", infile, errno, strerror(errno));
1558 return FORCE_EXIT;
1559 }
1560
1561 setbuf(fpin, NULL);
1562
1563 {
1564 char str[MAX_FILE_PATH];
1565 sprintf(str, "Starting lazy_sftp_copy \'%s\' to \'%s\'", infile, outfile);
1566 if (msg_flag)
1567 cm_msg(MTALK, "Lazy", "%s", str);
1568 // wrtie to file
1569 cm_msg1(MINFO, "lazy_sftp_copy", "lazy", "%s", str);
1570 }
1571
1572 double cpy_start_time = ss_millitime();
1573
1574 cm_get_watchdog_params(&watchdog_flag, &watchdog_timeout);
1575 cm_set_watchdog_params(watchdog_flag, 10 * 60 * 1000); /* increase timeout in case of delays writing output file */
1576
1578
1580
1581 // Check for remote file size matching what we just sent.
1582 if (lazyst.file_size != remote_size) {
1583 printf(" File copied incomplete (%s)\n", outfile);
1584 cm_msg(MERROR, "Lazy_SFTP_Copy", "File copied incomplete (%s)\n", outfile);
1585 return TRY_LATER;
1586 }
1587
1588 if (debug)
1589 printf("*********** remove File Size: %d\n", remote_size);
1590
1591 cm_set_watchdog_params(watchdog_flag, watchdog_timeout);
1592
1593 /* update for last the statistics */
1595
1596 /* close input log device */
1597 fclose(fpin);
1598 fpin = NULL;
1599
1600 if (copy_status) {
1601 return copy_status;
1602 }
1603
1604 chmod(outfile, 0444);
1605
1606 double t = (ss_millitime() - cpy_start_time) / 1000.0;
1607 //double MiB = 1024*1024;
1608 cm_msg(MINFO, "lazy_disk_copy", "Copy finished in %.1f sec, %.1f MiBytes at %.1f MiBytes/sec", t,
1610
1611 return 0;
1612}
1613#endif // HAVE_CURL
1614
1615INT lazy_disk_copy(const char *outfile, const char *infile)
1616/********************************************************************\
1617Routine: lazy_disk_copy
1618Purpose: backup file to backup device
1619every 2 second will update the statistics and yield
1620if condition requires no copy, every 5 second will yield
1621Input:
1622char * outfile backup destination file
1623char * infile source file to be backed up
1624Output:
1625Function value:
16260 success
1627\*********************************************************************/
1628{
1629 int status;
1630 DWORD watchdog_timeout;
1632
1633 if (debug)
1634 printf("lazy_disk_copy %s to %s\n", infile, outfile);
1635
1636 double MiB = 1024 * 1024;
1637 double disk_size = ss_disk_size((char *) outfile);
1638 double disk_free = ss_disk_free((char *) outfile);
1639
1640 if (debug)
1641 printf("output disk size %.1f MiB, free %.1f MiB\n", disk_size / MiB, disk_free / MiB);
1642
1643 /* init copy variables */
1644 lazyst.cur_size = 0.0f;
1645
1646 /* run shell command if available */
1647 if (lazy.commandBefore[0]) {
1648 char cmd[256];
1649 sprintf(cmd, "%s %s %i", lazy.commandBefore, infile, lazyst.nfiles);
1650 cm_msg(MINFO, "Lazy", "Exec pre file write script:%s", cmd);
1651 ss_system(cmd);
1652 }
1653
1654 FILE *fpin = fopen(infile, "rb");
1655 if (!fpin) {
1656 cm_msg(MERROR, "Lazy_disk_copy", "Cannot read from \'%s\', errno %d (%s)", infile, errno, strerror(errno));
1657 return FORCE_EXIT;
1658 }
1659
1660 FILE *fptest = fopen(outfile, "rb");
1661 if (fptest) {
1662 fclose(fptest);
1663 fptest = NULL;
1664 cm_msg(MINFO, "Lazy_disk_copy", "Output file \'%s\' already exists, removing", outfile);
1665 unlink(outfile);
1666 //return FORCE_EXIT;
1667 }
1668
1669 FILE *fpout = fopen(outfile, "wb");
1670 if (!fpout) {
1671 cm_msg(MERROR, "Lazy_disk_copy", "Cannot write to \'%s\', errno %d (%s)", outfile, errno, strerror(errno));
1672 fclose(fpin);
1673 return TRY_LATER;
1674 }
1675
1676 setbuf(fpin, NULL);
1677 setbuf(fpout, NULL);
1678
1679 {
1680 char str[MAX_FILE_PATH];
1681 sprintf(str, "Starting lazy_disk_copy \'%s\' to \'%s\'", infile, outfile);
1682 if (msg_flag)
1683 cm_msg(MTALK, "Lazy", "%s", str);
1684 cm_msg1(MINFO, "lazy_disk_copy", "lazy", "%s", str);
1685 }
1686
1687 double cpy_start_time = ss_millitime();
1688
1689 cm_get_watchdog_params(&watchdog_flag, &watchdog_timeout);
1690 cm_set_watchdog_params(watchdog_flag, 10 * 60 * 1000); /* increase timeout in case of delays writing output file */
1691
1693
1694 cm_set_watchdog_params(watchdog_flag, watchdog_timeout);
1695
1696 /* update for last the statistics */
1698
1699 /* close input log device */
1700 fclose(fpin);
1701 fpin = NULL;
1702
1703 status = fclose(fpout);
1704 if (status != 0) {
1705 cm_msg(MERROR, "Lazy_disk_copy", "Cannot close \'%s\', errno %d (%s)", outfile, errno, strerror(errno));
1706 //if (status == SS_NO_SPACE)
1707 // return status;
1708 return TRY_LATER;
1709 }
1710
1711 if (copy_status) {
1712 return copy_status;
1713 }
1714
1715 chmod(outfile, 0444);
1716
1717 double t = (ss_millitime() - cpy_start_time) / 1000.0;
1718 //double MiB = 1024*1024;
1719 cm_msg(MINFO, "lazy_disk_copy", "Copy finished in %.1f sec, %.1f MiBytes at %.1f MiBytes/sec", t,
1721
1722 return 0;
1723}
1724
1725/*------------------------------------------------------------------*/
1726
1727#ifdef OS_LINUX // does not work under Windows because of missing popen
1728
1730/********************************************************************\
1731Routine: lazy_script_copy
1732Purpose: call user script to backup file to backup device
1733Input:
1734char * infile source file to be backed up
1735Output:
1736Function value:
17370 success
1738\********************************************************************/
1739{
1740 int status;
1741 FILE *fin;
1743 char cmd[256];
1744
1745 /* init copy variables */
1746 lazyst.cur_size = 0;
1747
1748 /* run shell command if available */
1749 if (lazy.commandBefore[0]) {
1750 char cmd[256];
1751 sprintf(cmd, "%s %s %i", lazy.commandBefore, infile, lazyst.nfiles);
1752 cm_msg(MINFO, "Lazy", "Exec pre file write script:%s", cmd);
1753 ss_system(cmd);
1754 }
1755
1756 /* create the command for the backup script */
1757 sprintf(cmd, "%s %s 2>&1", lazy.path, infile);
1758
1759 {
1760 char str[100 + 256];
1761 sprintf(str, "Starting lazy job \'%s\'", cmd);
1762 if (msg_flag)
1763 cm_msg(MTALK, "Lazy", "%s", str);
1764 cm_msg1(MINFO, "lazy_script_copy", "lazy", "%s", str);
1765 }
1766
1767 /* start the backup script */
1768 fin = popen(cmd, "r");
1769
1770 if (fin == NULL) {
1771 cm_msg(MTALK, "lazy_script_copy", "Cannot start \'%s\', errno %d (%s)", cmd, errno, strerror(errno));
1772 return FORCE_EXIT;
1773 }
1774
1775 if (1) {
1776 int desc = fileno(fin);
1777 int flags = fcntl(desc, F_GETFL, 0);
1778 fcntl(desc, F_SETFL, flags | O_NONBLOCK);
1779 }
1780
1781 /* infinite loop while copying */
1782 while (1) {
1783 char buf[1024];
1784 int rd = read(fileno(fin), buf, sizeof(buf));
1785 if (rd == 0) {
1786 /* file closed - backup script completed */
1787 break;
1788 } else if (rd < 0) {
1789 /* i/o error */
1790
1791 if (errno == EAGAIN) {
1792 /* this is the main loop while waiting for the backup script */
1793 status = cm_yield(1000);
1794 continue;
1795 }
1796
1797 cm_msg(MERROR, "lazy_script_copy", "Error reading output of the backup script, errno %d (%s)", errno,
1798 strerror(errno));
1799 break;
1800 } else {
1801 char *p;
1802 /* backup script printed something, write it to log file */
1803
1804 /* make sure text is NUL-terminated */
1805 buf[rd] = 0;
1806
1807 /* chop the output of the backup script into lines separated by '\n' */
1808 p = buf;
1809 while (p) {
1810 char *q = strchr(p, '\n');
1811 if (q) {
1812 *q = 0; // replace '\n' with NUL
1813 q++;
1814 if (q[0] == 0) // check for end of line
1815 q = NULL;
1816 }
1817 cm_msg(MINFO, "lazy_script_copy", "%s", p);
1818 p = q;
1819 }
1820 }
1821 }
1822
1823 /* update for last the statistics */
1825
1826 /* close input log device */
1827 status = pclose(fin);
1828
1829 if (status == -1) {
1830 cm_msg(MERROR, "lazy_script_copy", "pclose() returned %d, errno %d (%s)", status, errno, strerror(errno));
1831 return FORCE_EXIT;
1832 }
1833
1834 if (status != 0) {
1835 cm_msg(MERROR, "lazy_script_copy", "Backup script finished with exit code %d, status 0x%x", (status >> 8),
1836 status);
1837 return SS_NO_SPACE;
1838 }
1839
1840 cm_msg(MINFO, "lazy_script_copy", "Backup script finished in %.1f sec with exit code %d",
1841 (ss_millitime() - cpy_loop_time) / 1000.0, (status >> 8));
1842
1843 /* request exit */
1844 return 0;
1845}
1846
1847#endif // OS_LINUX
1848
1849/*------------------------------------------------------------------*/
1850BOOL lazy_file_exists(char *dir, char *file)
1851/********************************************************************\
1852Routine: lazy_file_exists
1853Purpose: check if file exists in dir by extracting its size
1854Input:
1855char * dir data directory
1856char * file file to be checked
1857Output:
1858Function value:
1859TRUE file found
1860FALSE file not found
1861\********************************************************************/
1862{
1863 char *list;
1864 char fullfile[MAX_FILE_PATH] = {'\0'};
1865
1866 if (ss_file_find(dir, file, &list) == 1) {
1867 strcat(fullfile, dir);
1870 if ((lazyst.file_size = (double) (ss_file_size(fullfile))) > 0) {
1871 free(list);
1872 return TRUE;
1873 }
1874 }
1875 free(list);
1876 return FALSE;
1877}
1878
1879/*------------------------------------------------------------------*/
1880
1882 int status;
1883
1884 /* update "maintain free space" */
1886
1887 /* check SPACE and purge if necessary = % (1:99) */
1888 if (lazy.pupercent > 0) {
1889
1890 // Compute initial disk space
1891 double freepercent = 100. * ss_disk_free(lazy.dir) / ss_disk_size(lazy.dir);
1892
1893 // Check for Disk full first
1894 if (freepercent < 5.0) {
1895 std::string str;
1896 str += "Disk ";
1897 str += lazy.dir;
1898 str += "is almost full, free space: ";
1899 char buf[256];
1900 sprintf(buf, "%.1f%%", freepercent);
1901 str += buf;
1902 al_trigger_alarm("Disk Full", str.c_str(), lazy.alarm, "Disk buffer full", AT_INTERNAL);
1903 } else {
1904 HNDLE hKey;
1905 if (db_find_key(hDB, 0, "/Alarms/Alarms/Disk Full", &hKey) == DB_SUCCESS)
1906 al_reset_alarm("Disk Full");
1907 }
1908
1909 if (debug)
1910 printf("free space on %s: %.1f%%, lazy limit %d%%\n", lazy.dir, freepercent, lazy.pupercent);
1911
1912 /* Lock other clients out of this following code as
1913 it may access the other client info tree */
1914
1916 if (status != SS_SUCCESS) {
1917 /* exit for now and come back later */
1918 return NOTHING_TODO;
1919 }
1920
1921 /* check purging action */
1922 while (freepercent <= (double) lazy.pupercent) {
1923 // flag for single purge
1925 /* search file to purge : run in donelist AND run in dirlog */
1926 /* synchronize donelist to dir log in case user has purged
1927 some file by hand. Basically remove the run in the list if the
1928 file is not anymore in the source dir. */
1929 DIRLOG f;
1930 if (lazy_select_purge(pLch->hKey, channel, pLall, lazy.backfmt, lazy.dir, &f) == SUCCESS) {
1931 /* check if beyond keep file + 1 */
1932 if (1 /*purun < (cur_acq_run - abs(lazy.staybehind) - 1)*/) {
1933 DWORD rm_time;
1934 /* remove file */
1936 std::string path = lazy.dir;
1937 path += f.filename;
1938 if (debug)
1939 printf("file selected for removal %s [%s]\n", f.filename.c_str(), path.c_str());
1940 status = lazy_file_remove(path.c_str());
1942 if (status != SS_SUCCESS) {
1943 cm_msg(MERROR, "Lazy", "lazy_file_remove failed on file %s", path.c_str());
1944 // break out if can't delete files
1945 break;
1946 } else {
1947 status = lazy_log_update(REMOVE_FILE, f.runno, NULL, path.c_str(), rm_time);
1948 donepurge = TRUE;
1949 }
1950 } // purun found
1951
1952 // Re-compute free space
1954
1955 if (debug)
1956 printf("free space on %s: %.1f%%, lazy limit %d%%\n", lazy.dir, freepercent, lazy.pupercent);
1957
1958 } // select_purge
1959
1960 // donepurge = FALSE => nothing else to do
1961 // donepurge = TRUE => one purge done loop back once more
1962 if (!donepurge)
1963 break;
1964 } // while
1965
1966 /* Release the semaphore */
1968
1969 } /* end of if pupercent > 0 */
1970
1971 return SUCCESS;
1972}
1973
1974/*------------------------------------------------------------------*/
1976/********************************************************************\
1977Routine: lazy_main
1978Purpose: check if backup is necessary...
1979Input:
1980channel: Current channel number
1981*pLall : Pointer to all channels
1982Output:
1983Function value:
1984\********************************************************************/
1985{
1986 DWORD cp_time;
1987 INT size, status;
1990 DWORD watchdog_timeout;
1991 LAZY_INFO *pLch;
1992 static BOOL eot_reached = FALSE;
1993 BOOL haveTape;
1994
1995 /* current channel */
1996 pLch = &pLall[channel];
1997
1998 if (convert_flag) {
1999 convert_done_list(pLch->hKey);
2000 assert(!"NOT REACHED");
2001 }
2002
2003 /* extract Data format from the struct */
2004 if (equal_ustring(lazy.format, "MIDAS"))
2006 else {
2007 cm_msg(MERROR, "Lazy", "Unknown data format %s (MIDAS)", lazy.format);
2008 return DB_NO_ACCESS;
2009 }
2010
2011 /* extract Device type from the struct */
2012 if (equal_ustring(lazy.type, "DISK"))
2014 else if (equal_ustring(lazy.type, "TAPE"))
2016 else if (equal_ustring(lazy.type, "FTP"))
2018 else if (equal_ustring(lazy.type, "SFTP"))
2020 else if (equal_ustring(lazy.type, "SCRIPT"))
2022 else {
2023 cm_msg(MERROR, "Lazy", "Unknown device type %s (Disk, Tape, SFTP, FTP or SCRIPT)", lazy.type);
2024 return DB_NO_ACCESS;
2025 }
2026
2028 if (lazy.backlabel[0] == 0 || strcmp(lazy.backlabel, lazyinfo[channel].name) != 0) {
2030 size = sizeof(lazy.backlabel);
2031 db_set_value(hDB, pLch->hKey, "Settings/List label", lazy.backlabel, size, 1, TID_STRING);
2032 }
2033 /* make sure that we don't operate on the current DAQ file if so set to oldest */
2034 //if (lazy.staybehind == 0) {
2035 // cm_msg(MERROR, "Lazy", "Stay behind cannot be 0");
2036 // return NOTHING_TODO;
2037 //}
2038
2039 /* Check if Tape is OK */
2040 /* ... */
2041
2042 haveTape = (lazy.backlabel[0] != '\0');
2043
2044 /* check if space on device (not empty tape label) */
2045 if (lazy.backlabel[0] == '\0') {
2047 } else {
2048 if (full_bck_flag) {
2050 size = sizeof(lazyst);
2051 memset(&lazyst, 0, size);
2052 if (db_find_key(hDB, pLch->hKey, "Statistics", &hKeyst) == DB_SUCCESS) {
2053 status = db_set_record(hDB, hKeyst, &lazyst, size, 0);
2054 /* New session of lazy, apply append in case of Tape */
2055 /* DISK for debugging */
2056 if ((dev_type == LOG_TYPE_DISK) && lazy.tapeAppend) {
2057 /* Position Tape to end of Data */
2058 cm_msg(MINFO, "Lazy", "Positioning Tape to EOD");
2059 }
2060 } else
2061 cm_msg(MERROR, "lazy_main", "did not find /Lazy/Lazy_%s/Statistics for zapping", pLch->name);
2062 // INT al_reset_alarm(char *alarm_name)
2063 if (dev_type == LOG_TYPE_TAPE)
2064 al_reset_alarm("Tape");
2065 }
2066 }
2067 /* check if data dir is none empty */
2068 if (lazy.dir[0] == '\0') {
2069 cm_msg(MINFO, "Lazy", "Please setup Data dir for input source path!");
2070 return NOTHING_TODO;
2071 }
2072
2073 if (lazy.dir[0] != 0)
2074 if (lazy.dir[strlen(lazy.dir) - 1] != DIR_SEPARATOR)
2076
2077 /* check if device path is set */
2078 if (lazy.path[0] == '\0') {
2079 cm_msg(MINFO, "Lazy", "Please setup backup device path too!");
2080 return NOTHING_TODO;
2081 }
2082
2085
2086 save_list(pLch->name, "dirlist", &dirlist);
2087
2090
2092
2093 /* compare list : run NOT in donelist AND run in dirlog */
2095
2096 //const DIRLOG* tobe_backup = cmp_log2donelist(&dirlist, &donelist);
2097
2098 //if (debug)
2099 //print_dirlog(&dirlist);
2100
2101 //print_dirlog(&donelist);
2102 //printf("tobe_backup: %p\n", tobe_backup);
2103
2104 if (tobe_backup < 0)
2105 return NOTHING_TODO;
2106
2107 if (debug)
2108 printf("selected for backup: %s, run %d\n", dirlist[tobe_backup].filename.c_str(), dirlist[tobe_backup].runno);
2109
2110 /* Get current run number */
2111 int cur_acq_run;
2112 size = sizeof(cur_acq_run);
2113 status = db_get_value(hDB, 0, "Runinfo/Run number", &cur_acq_run, &size, TID_INT, FALSE);
2114 assert(status == SUCCESS);
2115
2117
2118 int behind_files = dirlist.size() - tobe_backup;
2120
2123
2124 bool nothing_todo = false;
2125
2126 /* "stay behind by so many runs" mode */
2127 if (lazy.staybehind < 0)
2129
2130 /* "stay behind by so many files" mode */
2131 if (lazy.staybehind > 0)
2133
2134 /* "no stay behind" mode */
2135 if (lazy.staybehind == 0) {
2136 if (dirlist[tobe_backup].runno != cur_acq_run)
2137 nothing_todo = false;
2138 else if (behind_files > 1)
2139 nothing_todo = false;
2140 else {
2141 nothing_todo = false;
2142
2143 /* In case it is the current run make sure
2144 1) no transition is in progress
2145 2) the run start has not been aborted
2146 3) the run has been ended
2147 */
2148
2149 int flag;
2150 size = sizeof(flag);
2151 status = db_get_value(hDB, 0, "Runinfo/Transition in progress", &flag, &size, TID_INT, FALSE);
2152 assert(status == SUCCESS);
2153 if (flag) {
2154 if (debug)
2155 printf("transition in progress, cannot backup last file\n");
2156 nothing_todo = true;
2157 }
2158
2159 size = sizeof(flag);
2160 status = db_get_value(hDB, 0, "Runinfo/Start abort", &flag, &size, TID_INT, FALSE);
2161 assert(status == SUCCESS);
2162 if (flag) {
2163 if (debug)
2164 printf("run start aborted, cannot backup last file\n");
2165 nothing_todo = true;
2166 }
2167
2168 int cur_state_run;
2169 status = db_get_value(hDB, 0, "Runinfo/State", &cur_state_run, &size, TID_INT, FALSE);
2170 assert(status == SUCCESS);
2171 if ((cur_state_run != STATE_STOPPED)) {
2172 if (debug)
2173 printf("run still running, cannot backup last file\n");
2174 nothing_todo = true;
2175 }
2176 }
2177 }
2178
2179 if (debug)
2180 printf("behind: %d files, %d runs, staybehind: %d, nothing_todo: files: %d, runs: %d, lazylogger: %d\n",
2182
2183 if (nothing_todo) {
2184 return NOTHING_TODO;
2185 }
2186
2188 if (!haveTape) {
2189 if (debug)
2190 printf("haveTape: %d, nothing to do.\n", haveTape);
2191 return NOTHING_TODO;
2192 }
2193
2194 mstrlcpy(lazyst.backfile, dirlist[tobe_backup].filename.c_str(), sizeof(lazyst.backfile));
2195
2196 std::string xfile = lazy.dir;
2197 xfile += dirlist[tobe_backup].filename;
2198 mstrlcpy(inffile, xfile.c_str(), sizeof(inffile));
2199
2200 /* Check again if the backup file is present in the logger dir */
2202 /* compose the destination file name */
2203 if ((dev_type == LOG_TYPE_DISK) || (dev_type == LOG_TYPE_SFTP)) {
2204 if (lazy.path[0] != 0)
2205 if (lazy.path[strlen(lazy.path) - 1] != DIR_SEPARATOR)
2207 strcpy(outffile, lazy.path);
2209 } else if (dev_type == LOG_TYPE_TAPE)
2210 strcpy(outffile, lazy.path);
2211 else if (dev_type == LOG_TYPE_FTP) {
2212 /* Format for FTP
2213 lazy.path=host,port,user,password,directory,filename[,umask]
2214 expect filename in format such as "bck%08d.mid" */
2215
2216 /*
2217 if (lazy.path[0] != 0)
2218 if (lazy.path[strlen(lazy.path)-1] != DIR_SEPARATOR)
2219 strcat(lazy.path, DIR_SEPARATOR_STR);
2220 */
2221
2222 strcpy(str, lazy.path);
2223 /* substitute "%d" for current run number */
2224 if (strchr(str, '%'))
2226 else
2227 strcpy(outffile, str);
2228
2229 /* substitute "#d" for current run number millenium */
2230 mstrlcpy(str, outffile, sizeof(str));
2231 if (strchr(str, '#')) {
2232 *strchr(str, '#') = '%';
2233 sprintf(outffile, str, lazyst.cur_run / 1000);
2234 }
2235 }
2236
2237 /* check if space on backup device ONLY in the TAPE case */
2239 char pre_label[32];
2240 /* save the last label for shell script */
2241 strcpy(pre_label, lazy.backlabel);
2242
2243 /* Reset EOT reached */
2245
2246 /* not enough space => reset list label */
2247 lazy.backlabel[0] = '\0';
2248 size = sizeof(lazy.backlabel);
2249 db_set_value(hDB, pLch->hKey, "Settings/List label", lazy.backlabel, size, 1, TID_STRING);
2251 cm_msg(MINFO, "Lazy", "Not enough space for next copy on backup device!");
2252
2253 /* rewind device if TAPE type */
2254 if (dev_type == LOG_TYPE_TAPE) {
2256 char str[256];
2257 sprintf(str, "Tape %s is full with %d files", pre_label, lazyst.nfiles);
2258 cm_msg(MINFO, "Lazy", "%s", str);
2259
2260 /* Setup alarm */
2261 lazy.alarm[0] = 0;
2262 size = sizeof(lazy.alarm);
2263 db_get_value(hDB, pLch->hKey, "Settings/Alarm Class", lazy.alarm, &size, TID_STRING, TRUE);
2264
2265 /* trigger alarm if defined */
2266 if (lazy.alarm[0])
2267 al_trigger_alarm("Tape",
2268 "Tape full, Please remove current tape and load new one!",
2269 lazy.alarm, "Tape full", AT_INTERNAL);
2270
2271 /* run shell command if available */
2272 if (lazy.command[0]) {
2273 std::string cmd;
2274 cmd += lazy.command;
2275 cmd += " ";
2276 cmd += lazy.path;
2277 cmd += " ";
2278 cmd += pLch->name;
2279 cmd += " ";
2280 cmd += pre_label;
2281 cm_msg(MINFO, "Lazy", "Exec post-rewind script:%s", cmd.c_str());
2282 ss_system(cmd.c_str());
2283 }
2284
2285 cm_msg(MINFO, "Lazy", "backup device rewinding...");
2286 cm_get_watchdog_params(&watchdog_flag, &watchdog_timeout);
2287 cm_set_watchdog_params(watchdog_flag, 300000); /* 5 min for tape rewind */
2289 if (channel < 0) {
2290 cm_msg(MERROR, "Lazy", "Cannot rewind tape %s - %d - %d", outffile, channel, status);
2291 return NOTHING_TODO;
2292 }
2293 //else
2294 // cm_msg(MINFO,"Lazy", "After call ss_tape_open used to rewind tape %s - %d - %d", outffile, channel, status);
2295 cm_msg(MINFO, "Lazy", "Calling ss_tape_unmount");
2298 cm_set_watchdog_params(watchdog_flag, watchdog_timeout);
2299 return NOTHING_TODO;
2300 } // 1
2301 } // LOG_TYPE_TAPE
2302
2303 // Postpone copy by "copy_delay" if the copy check happens right after the
2304 // stop transition. This permit EOR external scripts to complete there operations
2305 // prior to the lazycopy.
2306 // Delay the copy in case:
2307 // 0) all previous condition for copy is satisfied
2308 // 1) Stopped transition has been detected,
2309
2310 if (stop_transition) {
2311 printf("in loop stop detected\n");
2312 stop_transition = FALSE; // reset transition (trfunction())
2313 delay_start = TRUE; // take notice of transition
2314 lazy_time = ss_time(); // mark time for delay
2315 }
2316 // check if its time after a stop transition
2317 if (delay_start && (ss_time() - lazy_time) < (DWORD) lazy.copy_delay) {
2318 printf("During delay %d... (%d)\n", ss_time() - lazy_time, lazy.copy_delay);
2319 return NOTHING_TODO;
2320 } else {
2322 }
2323
2324 /* Finally do the copy */
2326 status = 0;
2327 if (dev_type == LOG_TYPE_SCRIPT) {
2328#ifdef OS_LINUX
2329 //sprintf(lazy.backlabel, "%06d", 100 * (lazyst.cur_run / 100));
2331#else
2332 assert(!"lazy_script_copy not supported under Windows");
2333#endif
2334 } else if (dev_type == LOG_TYPE_SFTP) {
2335#ifdef HAVE_CURL
2336 // copy CURL SFTP
2338#else
2339 assert(!"SFTP copying requires CURL to be installed! Install CURL, re-run cmake, and re-compile!");
2340#endif
2341 } else if (dev_type == LOG_TYPE_DISK) {
2342 // copy block mode
2344 } else {
2345 // copy event mode (old method)
2347 }
2348
2349 if ((status != 0) && (status != EXIT_REQUEST)) {
2350 if (status == SS_NO_SPACE) {
2351 /* Consider this case as EOT reached */
2352 eot_reached = TRUE;
2353 return status;
2354 } else if (status == FORCE_EXIT)
2355 return status;
2356 cm_msg(MERROR, "Lazy", "copy failed -%s-%s-%i", lazy.path, lazyst.backfile, status);
2357 if (status == TRY_LATER)
2358 return status;
2359 return FORCE_EXIT;
2360 }
2362
2363 // copy done, update listings, logs, ODB
2364 donelist.push_back(dirlist[tobe_backup]);
2365 save_done_list(pLch->hKey, &donelist);
2368 } /* file exists */
2369 else {
2370 // If file not present it may be due to a run abort.
2371 // As the file is based on the "tobe_backup" run number
2372 // which is evaluated every lazy check, if a run is missing
2373 // it will be skiped properly.
2374 // No message is needed in this case.
2375 // cm_msg(MERROR, "Lazy", "lazy_file_exists file %s doesn't exists", lazyst.backfile);
2376 return NOTHING_TODO;
2377 }
2378
2379 if (status == EXIT_REQUEST)
2381
2382 //-PAA code moved at the end of "file exists condition" (above)
2383 // cp_time = ss_millitime() - cp_time;
2384 // donelist.push_back(dirlist[tobe_backup]);
2385 // save_done_list(pLch->hKey, &donelist);
2386 // lazy_log_update(NEW_FILE, lazyst.cur_run, lazy.backlabel, lazyst.backfile, cp_time);
2387
2388 if (msg_flag)
2389 cm_msg(MTALK, "Lazy", " lazy job %s done!", lazyst.backfile);
2390
2391 /* generate/update a <channel>_recover.odb file when everything is Ok
2392 after each file copy */
2393 {
2394 std::string str;
2395 /* leave "list label" as it is, as long as the _recover.odb is loaded before
2396 the lazylogger is started with NO -z things should be fine */
2397 /* save the recover with "List Label" empty */
2398 if (lazy.dir[strlen(lazy.dir) - 1] != DIR_SEPARATOR) {
2399 str += lazy.dir;
2400 str += DIR_SEPARATOR;
2401 str += pLch->name;
2402 str += "_recover.odb";
2403 } else {
2404 str += lazy.dir;
2405 str += pLch->name;
2406 str += "_recover.odb";
2407 }
2408
2409 db_save(hDB, pLch->hKey, str.c_str(), TRUE);
2410 }
2411
2412 if (exit_request)
2413 return (FORCE_EXIT);
2414 return NOTHING_TODO;
2415}
2416
2417/*------------------------------------------------------------------*/
2418
2420 int status;
2421 assert(info != NULL);
2422 HNDLE hSet = *(HNDLE *) info;
2423 int size = sizeof(lazy);
2425 if (status != DB_SUCCESS) {
2426 cm_msg(MINFO, "watch_settings", "db_get_record(settings) status %d", status);
2427 return;
2428 }
2429
2430 // printf("Settings updated\n");
2431
2432 if (lazy.pupercent != 0)
2434 else
2436
2437 //printf("pup %d, touched %d\n", lazy.pupercent, maintain_touched);
2438}
2439
2440/*------------------------------------------------------------------*/
2441int main(int argc, char **argv) {
2442 char channel_name[32];
2445 BOOL daemon;
2446 INT i, msg, size, status, mainlast_time;
2447 DWORD last_time_kb = 0;
2448 setbuf(stdout, NULL);
2449 setbuf(stderr, NULL);
2450
2451 /* set default */
2452 host_name[0] = 0;
2453 expt_name[0] = 0;
2454 channel_name[0] = 0;
2456 msg_flag = FALSE;
2457 debug = daemon = FALSE;
2458
2459 /* set default */
2461
2462 /* get parameters */
2463 for (i = 1; i < argc; i++) {
2464 if (argv[i][0] == '-' && argv[i][1] == 'd')
2465 debug = TRUE;
2466 else if (argv[i][0] == '-' && argv[i][1] == 'n')
2467 nodelete = TRUE;
2468 else if (argv[i][0] == '-' && argv[i][1] == 'D')
2469 daemon = TRUE;
2470 else if (strncmp(argv[i], "-C", 2) == 0)
2472 else if (strncmp(argv[i], "-z", 2) == 0)
2473 zap_flag = TRUE;
2474 else if (strncmp(argv[i], "-t", 2) == 0)
2475 msg_flag = TRUE;
2476 else if (argv[i][0] == '-') {
2477 if (i + 1 >= argc || argv[i + 1][0] == '-')
2478 goto usage;
2479 if (strncmp(argv[i], "-e", 2) == 0)
2480 strcpy(expt_name, argv[++i]);
2481 else if (strncmp(argv[i], "-h", 2) == 0)
2482 strcpy(host_name, argv[++i]);
2483 else if (strncmp(argv[i], "-c", 2) == 0)
2484 strcpy(channel_name, argv[++i]);
2485 } else {
2486 usage:
2487 printf("Lazylogger: Multi channel background data copier\n");
2488 printf("\n");
2489 printf("Usage: lazylogger [-d] [-n] [-D] [-h <Hostname>] [-e <Experiment>] [-z] [-t] [-C] -c <channel name>\n");
2490 printf("\n");
2491 printf("Options:\n");
2492 printf(" -c <channel name> - specify lazylogger channel name\n");
2493 printf(" -C - convert old-format done list to new file-based format\n");
2494 printf(" -d - enable debug printout\n");
2495 printf(" -n - do not delete any files (for testing \"Maintain free space\")\n");
2496 printf(" -D - start as a daemon\n");
2497 printf(" -h - connect to experiment on another machine\n");
2498 printf(" -e - connect to non-default experiment\n");
2499 printf(" -z - clear /Lazy/channel/Statistics\n");
2500 printf(" -t - permit lazy logger to TALK (see mlxspeaker)\n");
2501 printf("\n");
2502 printf("Quick man :\n");
2503 printf("The Lazy/Settings tree is composed of the following parameters:\n");
2504 printf("Maintain free space (%%)(0): purge source device to maintain free space on the source directory\n");
2505 printf(" (0) : no purge \n");
2506 printf("Stay behind (0) : If negative number : lazylog runs starting from the OLDEST\n");
2507 printf(" run file sitting in the 'Dir data' to the current acquisition\n");
2508 printf(" run minus the 'Stay behind number'\n");
2509 printf(" If positive number : lazylog starts from the current\n");
2510 printf(" acquisition run minus 'Stay behind number' \n");
2511 printf(" Zero : no stay-behind - files are saved as soon as they are closed\n");
2512 printf("Alarm Class : Specify the Class to be used in case of Tape Full condition\n");
2513 printf("Running condition : active/deactive lazylogger under given condition i.e:\n");
2514 printf(" 'ALWAYS' (default) : Independent of the ACQ state ...\n");
2515 printf(" 'NEVER' : ...\n");
2516 printf(" 'WHILE_ACQ_NOT_RUNNING': ...\n");
2517 printf(" '/alias/max_rate < 200' (max_rate is a link)\n");
2518 printf(" '/equipment/scaler/variables/scal[4] < 23.45'\n");
2519 printf(" '/equipment/trigger/statistics/events per sec. < 400'\n");
2520 printf("Data dir : MIDAS Data Directory (same as \"/Logger/Data Dir\")\n");
2521 printf("Data format : Data format (MIDAS)\n");
2522 printf("Filename format : Run format i.e. \"run%%05d.mid\", or \"*.mid.gz\" or \"*.mid.gz,*.xml\" \n");
2523 printf("List label : Label of destination save_set.\n");
2524 printf(" Prevent lazylogger to run if not given.\n");
2525 printf(" Will be reset if maximum capacity reached.\n");
2526 printf("Execute after rewind : Execute the command <cmd> after rewind complete\n");
2527 printf(" : args passed are: 'device path' 'channel name' 'list label'\n");
2528 printf(" : The actual command will look like: <cmd> /dev/nst0 Tape Data_2000\n");
2529 printf("Backup type : Destination device type (Disk, Tape, Script, SFTP, FTP)\n");
2530 printf("Path : Destination path (file.ext, /dev/nst0, ftp...)\n");
2531 printf(" in case of SFTP type, the 'Path' entry should be:\n");
2532 printf(" sftp://username@host/path\n");
2533 printf(" in case of FTP type, the 'Path' entry should be:\n");
2534 printf(" host, port, user, password, directory, run%%05d.mid\n");
2535 printf("Capacity (Bytes) : Maximum capacity of the destination device.\n");
2536 printf("modulo : Enable multiple lazy on same source. Ex: 3ch : 3.0, 3.1, 3.2\n");
2537 printf("tapeAppend : Enable positioning of the TAPE to EOD before each lazy copy\n");
2538 return 1;
2539 }
2540 }
2541
2542 /* Handle SIGPIPE signals generated from errors on the pipe */
2543#ifdef SIGPIPE
2545#endif
2546 if (daemon) {
2547 printf("Becoming a daemon...\n");
2549 }
2550
2551 /* connect to experiment */
2553 if (status != CM_SUCCESS)
2554 return 1;
2555
2556 /* create a common semaphore for the independent lazylogger */
2558
2559 /* check lazy status for multiple channels */
2561 if (db_find_key(hDB, 0, "/Lazy", &hKey) == DB_SUCCESS) {
2562 HNDLE hSubkey;
2563 KEY key;
2564 INT j = 0;
2565 for (i = 0;; i++) {
2567 if (!hSubkey)
2568 break;
2570 if (key.type == TID_KEY) {
2571 /* compose client name */
2572 std::string strclient;
2573 strclient += "Lazy_";
2574 strclient += key.name;
2575 if (cm_exist(strclient.c_str(), TRUE) == CM_SUCCESS)
2576 lazyinfo[j].active = TRUE;
2577 else
2579 strcpy(lazyinfo[j].name, key.name);
2580
2582 j++;
2583 }
2584 }
2585 } else {
2586 /* create settings tree */
2587 channel = 0;
2588 if (channel_name[0] != 0)
2590 std::string str;
2591 str += "/Lazy/";
2593 str += "/Settings";
2595 }
2596
2597 { /* Selection of client */
2598 INT i, j;
2599 char str[32];
2600
2601 if (lazyinfo[0].hKey) {
2602 if (channel_name[0] == 0) {
2603 /* command prompt */
2604 printf(" Available Lazy channels to connect to:\n");
2605 i = 0;
2606 j = 1;
2607 while (lazyinfo[i].hKey) {
2608 if (!lazyinfo[i].active)
2609 printf("%d) Lazy %s \n", j, lazyinfo[i].name);
2610 else
2611 printf(".) Lazy %s already active\n", lazyinfo[i].name);
2612 j++;
2613 i++;
2614 }
2615 printf("Enter client number or new lazy client name: ");
2616 i = atoi(ss_gets(str, 32));
2617 if ((i == 0) && ((strlen(str) == 0) || (strncmp(str, " ", 1) == 0))) {
2618 cm_msg(MERROR, "Lazy", "Please specify a valid channel name (%s)", str);
2620 return 1;
2621 }
2622 } else {
2623 /* Skip the command prompt for serving the -c option */
2624 /*
2625 scan if channel_name already exists
2626 Yes : check if client is running
2627 Yes : get out (goto error)
2628 No : connect (extract index)
2629 No : new channel (i=0)
2630 */
2631 i = 0;
2632 j = -1;
2633 while (lazyinfo[i].hKey) {
2635 /* correct name => check active */
2636 if (lazyinfo[i].active) {
2637 cm_msg(MERROR, "Lazy", "Lazy channel "
2638 "%s"
2639 " already running!",
2640 lazyinfo[i].name);
2642 return 1;
2643 }
2644 j = i;
2645 }
2646 i++;
2647 }
2648 if (j == -1) {
2649 /* new entry */
2650 i = 0;
2651 mstrlcpy(str, channel_name, sizeof(str));
2652 } else {
2653 /* connect to */
2654 i = j + 1;
2655 }
2656 }
2657
2658 if (i == 0) { /* new entry */
2659 for (j = 0; j < MAX_LAZY_CHANNEL; j++) {
2660 if (lazyinfo[j].hKey == 0) {
2661 /* compose client name */
2662 std::string strclient;
2663 strclient += "Lazy_";
2664 strclient += str;
2665 if (cm_exist(strclient.c_str(), TRUE) == CM_SUCCESS)
2666 lazyinfo[j].active = TRUE;
2667 else
2669 strcpy(lazyinfo[j].name, str);
2670 lazyinfo[j].hKey = 0;
2671 channel = j;
2672 break;
2673 }
2674 }
2675 } else if (!lazyinfo[i - 1].active)
2676 channel = i - 1;
2677 else
2678 channel = -1;
2679 }
2680
2681 if (channel < 0) {
2683 return 1;
2684 }
2685
2686 { /* creation of the lazy channel */
2687 char str[128];
2688
2689 if (lazyinfo[channel].hKey == 0)
2690 printf(" Creating Lazy channel %s\n", lazyinfo[channel].name);
2691
2692 /* create/update settings */
2693 sprintf(str, "/Lazy/%s/Settings", lazyinfo[channel].name);
2695 /* create/update statistics */
2696 sprintf(str, "/Lazy/%s/Statistics", lazyinfo[channel].name);
2698 sprintf(str, "/Lazy/%s", lazyinfo[channel].name);
2700 }
2701 }
2702 /* disconnect from experiment */
2704
2705 { /* reconnect to experiment with proper name */
2706 std::string str;
2707 str += "Lazy_";
2710 }
2711 if (status != CM_SUCCESS) {
2713 return 1;
2714 }
2715
2717
2719
2720 size = sizeof(max_event_size);
2721 status = db_get_value(hDB, 0, "/Experiment/MAX_EVENT_SIZE", &max_event_size, &size, TID_DWORD, TRUE);
2722
2723 /* Remove temporary Lazy entry */
2724 {
2725 HNDLE hPkey;
2726
2727 status = db_find_key(hDB, 0, "Programs/Lazy", &hPkey);
2728 if (status == DB_SUCCESS) {
2730 if (status != DB_SUCCESS) {
2731 cm_msg(MERROR, "Lazy", "Cannot delete /Programs/Lazy");
2732 }
2733 }
2734 }
2735
2736 /* turn on keepalive messages with increased timeout */
2737 if (debug)
2739
2740#ifdef HAVE_FTPLIB
2741 if (debug)
2742 ftp_debug((int (*)(const char *)) puts, (int (*)(const char *)) puts);
2743#endif
2744
2745 printf("Lazy_%s starting... "
2746 "!"
2747 " to exit \n",
2749
2750 if (zap_flag) {
2751 /* reset the statistics */
2752 cm_msg(MINFO, "Lazy", "zapping %s/statistics content", lazyinfo[channel].name);
2753 size = sizeof(lazyst);
2754 memset(&lazyst, 0, size);
2755 if (db_find_key(hDB, lazyinfo[channel].hKey, "Statistics", &hKeyst) == DB_SUCCESS)
2756 status = db_set_record(hDB, hKeyst, &lazyst, size, 0);
2757 else
2758 cm_msg(MERROR, "Lazy", "did not find %s/Statistics for zapping", lazyinfo[channel].name);
2759 }
2760
2761 /* get value once & hot links the run state */
2762 db_find_key(hDB, 0, "/runinfo/state", &hKey);
2763 size = sizeof(run_state);
2764 db_get_data(hDB, hKey, &run_state, &size, TID_INT);
2765 status = db_open_record(hDB, hKey, &run_state, sizeof(run_state), MODE_READ, NULL, NULL); // watch a TID_INT
2766 if (status != DB_SUCCESS) {
2767 cm_msg(MERROR, "Lazy", "cannot open /runinfo/state record");
2768 }
2769 /* hot link for statistics in write mode */
2770 size = sizeof(lazyst);
2771 if (db_find_key(hDB, lazyinfo[channel].hKey, "Statistics", &hKey) == DB_SUCCESS) {
2773 }
2775 if (status == DB_NO_ACCESS) {
2776 /* record is probably still in exclusive access by dead FE, so reset it */
2778 if (status != DB_SUCCESS)
2779 cm_msg(MERROR, "Lazy", "Cannot change access mode for %s/Statistics record, error %d", lazyinfo[channel].name,
2780 status);
2781 else
2782 cm_msg(MINFO, "Lazy", "Recovered access mode for %s/Statistics record", lazyinfo[channel].name);
2784 }
2785 if (status != DB_SUCCESS) {
2786 cm_msg(MERROR, "Lazy", "cannot open %s/Statistics record", lazyinfo[channel].name);
2787 }
2788 /* get /settings once & hot link settings in read mode */
2789 db_find_key(hDB, lazyinfo[channel].hKey, "Settings", &hKey);
2790
2791 size = sizeof(lazy);
2793 if (status != DB_SUCCESS) {
2794 cm_msg(MERROR, "Lazy", "cannot get %s/Settings record, db_get_record() status %d", lazyinfo[channel].name,
2795 status);
2796 }
2797
2799 if (status != DB_SUCCESS) {
2800 cm_msg(MERROR, "Lazy", "cannot open %s/Settings record", lazyinfo[channel].name);
2801 }
2802
2803 /* set global key for that channel */
2805
2806 /* set Data dir from /logger if local is empty & /logger exists */
2807 if ((lazy.dir[0] == '\0') && (db_find_key(hDB, 0, "/Logger/Data dir", &hKey) == DB_SUCCESS)) {
2808 size = sizeof(lazy.dir);
2810 db_set_value(hDB, lazyinfo[channel].hKey, "Settings/Data dir", lazy.dir, size, 1, TID_STRING);
2811 }
2812
2813 // Register for STOP transition
2815 printf("Failed to start local RPC server");
2817
2818 /* let user read message before window might close */
2819 ss_sleep(5000);
2820 return 1;
2821 }
2822
2823 mainlast_time = 0;
2824
2825 /* initialize ss_getchar() */
2826 ss_getchar(0);
2827
2828 DWORD period = lazy.period * 1000;
2829
2830 int ch = 0;
2831
2832 do {
2833 msg = cm_yield(2000);
2834 if (period < 1)
2835 period = 1;
2836 if ((ss_millitime() - mainlast_time) > period) {
2838 if (status == FORCE_EXIT) {
2839 cm_msg(MERROR, "lazy", "Exit requested by program");
2840 break;
2841 }
2843 if (status == TRY_LATER) {
2844 period *= 2;
2845 DWORD max_period = 30 * 60 * 1000;
2846 if (period > max_period)
2847 period = max_period;
2848 cm_msg(MINFO, "lazy", "Will try again after %d seconds", period);
2849 } else {
2850 period = lazy.period * 1000;
2851 }
2852 }
2853
2854 /* check keyboard once every 100 ms */
2855 if (ss_millitime() - last_time_kb > 100) {
2857
2858 ch = 0;
2859 while (ss_kbhit()) {
2860 ch = ss_getchar(0);
2861 if (ch == -1)
2862 ch = getchar();
2863 if ((char) ch == '!')
2864 break;
2865 }
2866 }
2867 } while (msg != RPC_SHUTDOWN && msg != SS_ABORT && ch != '!');
2868
2870 return 1;
2871}
2872
2873/* emacs
2874 * Local Variables:
2875 * tab-width: 8
2876 * c-basic-offset: 3
2877 * indent-tabs-mode: nil
2878 * End:
2879 */
#define FALSE
Definition cfortran.h:309
INT lModulo
Global var for testing passed at BOR.
Definition ebuser.cxx:48
struct usb_device * dev
Definition feccusb.cxx:80
static void usage()
int done
void ftp_debug(int(*debug_func)(const char *message), int(*error_func)(const char *message))
Definition ftplib.cxx:32
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:525
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
Definition alarm.cxx:283
INT cm_register_transition(INT transition, INT(*func)(INT, char *), INT sequence_number)
Definition midas.cxx:3593
INT cm_yield(INT millisec)
Definition midas.cxx:5642
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3317
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
Definition midas.cxx:2297
INT cm_disconnect_experiment(void)
Definition midas.cxx:2846
std::string cm_get_path()
Definition midas.cxx:1537
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2134
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3283
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7520
#define CM_SUCCESS
Definition midas.h:582
#define DB_NO_ACCESS
Definition midas.h:648
#define DB_SUCCESS
Definition midas.h:631
#define SS_SUCCESS
Definition midas.h:663
#define SS_ABORT
Definition midas.h:677
#define SS_FILE_ERROR
Definition midas.h:669
#define SS_INVALID_NAME
Definition midas.h:666
#define SS_NO_SPACE
Definition midas.h:687
#define RPC_SHUTDOWN
Definition midas.h:707
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TID_DOUBLE
Definition midas.h:343
#define TID_KEY
Definition midas.h:349
#define STATE_STOPPED
Definition midas.h:305
#define MINFO
Definition midas.h:560
#define MODE_DELETE
Definition midas.h:372
#define TID_STRING
Definition midas.h:346
#define MODE_WRITE
Definition midas.h:371
#define MERROR
Definition midas.h:559
#define STATE_RUNNING
Definition midas.h:307
#define MODE_READ
Definition midas.h:370
#define FORMAT_MIDAS
Definition midas.h:311
#define MTALK
Definition midas.h:564
#define TID_INT
Definition midas.h:338
#define TR_STOP
Definition midas.h:406
#define TID_DWORD
Definition midas.h:336
#define MD_SUCCESS
Definition mdsupport.h:60
INT md_file_wclose(INT handle, INT type, INT data_fmt, char *destination)
INT md_file_ropen(char *infile, INT data_fmt, INT openzip, INT max_event_size)
INT md_physrec_get(INT data_fmt, void **precord, DWORD *readn)
INT md_file_wopen(INT type, INT data_fmt, char *filename, INT *hDev)
INT md_log_write(INT handle, INT data_fmt, INT type, void *prec, DWORD nbytes)
INT md_file_rclose(INT data_fmt)
#define LOG_TYPE_DISK
Definition msystem.h:493
#define LOG_TYPE_TAPE
Definition msystem.h:494
#define LOG_TYPE_SFTP
Definition msystem.h:496
#define MAX_STRING_LENGTH
Definition msystem.h:113
#define LOG_TYPE_FTP
Definition msystem.h:495
BOOL ss_kbhit()
Definition system.cxx:3664
double ss_disk_size(const char *path)
Definition system.cxx:7048
DWORD ss_millitime()
Definition system.cxx:3393
INT ss_semaphore_create(const char *name, HNDLE *semaphore_handle)
Definition system.cxx:2460
INT ss_getchar(BOOL reset)
Definition system.cxx:7503
INT ss_tape_close(INT channel)
Definition system.cxx:5902
double ss_disk_free(const char *path)
Definition system.cxx:6620
INT ss_tape_get_blockn(INT channel)
Definition system.cxx:6568
double ss_file_size(const char *path)
Definition system.cxx:6972
INT ss_semaphore_release(HNDLE semaphore_handle)
Definition system.cxx:2781
INT ss_tape_spool(INT channel)
Definition system.cxx:6400
INT ss_file_remove(const char *path)
Definition system.cxx:6952
INT ss_daemon_init(BOOL keep_stdout)
Definition system.cxx:2001
DWORD ss_time()
Definition system.cxx:3462
INT ss_sleep(INT millisec)
Definition system.cxx:3628
INT ss_tape_unmount(INT channel)
Definition system.cxx:6512
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
Definition system.cxx:2639
INT ss_tape_open(char *path, INT oflag, INT *channel)
Definition system.cxx:5811
char * ss_gets(char *string, int size)
Definition system.cxx:7770
INT ss_system(const char *command)
Definition system.cxx:2116
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6713
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:973
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6893
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3856
INT db_send_changed_records()
Definition odb.cxx:13777
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
INT db_open_record(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info)
Definition odb.cxx:13291
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition odb.cxx:11805
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6539
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:8027
INT db_save(HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote)
Definition odb.cxx:9245
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13813
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10843
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6261
INT db_open_record1(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info, const char *rec_str)
Definition odb.cxx:13441
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
Definition odb.cxx:12291
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12800
static std::string q(const char *s)
const double MiB
int main()
Definition hwtest.cxx:23
void ** info
Definition fesimdaq.cxx:41
int lazy_disk_copy_loop(const char *outfile, const char *infile, FILE *fpout, FILE *fpin)
INT lazy_run_extract(const char *name)
BOOL lazy_condition_check(void)
INT blockn
#define MAX_FILE_PATH
#define REMOVE_FILE
INT lazy_log_update(INT action, INT run, const char *label, const char *file, DWORD perf_time)
void lazy_maintain_check(HNDLE hKey, LAZY_INFO *pLall)
INT lazy_copy(char *dev, char *file, int max_event_size)
LAZY_STATISTICS lazyst
int find_next_file(const DIRLOGLIST *plog, const DIRLOGLIST *pdone)
double lastsz
INT lazy_semaphore
#define REMOVE_ENTRY
INT lazy_maintain_free_space(LAZY_INFO *pLch, LAZY_INFO *pLall)
#define NEW_FILE
void convert_done_list(HNDLE hLch)
INT build_log_list(const char *fmt, const char *dir, DIRLOGLIST *plog)
LAZY_INFO lazyinfo[MAX_LAZY_CHANNEL]
BOOL full_bck_flag
INT lazy_load_params(HNDLE hDB, HNDLE hKey)
BOOL delay_start
BOOL convert_flag
#define LAZY_SETTINGS_STRING
#define EXIT_REQUEST
INT lazy_disk_copy(const char *outfile, const char *infile)
void load_done_list(const char *lazyname, const DIRLOGLIST *dirlist, DIRLOGLIST *dlist)
void lazy_statistics_update(INT cploop_time)
INT channel
char lazylog[MAX_STRING_LENGTH]
DWORD lazy_time
INT run_state
BOOL debug
debug printouts
BOOL lazy_file_exists(char *dir, char *file)
#define MAX_LAZY_CHANNEL
INT lazy_main(INT, LAZY_INFO *, int max_event_size)
#define FORCE_EXIT
std::vector< DIRLOG > DIRLOGLIST
HNDLE hKey
BOOL stop_transition
#define LAZY_STATISTICS_STRING
INT lazy_file_remove(const char *pufile)
#define TRY_LATER
static void watch_settings(HNDLE hDB, HNDLE hKey, HNDLE index, void *info)
BOOL nodelete
#define NOTHING_TODO
void lazy_settings_hotlink(HNDLE hDB, HNDLE hKey, void *info)
INT save_done_list(HNDLE hLch, DIRLOGLIST *pdone)
INT data_fmt
bool cmp_dirlog1(const DIRLOG &a, const DIRLOG &b)
HNDLE hDB
main ODB handle
BOOL msg_flag
BOOL copy_continue
#define WATCHDOG_TIMEOUT
bool cmp_dirlog(const DIRLOG &a, const DIRLOG &b)
#define DONTOPENZIP
HNDLE pcurrent_hKey
void print_dirlog(const DIRLOGLIST *dirlog)
INT lazy_select_purge(HNDLE hKey, INT channel, LAZY_INFO *pLall, const char *fmt, const char *dir, DIRLOG *f)
#define LOG_TYPE_SCRIPT
BOOL condition_test(char *string)
INT build_done_list_odb(HNDLE, INT **)
std::string list_filename(const char *lazyname, const char *listname)
INT moduloCheck(INT lModulo, INT lPosition, INT lrun)
LAZY_SETTING lazy
INT build_done_list(HNDLE hLch, const DIRLOGLIST *pdirlist, DIRLOGLIST *pdone)
INT hDev
BOOL maintain_touched
INT lazy_trstop(INT rn, char *error)
INT dev_type
int save_list(const char *lazyname, const char *listname, const DIRLOGLIST *dlist)
HNDLE hKeyst
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
BOOL daemon
Definition mana.cxx:258
INT type
Definition mana.cxx:269
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
HNDLE hSubkey
Definition mdump.cxx:35
char expt_name[NAME_LENGTH]
Definition mevb.cxx:44
INT max_event_size
Definition mfed.cxx:30
#define DIR_SEPARATOR
Definition midas.h:193
#define AT_INTERNAL
Definition midas.h:1442
INT HNDLE
Definition midas.h:132
#define HOST_NAME_LENGTH
Definition midas.h:273
DWORD BOOL
Definition midas.h:105
#define DIR_SEPARATOR_STR
Definition midas.h:194
int INT
Definition midas.h:129
#define DEFAULT_MAX_EVENT_SIZE
Definition midas.h:254
#define TRUE
Definition midas.h:182
#define DEFAULT_ODB_SIZE
Definition midas.h:270
#define read(n, a, f)
#define name(x)
Definition midas_macro.h:24
static FILE * fp
static int left(const struct frozen *f)
INT rn
Definition mstat.cxx:30
HNDLE hSet
Definition msysmon.cxx:531
INT j
Definition odbhist.cxx:40
DWORD run
Definition odbhist.cxx:39
double value[100]
Definition odbhist.cxx:42
INT k
Definition odbhist.cxx:40
char str[256]
Definition odbhist.cxx:33
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
INT runno
std::string filename
double size
Definition midas.h:1026
INT num_values
Definition midas.h:1028
DWORD type
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1029
INT item_size
Definition midas.h:1032
char name[32]
char commandAfter[64]
char condition[128]
char command[64]
char alarm[32]
char path[MAX_FILE_PATH]
char commandBefore[64]
char backfmt[MAX_FILE_PATH]
char dir[256]
char backlabel[MAX_FILE_PATH]
char backfile[MAX_FILE_PATH]
double d
Definition system.cxx:1311
static te_expr * list(state *s)
Definition tinyexpr.c:567