]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/cats.h
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / cats / cats.h
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  *  Catalog DB header file
22  *
23  *  Written by Kern E. Sibbald
24  *
25  *  Anyone who accesses the database will need to include
26  *   this file.
27  */
28
29 #ifndef __CATS_H_
30 #define __CATS_H_ 1
31
32 /*
33    Here is how database versions work.
34
35    While I am working on a new release with database changes, the
36    update scripts are in the src/cats directory under the names
37    update_xxx_tables.in.  Most of the time, I make database updates
38    in one go and immediately update the version, but not always.  If
39    there are going to be several updates as is the case with version
40    1.37, then I will often forgo changing the version until the last
41    update otherwise I will end up with too many versions and a lot
42    of confusion.
43
44    When I am pretty sure there will be no more updates, I will
45    change the version from 8 to 9 (in the present case), and when I
46    am 100% sure there will be no more changes, the update script
47    will be copied to the updatedb directory with the correct name
48    (in the present case 8 to 9).
49  */
50
51 /* Current database version number for all drivers */
52 #define BDB_VERSION 15
53
54 typedef void (DB_LIST_HANDLER)(void *, const char *);
55 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
56
57 /* What kind of database we have */
58 typedef enum {
59    SQL_TYPE_MYSQL      = 0,
60    SQL_TYPE_POSTGRESQL = 1,
61    SQL_TYPE_SQLITE3    = 2,
62    SQL_TYPE_UNKNOWN    = 99
63 } SQL_DBTYPE;
64
65 /* What kind of driver we have */
66 typedef enum {
67    SQL_DRIVER_TYPE_MYSQL      = 0,
68    SQL_DRIVER_TYPE_POSTGRESQL = 1,
69    SQL_DRIVER_TYPE_SQLITE3    = 2,
70 } SQL_DRIVER;
71
72
73 /* ==============================================================
74  *
75  *  What follows are definitions that are used "globally" for all
76  *   the different SQL engines and both inside and external to the
77  *   cats directory.
78  */
79
80 #define faddr_t long
81
82 /*
83  * Generic definition of a sql_row.
84  */
85 typedef char **SQL_ROW;
86
87 /*
88  * Generic definition of a a sql_field.
89  */
90 typedef struct sql_field {
91    char *name;                        /* name of column */
92    int max_length;                    /* max length */
93    uint32_t type;                     /* type */
94    uint32_t flags;                    /* flags */
95 } SQL_FIELD;
96
97
98 /*
99  * Structure used when calling db_get_query_ids()
100  *  allows the subroutine to return a list of ids.
101  */
102 class dbid_list : public SMARTALLOC {
103 public:
104    DBId_t *DBId;                      /* array of DBIds */
105    char *PurgedFiles;                 /* Array of PurgedFile flags */
106    int num_ids;                       /* num of ids actually stored */
107    int max_ids;                       /* size of id array */
108    int num_seen;                      /* number of ids processed */
109    int tot_ids;                       /* total to process */
110
111    dbid_list();                       /* in sql.c */
112    ~dbid_list();                      /* in sql.c */
113 };
114
115 /* Job information passed to create job record and update
116  * job record at end of job. Note, although this record
117  * contains all the fields found in the Job database record,
118  * it also contains fields found in the JobMedia record.
119  */
120 /* Job record */
121 struct JOB_DBR {
122    JobId_t JobId;
123    char Job[MAX_NAME_LENGTH];         /* Job unique name */
124    char Name[MAX_NAME_LENGTH];        /* Job base name */
125    int JobType;                       /* actually char(1) */
126    int JobLevel;                      /* actually char(1) */
127    int JobStatus;                     /* actually char(1) */
128    DBId_t ClientId;                   /* Id of client */
129    DBId_t PoolId;                     /* Id of pool */
130    DBId_t FileSetId;                  /* Id of FileSet */
131    DBId_t PriorJobId;                 /* Id of migrated (prior) job */
132    time_t SchedTime;                  /* Time job scheduled */
133    time_t StartTime;                  /* Job start time */
134    time_t EndTime;                    /* Job termination time of orig job */
135    time_t RealEndTime;                /* Job termination time of this job */
136    utime_t JobTDate;                  /* Backup time/date in seconds */
137    uint32_t VolSessionId;
138    uint32_t VolSessionTime;
139    uint32_t JobFiles;
140    uint32_t JobErrors;
141    uint32_t JobMissingFiles;
142    uint64_t JobBytes;
143    uint64_t ReadBytes;
144    int PurgedFiles;
145    int HasBase;
146
147    /* Note, FirstIndex, LastIndex, Start/End File and Block
148     * are only used in the JobMedia record.
149     */
150    uint32_t FirstIndex;               /* First index this Volume */
151    uint32_t LastIndex;                /* Last index this Volume */
152    uint32_t StartFile;
153    uint32_t EndFile;
154    uint32_t StartBlock;
155    uint32_t EndBlock;
156
157    char cSchedTime[MAX_TIME_LENGTH];
158    char cStartTime[MAX_TIME_LENGTH];
159    char cEndTime[MAX_TIME_LENGTH];
160    char cRealEndTime[MAX_TIME_LENGTH];
161    /* Extra stuff not in DB */
162    int limit;                         /* limit records to display */
163    faddr_t rec_addr;
164    uint32_t FileIndex;                /* added during Verify */
165 };
166
167 /* Job Media information used to create the media records
168  * for each Volume used for the job.
169  */
170 /* JobMedia record */
171 struct JOBMEDIA_DBR {
172    DBId_t JobMediaId;                 /* record id */
173    JobId_t  JobId;                    /* JobId */
174    DBId_t MediaId;                    /* MediaId */
175    uint32_t FirstIndex;               /* First index this Volume */
176    uint32_t LastIndex;                /* Last index this Volume */
177    uint32_t StartFile;                /* File for start of data */
178    uint32_t EndFile;                  /* End file on Volume */
179    uint32_t StartBlock;               /* start block on tape */
180    uint32_t EndBlock;                 /* last block */
181 };
182
183
184 /* Volume Parameter structure */
185 struct VOL_PARAMS {
186    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
187    char MediaType[MAX_NAME_LENGTH];   /* Media Type */
188    char Storage[MAX_NAME_LENGTH];     /* Storage name */
189    uint32_t VolIndex;                 /* Volume seqence no. */
190    uint32_t FirstIndex;               /* First index this Volume */
191    uint32_t LastIndex;                /* Last index this Volume */
192    int32_t Slot;                      /* Slot */
193    uint64_t StartAddr;                /* Start address */
194    uint64_t EndAddr;                  /* End address */
195    int32_t InChanger;                 /* InChanger flag */
196 };
197
198
199 /* Attributes record -- NOT same as in database because
200  *  in general, this "record" creates multiple database
201  *  records (e.g. pathname, filename, fileattributes).
202  */
203 struct ATTR_DBR {
204    char *fname;                       /* full path & filename */
205    char *link;                        /* link if any */
206    char *attr;                        /* attributes statp */
207    uint32_t FileIndex;
208    uint32_t Stream;
209    uint32_t FileType;
210    uint32_t DeltaSeq;
211    JobId_t  JobId;
212    DBId_t ClientId;
213    DBId_t PathId;
214    DBId_t FilenameId;
215    FileId_t FileId;
216    char *Digest;
217    int DigestType;
218 };
219
220 struct ROBJECT_DBR {
221    char *object_name;
222    char *object;
223    char *plugin_name;
224    char *JobIds;
225    uint32_t object_len;
226    uint32_t object_full_len;
227    uint32_t object_index;
228    int32_t  object_compression;
229    uint32_t FileIndex;
230    uint32_t Stream;
231    uint32_t FileType;
232    JobId_t  JobId;
233    DBId_t RestoreObjectId;
234 };
235
236
237 /* File record -- same format as database */
238 struct FILE_DBR {
239    FileId_t FileId;
240    uint32_t FileIndex;
241    JobId_t  JobId;
242    DBId_t FilenameId;
243    DBId_t PathId;
244    JobId_t  MarkId;
245    uint32_t DeltaSeq;
246    char LStat[256];
247    char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
248    int DigestType;                    /* NO_SIG/MD5_SIG/SHA1_SIG */
249 };
250
251 /* Pool record -- same format as database */
252 struct POOL_DBR {
253    DBId_t PoolId;
254    char Name[MAX_NAME_LENGTH];        /* Pool name */
255    uint32_t NumVols;                  /* total number of volumes */
256    uint32_t MaxVols;                  /* max allowed volumes */
257    int32_t LabelType;                 /* Bacula/ANSI/IBM */
258    int32_t UseOnce;                   /* set to use once only */
259    int32_t UseCatalog;                /* set to use catalog */
260    int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
261    int32_t AutoPrune;                 /* set to prune automatically */
262    int32_t Recycle;                   /* default Vol recycle flag */
263    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
264    utime_t  VolRetention;             /* retention period in seconds */
265    utime_t  VolUseDuration;           /* time in secs volume can be used */
266    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
267    uint32_t MaxVolFiles;              /* Max files on Volume */
268    uint64_t MaxVolBytes;              /* Max bytes on Volume */
269    DBId_t RecyclePoolId;              /* RecyclePool destination when media is purged */
270    DBId_t ScratchPoolId;              /* ScratchPool source when media is needed */
271    char PoolType[MAX_NAME_LENGTH];
272    char LabelFormat[MAX_NAME_LENGTH];
273    /* Extra stuff not in DB */
274    faddr_t rec_addr;
275 };
276
277 class DEVICE_DBR {
278 public:
279    DBId_t DeviceId;
280    char Name[MAX_NAME_LENGTH];        /* Device name */
281    DBId_t MediaTypeId;                /* MediaType */
282    DBId_t StorageId;                  /* Storage id if autochanger */
283    uint32_t DevMounts;                /* Number of times mounted */
284    uint32_t DevErrors;                /* Number of read/write errors */
285    uint64_t DevReadBytes;             /* Number of bytes read */
286    uint64_t DevWriteBytes;            /* Number of bytew written */
287    uint64_t DevReadTime;              /* time spent reading volume */
288    uint64_t DevWriteTime;             /* time spent writing volume */
289    uint64_t DevReadTimeSincCleaning;  /* read time since cleaning */
290    uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
291    time_t   CleaningDate;             /* time last cleaned */
292    utime_t  CleaningPeriod;           /* time between cleanings */
293 };
294
295 class STORAGE_DBR {
296 public:
297    DBId_t StorageId;
298    char Name[MAX_NAME_LENGTH];        /* Device name */
299    int AutoChanger;                   /* Set if autochanger */
300
301    /* Not in database */
302    bool created;                      /* set if created by db_create ... */
303 };
304
305 class MEDIATYPE_DBR {
306 public:
307    DBId_t MediaTypeId;
308    char MediaType[MAX_NAME_LENGTH];   /* MediaType string */
309    int ReadOnly;                      /* Set if read-only */
310 };
311
312 /* Media record -- same as the database */
313 class MEDIA_DBR {
314 public:
315    MEDIA_DBR() { memset(this, 0, sizeof(MEDIA_DBR)); };
316    ~MEDIA_DBR() {  };
317    void clear() { memset(this, 0, sizeof(MEDIA_DBR)); };
318    void copy(MEDIA_DBR *omr) { memcpy(this, omr, sizeof(MEDIA_DBR)); };
319
320    DBId_t MediaId;                    /* Unique volume id */
321    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
322    char MediaType[MAX_NAME_LENGTH];   /* Media type */
323    DBId_t PoolId;                     /* Pool id */
324    time_t   FirstWritten;             /* Time Volume first written this usage */
325    time_t   LastWritten;              /* Time Volume last written */
326    time_t   LabelDate;                /* Date/Time Volume labeled */
327    time_t   InitialWrite;             /* Date/Time Volume first written */
328    int32_t  LabelType;                /* Label (Bacula/ANSI/IBM) */
329    uint32_t VolJobs;                  /* number of jobs on this medium */
330    uint32_t VolFiles;                 /* Number of files */
331    uint32_t VolBlocks;                /* Number of blocks */
332    uint32_t VolMounts;                /* Number of times mounted */
333    uint32_t VolErrors;                /* Number of read/write errors */
334    uint64_t VolWrites;                /* Number of writes */
335    uint64_t VolReads;                 /* Number of reads */
336    uint64_t VolBytes;                 /* Number of bytes written */
337    uint64_t VolABytes;                /* Size of aligned volume */
338    uint64_t VolHoleBytes;             /* The size of Holes */
339    uint32_t VolHoles;                 /* Number of holes */
340    uint32_t VolType;                  /* Device type of where Volume labeled */
341    uint64_t MaxVolBytes;              /* Max bytes to write to Volume */
342    uint64_t VolCapacityBytes;         /* capacity estimate */
343    uint64_t VolReadTime;              /* time spent reading volume */
344    uint64_t VolWriteTime;             /* time spent writing volume */
345    utime_t  VolRetention;             /* Volume retention in seconds */
346    utime_t  VolUseDuration;           /* time in secs volume can be used */
347    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
348    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
349    uint32_t MaxVolFiles;              /* Max files on Volume */
350    int32_t  Recycle;                  /* recycle yes/no */
351    int32_t  Slot;                     /* slot in changer */
352    int32_t  Enabled;                  /* 0=disabled, 1=enabled, 2=archived */
353    int32_t  InChanger;                /* Volume currently in changer */
354    DBId_t   StorageId;                /* Storage record Id */
355    uint32_t EndFile;                  /* Last file on volume */
356    uint32_t EndBlock;                 /* Last block on volume */
357    uint32_t RecycleCount;             /* Number of times recycled */
358    char     VolStatus[20];            /* Volume status */
359    DBId_t   DeviceId;                 /* Device where Vol last written */
360    DBId_t   LocationId;               /* Where Volume is -- user defined */
361    DBId_t   ScratchPoolId;            /* Where to move if scratch */
362    DBId_t   RecyclePoolId;            /* Where to move when recycled */
363    /* Extra stuff not in DB */
364    faddr_t rec_addr;                  /* found record address */
365    /* Since the database returns times as strings, this is how we pass
366     *   them back.
367     */
368    char    cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */
369    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
370    char    cLabelDate[MAX_TIME_LENGTH];    /* LabelData returned from DB */
371    char    cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
372    bool    set_first_written;
373    bool    set_label_date;
374 };
375
376 /* Client record -- same as the database */
377 struct CLIENT_DBR {
378    DBId_t ClientId;                   /* Unique Client id */
379    int AutoPrune;
380    utime_t FileRetention;
381    utime_t JobRetention;
382    char Name[MAX_NAME_LENGTH];        /* Client name */
383    char Uname[256];                   /* Uname for client */
384 };
385
386 /* Counter record as in database */
387 struct COUNTER_DBR {
388    char Counter[MAX_NAME_LENGTH];
389    int32_t MinValue;
390    int32_t MaxValue;
391    int32_t CurrentValue;
392    char WrapCounter[MAX_NAME_LENGTH];
393 };
394
395
396 /* FileSet record -- same as the database */
397 struct FILESET_DBR {
398    DBId_t FileSetId;                  /* Unique FileSet id */
399    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
400    char MD5[50];                      /* MD5 signature of include/exclude */
401    time_t CreateTime;                 /* date created */
402    /*
403     * This is where we return CreateTime
404     */
405    char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
406    /* Not in DB but returned by db_create_fileset() */
407    bool created;                      /* set when record newly created */
408 };
409
410 class SNAPSHOT_DBR {
411 public:
412    SNAPSHOT_DBR() {
413       memset(this, 0, sizeof(SNAPSHOT_DBR));
414    };
415    ~SNAPSHOT_DBR() {
416       reset();
417    };
418    void debug(int level) {
419       Dmsg8(DT_SNAPSHOT|level,
420             "Snapshot      %s:\n"
421             "  Volume:     %s\n"
422             "  Device:     %s\n"
423             "  Id:         %d\n"
424             "  FileSet:    %s\n"
425             "  CreateDate: %s\n"
426             "  Client:     %s\n"
427             "  Type:       %s\n",
428             Name, NPRT(Volume), NPRT(Device), SnapshotId,
429             FileSet, CreateDate, Client, Type);
430    };
431    char *as_arg(POOLMEM **out) {
432       bash_spaces(Name);
433       bash_spaces(Type);
434
435       if (Volume) {
436          bash_spaces(Volume);
437       }
438       if (Device) {
439          bash_spaces(Device);
440       }
441
442       Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
443            Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
444
445       unbash_spaces(Name);
446       unbash_spaces(Type);
447       if (Volume) {
448          unbash_spaces(Volume);
449       }
450       if (Device) {
451          unbash_spaces(Device);
452       }
453       return *out;
454    };
455    void reset() {
456       if (need_to_free) {
457          if (Volume) {
458             free(Volume);
459          }
460          if (Device) {
461             free(Device);
462          }
463          if (errmsg) {
464             free(errmsg);
465          }
466          errmsg = Volume = Device = NULL;
467       }
468       need_to_free = false;
469    };
470    bool    need_to_free;             /* Need to free the internal memory */
471    /* Used when searching snapshots */
472    char    created_after[MAX_TIME_LENGTH];
473    char    created_before[MAX_TIME_LENGTH];
474    bool    expired;                 /* Look for CreateTDate > (NOW - Retention) */
475    bool    sorted_client;           /* Results sorted by Client, SnapshotId */
476    int     status;                  /* Status of the snapshot */
477
478    DBId_t  SnapshotId;              /* Unique Snapshot ID */
479    DBId_t  JobId;                   /* Related JobId */
480    DBId_t  FileSetId;               /* FileSetId if any */
481    DBId_t  ClientId;                /* From which client this snapshot comes */
482    char    Name[MAX_NAME_LENGTH];   /* Snapshot Name */
483    char    FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
484    char    Client[MAX_NAME_LENGTH]; /* Client name */
485    char    Type[MAX_NAME_LENGTH];   /* zfs, btrfs, lvm, netapp, */
486    char    Comment[MAX_NAME_LENGTH];/* Comment */
487    char    CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
488    time_t  CreateTDate;             /* Create TDate (in sec, since epoch) */
489    char   *Volume;                  /* Volume taken in snapshot */
490    char   *Device;                  /* Device, Pool, Directory, ...  */
491    char   *errmsg;                  /* Error associated with a snapshot */
492    utime_t Retention;               /* Number of second before pruning the snapshot */
493    uint64_t Size;                   /* Snapshot Size */
494 };
495
496 /* Call back context for getting a 32/64 bit value from the database */
497 class db_int64_ctx {
498 public:
499    int64_t value;                     /* value returned */
500    int count;                         /* number of values seen */
501
502    db_int64_ctx() : value(0), count(0) {};
503    ~db_int64_ctx() {};
504 private:
505    db_int64_ctx(const db_int64_ctx&);            /* prohibit pass by value */
506    db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
507 };
508
509 /* Call back context for getting a list of comma separated strings from the
510  * database
511  */
512 class db_list_ctx {
513 public:
514    POOLMEM *list;                     /* list */
515    int count;                         /* number of values seen */
516
517    db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
518    ~db_list_ctx() { free_pool_memory(list); list = NULL; }
519    void reset() { *list = 0; count = 0;}
520    void add(const db_list_ctx &str) {
521       if (str.count > 0) {
522          if (*list) {
523             pm_strcat(list, ",");
524          }
525          pm_strcat(list, str.list);
526          count += str.count;
527       }
528    }
529    void add(const char *str) {
530       if (count > 0) {
531          pm_strcat(list, ",");
532       }
533       pm_strcat(list, str);
534       count++;
535    }
536 private:
537    db_list_ctx(const db_list_ctx&);            /* prohibit pass by value */
538    db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
539 };
540
541 /* sql_query flags */
542 #define QF_STORE_RESULT 0x01
543  
544 /* sql_list.c */
545 enum e_list_type {
546    HORZ_LIST,                   /* list */
547    VERT_LIST,                   /* llist */
548    ARG_LIST,                    /* key1=v1 key2=v2 key3=v3 */
549    FAILED_JOBS,
550    INCOMPLETE_JOBS
551 };
552  
553 #include "bdb.h"
554 #include "protos.h"
555 #include "jcr.h"
556 #include "sql_cmds.h"
557
558
559 /* Object used in db_list_xxx function */
560 class LIST_CTX {
561 public:
562    char line[256];              /* Used to print last dash line */
563    int32_t num_rows;
564
565    e_list_type type;            /* Vertical/Horizontal */
566    DB_LIST_HANDLER *send;       /* send data back */
567    bool once;                   /* Used to print header one time */
568    void *ctx;                   /* send() user argument */
569    BDB *mdb;
570    JCR *jcr;
571
572    void empty() {
573       once = false;
574       line[0] = '\0';
575    }
576
577    void send_dashes() {
578       if (*line) {
579          send(ctx, line);
580       }
581    }
582
583    LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
584       line[0] = '\0';
585       once = false;
586       num_rows = 0;
587       type = t;
588       send = h;
589       ctx = c;
590       jcr = j;
591       mdb = m;
592    }
593 };
594
595 /* Functions exported by sql.c for use within the cats directory. */
596 int list_result(void *vctx, int cols, char **row);
597 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
598 int get_sql_record_max(JCR *jcr, BDB *mdb);
599 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
600
601 void print_dashes(BDB *mdb);
602 void print_result(BDB *mdb);
603 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
604 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
605 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
606 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
607
608 #endif  /* __CATS_H_ */