]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/cats.h
2e03c40d47a03e08e6f52521e912da166547736e
[bacula/bacula] / bacula / src / cats / cats.h
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Catalog DB header file
21  *
22  *  Written by Kern E. Sibbald
23  *
24  *  Anyone who accesses the database will need to include
25  *   this file.
26  */
27
28 #ifndef __CATS_H_
29 #define __CATS_H_ 1
30
31 /*
32    Here is how database versions work.
33
34    While I am working on a new release with database changes, the
35    update scripts are in the src/cats directory under the names
36    update_xxx_tables.in.  Most of the time, I make database updates
37    in one go and immediately update the version, but not always.  If
38    there are going to be several updates as is the case with version
39    1.37, then I will often forgo changing the version until the last
40    update otherwise I will end up with too many versions and a lot
41    of confusion.
42
43    When I am pretty sure there will be no more updates, I will
44    change the version from 8 to 9 (in the present case), and when I
45    am 100% sure there will be no more changes, the update script
46    will be copied to the updatedb directory with the correct name
47    (in the present case 8 to 9).
48  */
49
50 /* Current database version number for all drivers */
51 #define BDB_VERSION 15
52
53 typedef void (DB_LIST_HANDLER)(void *, const char *);
54 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
55
56 /* What kind of database we have */
57 typedef enum {
58    SQL_TYPE_MYSQL      = 0,
59    SQL_TYPE_POSTGRESQL = 1,
60    SQL_TYPE_SQLITE3    = 2,
61    SQL_TYPE_UNKNOWN    = 99
62 } SQL_DBTYPE;
63
64 /* What kind of driver we have */
65 typedef enum {
66    SQL_DRIVER_TYPE_MYSQL      = 0,
67    SQL_DRIVER_TYPE_POSTGRESQL = 1,
68    SQL_DRIVER_TYPE_SQLITE3    = 2
69 } SQL_DRIVER;
70
71
72 /* ==============================================================
73  *
74  *  What follows are definitions that are used "globally" for all
75  *   the different SQL engines and both inside and external to the
76  *   cats directory.
77  */
78
79 #define faddr_t long
80
81 /*
82  * Generic definition of a sql_row.
83  */
84 typedef char **SQL_ROW;
85
86 /*
87  * Generic definition of a a sql_field.
88  */
89 typedef struct sql_field {
90    char *name;                        /* name of column */
91    int max_length;                    /* max length */
92    uint32_t type;                     /* type */
93    uint32_t flags;                    /* flags */
94 } SQL_FIELD;
95
96
97 /*
98  * Structure used when calling db_get_query_ids()
99  *  allows the subroutine to return a list of ids.
100  */
101 class dbid_list : public SMARTALLOC {
102 public:
103    DBId_t *DBId;                      /* array of DBIds */
104    char *PurgedFiles;                 /* Array of PurgedFile flags */
105    int num_ids;                       /* num of ids actually stored */
106    int max_ids;                       /* size of id array */
107    int num_seen;                      /* number of ids processed */
108    int tot_ids;                       /* total to process */
109
110    dbid_list();                       /* in sql.c */
111    ~dbid_list();                      /* in sql.c */
112 };
113
114 /* Job information passed to create job record and update
115  * job record at end of job. Note, although this record
116  * contains all the fields found in the Job database record,
117  * it also contains fields found in the JobMedia record.
118  */
119 /* Job record */
120 struct JOB_DBR {
121    JobId_t JobId;
122    char Job[MAX_NAME_LENGTH];         /* Job unique name */
123    char Name[MAX_NAME_LENGTH];        /* Job base name */
124    int JobType;                       /* actually char(1) */
125    int JobLevel;                      /* actually char(1) */
126    int JobStatus;                     /* actually char(1) */
127    DBId_t ClientId;                   /* Id of client */
128    DBId_t PoolId;                     /* Id of pool */
129    DBId_t FileSetId;                  /* Id of FileSet */
130    DBId_t PriorJobId;                 /* Id of migrated (prior) job */
131    time_t SchedTime;                  /* Time job scheduled */
132    time_t StartTime;                  /* Job start time */
133    time_t EndTime;                    /* Job termination time of orig job */
134    time_t RealEndTime;                /* Job termination time of this job */
135    utime_t JobTDate;                  /* Backup time/date in seconds */
136    uint32_t VolSessionId;
137    uint32_t VolSessionTime;
138    uint32_t JobFiles;
139    uint32_t JobErrors;
140    uint32_t JobMissingFiles;
141    uint64_t JobBytes;
142    uint64_t ReadBytes;
143    int PurgedFiles;
144    int HasBase;
145
146    /* Note, FirstIndex, LastIndex, Start/End File and Block
147     * are only used in the JobMedia record.
148     */
149    uint32_t FirstIndex;               /* First index this Volume */
150    uint32_t LastIndex;                /* Last index this Volume */
151    uint32_t StartFile;
152    uint32_t EndFile;
153    uint32_t StartBlock;
154    uint32_t EndBlock;
155
156    char cSchedTime[MAX_TIME_LENGTH];
157    char cStartTime[MAX_TIME_LENGTH];
158    char cEndTime[MAX_TIME_LENGTH];
159    char cRealEndTime[MAX_TIME_LENGTH];
160    /* Extra stuff not in DB */
161    int order;                         /* 0 ASC, 1 DESC */
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    char   *exclude_list;                   /* Optionnal exclude list for db_find_next_volume() */
373    bool    set_first_written;
374    bool    set_label_date;
375 };
376
377 /* Client record -- same as the database */
378 struct CLIENT_DBR {
379    DBId_t ClientId;                   /* Unique Client id */
380    int AutoPrune;
381    utime_t FileRetention;
382    utime_t JobRetention;
383    char Name[MAX_NAME_LENGTH];        /* Client name */
384    char Uname[256];                   /* Uname for client */
385 };
386
387 /* Counter record as in database */
388 struct COUNTER_DBR {
389    char Counter[MAX_NAME_LENGTH];
390    int32_t MinValue;
391    int32_t MaxValue;
392    int32_t CurrentValue;
393    char WrapCounter[MAX_NAME_LENGTH];
394 };
395
396
397 /* FileSet record -- same as the database */
398 struct FILESET_DBR {
399    DBId_t FileSetId;                  /* Unique FileSet id */
400    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
401    char MD5[50];                      /* MD5 signature of include/exclude */
402    time_t CreateTime;                 /* date created */
403    /*
404     * This is where we return CreateTime
405     */
406    char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
407    /* Not in DB but returned by db_create_fileset() */
408    bool created;                      /* set when record newly created */
409 };
410
411 class SNAPSHOT_DBR {
412 public:
413    SNAPSHOT_DBR() {
414       memset(this, 0, sizeof(SNAPSHOT_DBR));
415    };
416    ~SNAPSHOT_DBR() {
417       reset();
418    };
419    void debug(int level) {
420       Dmsg8(DT_SNAPSHOT|level,
421             "Snapshot      %s:\n"
422             "  Volume:     %s\n"
423             "  Device:     %s\n"
424             "  Id:         %d\n"
425             "  FileSet:    %s\n"
426             "  CreateDate: %s\n"
427             "  Client:     %s\n"
428             "  Type:       %s\n",
429             Name, NPRT(Volume), NPRT(Device), SnapshotId,
430             FileSet, CreateDate, Client, Type);
431    };
432    char *as_arg(POOLMEM **out) {
433       bash_spaces(Name);
434       bash_spaces(Type);
435
436       if (Volume) {
437          bash_spaces(Volume);
438       }
439       if (Device) {
440          bash_spaces(Device);
441       }
442
443       Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
444            Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
445
446       unbash_spaces(Name);
447       unbash_spaces(Type);
448       if (Volume) {
449          unbash_spaces(Volume);
450       }
451       if (Device) {
452          unbash_spaces(Device);
453       }
454       return *out;
455    };
456    void reset() {
457       if (need_to_free) {
458          if (Volume) {
459             free(Volume);
460          }
461          if (Device) {
462             free(Device);
463          }
464          if (errmsg) {
465             free(errmsg);
466          }
467          errmsg = Volume = Device = NULL;
468       }
469       need_to_free = false;
470    };
471    bool    need_to_free;             /* Need to free the internal memory */
472    /* Used when searching snapshots */
473    char    created_after[MAX_TIME_LENGTH];
474    char    created_before[MAX_TIME_LENGTH];
475    bool    expired;                 /* Look for CreateTDate > (NOW - Retention) */
476    bool    sorted_client;           /* Results sorted by Client, SnapshotId */
477    int     status;                  /* Status of the snapshot */
478
479    DBId_t  SnapshotId;              /* Unique Snapshot ID */
480    DBId_t  JobId;                   /* Related JobId */
481    DBId_t  FileSetId;               /* FileSetId if any */
482    DBId_t  ClientId;                /* From which client this snapshot comes */
483    char    Name[MAX_NAME_LENGTH];   /* Snapshot Name */
484    char    FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
485    char    Client[MAX_NAME_LENGTH]; /* Client name */
486    char    Type[MAX_NAME_LENGTH];   /* zfs, btrfs, lvm, netapp, */
487    char    Comment[MAX_NAME_LENGTH];/* Comment */
488    char    CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
489    time_t  CreateTDate;             /* Create TDate (in sec, since epoch) */
490    char   *Volume;                  /* Volume taken in snapshot */
491    char   *Device;                  /* Device, Pool, Directory, ...  */
492    char   *errmsg;                  /* Error associated with a snapshot */
493    utime_t Retention;               /* Number of second before pruning the snapshot */
494    uint64_t Size;                   /* Snapshot Size */
495 };
496
497 /* Call back context for getting a 32/64 bit value from the database */
498 class db_int64_ctx {
499 public:
500    int64_t value;                     /* value returned */
501    int count;                         /* number of values seen */
502
503    db_int64_ctx() : value(0), count(0) {};
504    ~db_int64_ctx() {};
505 private:
506    db_int64_ctx(const db_int64_ctx&);            /* prohibit pass by value */
507    db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
508 };
509
510 /* Call back context for getting a list of comma separated strings from the
511  * database
512  */
513 class db_list_ctx {
514 public:
515    POOLMEM *list;                     /* list */
516    int count;                         /* number of values seen */
517
518    db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
519    ~db_list_ctx() { free_pool_memory(list); list = NULL; }
520    void reset() { *list = 0; count = 0;}
521    void add(const db_list_ctx &str) {
522       if (str.count > 0) {
523          if (*list) {
524             pm_strcat(list, ",");
525          }
526          pm_strcat(list, str.list);
527          count += str.count;
528       }
529    }
530    void add(const char *str) {
531       if (count > 0) {
532          pm_strcat(list, ",");
533       }
534       pm_strcat(list, str);
535       count++;
536    }
537 private:
538    db_list_ctx(const db_list_ctx&);            /* prohibit pass by value */
539    db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
540 };
541
542 /* sql_query flags */
543 #define QF_STORE_RESULT 0x01
544  
545 /* sql_list.c */
546 enum e_list_type {
547    HORZ_LIST,                   /* list */
548    VERT_LIST,                   /* llist */
549    ARG_LIST,                    /* key1=v1 key2=v2 key3=v3 */
550    FAILED_JOBS,
551    INCOMPLETE_JOBS
552 };
553  
554 #include "bdb.h"
555 #include "protos.h"
556 #include "jcr.h"
557 #include "sql_cmds.h"
558
559
560 /* Object used in db_list_xxx function */
561 class LIST_CTX {
562 public:
563    char line[256];              /* Used to print last dash line */
564    int32_t num_rows;
565
566    e_list_type type;            /* Vertical/Horizontal */
567    DB_LIST_HANDLER *send;       /* send data back */
568    bool once;                   /* Used to print header one time */
569    void *ctx;                   /* send() user argument */
570    BDB *mdb;
571    JCR *jcr;
572
573    void empty() {
574       once = false;
575       line[0] = '\0';
576    }
577
578    void send_dashes() {
579       if (*line) {
580          send(ctx, line);
581       }
582    }
583
584    LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
585       line[0] = '\0';
586       once = false;
587       num_rows = 0;
588       type = t;
589       send = h;
590       ctx = c;
591       jcr = j;
592       mdb = m;
593    }
594 };
595
596 /* Functions exported by sql.c for use within the cats directory. */
597 int list_result(void *vctx, int cols, char **row);
598 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
599 int get_sql_record_max(JCR *jcr, BDB *mdb);
600 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
601
602 void print_dashes(BDB *mdb);
603 void print_result(BDB *mdb);
604 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
605 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
606 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
607 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
608
609 #endif  /* __CATS_H_ */