1 /* 2 BAREOS® - Backup Archiving REcovery Open Sourced 3 4 Copyright (C) 2000-2012 Free Software Foundation Europe e.V. 5 Copyright (C) 2011-2016 Planets Communications B.V. 6 Copyright (C) 2013-2018 Bareos GmbH & Co. KG 7 8 This program is Free Software; you can redistribute it and/or 9 modify it under the terms of version three of the GNU Affero General Public 10 License as published by the Free Software Foundation and included 11 in the file LICENSE. 12 13 This program is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Affero General Public License for more details. 17 18 You should have received a copy of the GNU Affero General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 02110-1301, USA. 22 */ 23 /* 24 * Catalog header file 25 * 26 * by Kern E. Sibbald 27 */ 28 /** 29 * @file 30 * Catalog header file 31 * Anyone who accesses the database will need to include 32 * this file. 33 */ 34 35 #ifndef BAREOS_CATS_CATS_H_ 36 #define BAREOS_CATS_CATS_H_ 1 37 38 /* import automatically generated SQL_QUERY_ENUM */ 39 #include "bdb_query_enum_class.h" 40 41 /* ============================================================== 42 * 43 * What follows are definitions that are used "globally" for all 44 * the different SQL engines and both inside and external to the 45 * cats directory. 46 */ 47 48 #define faddr_t long 49 50 struct VolumeSessionInfo; 51 52 /** 53 * Generic definitions of list types, list handlers and result handlers. 54 */ 55 enum e_list_type 56 { 57 NF_LIST, 58 RAW_LIST, 59 HORZ_LIST, 60 VERT_LIST 61 }; 62 63 /** 64 * Structure used when calling db_get_query_ids() 65 * allows the subroutine to return a list of ids. 66 */ 67 class dbid_list : public SmartAlloc { 68 public: 69 DBId_t* DBId; /**< array of DBIds */ 70 char* PurgedFiles; /**< Array of PurgedFile flags */ 71 int num_ids; /**< num of ids actually stored */ 72 int max_ids; /**< size of id array */ 73 int num_seen; /**< number of ids processed */ 74 int tot_ids; /**< total to process */ 75 76 dbid_list(); /**< in sql.c */ 77 ~dbid_list(); /**< in sql.c */ 78 size()79 int size() const { return num_ids; } 80 DBId_t get(int i) const; 81 }; 82 83 /** 84 * Job information passed to create job record and update 85 * job record at end of job. Note, although this record 86 * contains all the fields found in the Job database record, 87 * it also contains fields found in the JobMedia record. 88 */ 89 90 /** 91 * Job record 92 */ 93 struct JobDbRecord { 94 JobId_t JobId; 95 char Job[MAX_NAME_LENGTH]; /**< Job unique name */ 96 char Name[MAX_NAME_LENGTH]; /**< Job base name */ 97 int JobType; /**< actually char(1) */ 98 int JobLevel; /**< actually char(1) */ 99 int JobStatus; /**< actually char(1) */ 100 DBId_t ClientId; /**< Id of client */ 101 DBId_t PoolId; /**< Id of pool */ 102 DBId_t FileSetId; /**< Id of FileSet */ 103 DBId_t PriorJobId; /**< Id of migrated (prior) job */ 104 time_t SchedTime; /**< Time job scheduled */ 105 time_t StartTime; /**< Job start time */ 106 time_t EndTime; /**< Job termination time of orig job */ 107 time_t RealEndTime; /**< Job termination time of this job */ 108 utime_t JobTDate; /**< Backup time/date in seconds */ 109 uint32_t VolSessionId; 110 uint32_t VolSessionTime; 111 uint32_t JobFiles; 112 uint32_t JobErrors; 113 uint32_t JobMissingFiles; 114 uint64_t JobBytes; 115 uint64_t ReadBytes; 116 uint64_t JobSumTotalBytes; /**< Total sum in bytes of all jobs but this one */ 117 int PurgedFiles; 118 int HasBase; 119 120 /* Note, FirstIndex, LastIndex, Start/End File and Block 121 * are only used in the JobMedia record. 122 */ 123 uint32_t FirstIndex; /**< First index this Volume */ 124 uint32_t LastIndex; /**< Last index this Volume */ 125 uint32_t StartFile; 126 uint32_t EndFile; 127 uint32_t StartBlock; 128 uint32_t EndBlock; 129 130 char cSchedTime[MAX_TIME_LENGTH]; 131 char cStartTime[MAX_TIME_LENGTH]; 132 char cEndTime[MAX_TIME_LENGTH]; 133 char cRealEndTime[MAX_TIME_LENGTH]; 134 135 /* 136 * Extra stuff not in DB 137 */ 138 int limit; /**< limit records to display */ 139 int offset; /**< offset records to display */ 140 faddr_t rec_addr; 141 uint32_t FileIndex; /**< added during Verify */ 142 }; 143 144 /* Job Media information used to create the media records 145 * for each Volume used for the job. 146 */ 147 /** 148 * JobMedia record 149 */ 150 struct JobMediaDbRecord { 151 DBId_t JobMediaId; /**< record id */ 152 JobId_t JobId; /**< JobId */ 153 DBId_t MediaId; /**< MediaId */ 154 uint32_t FirstIndex; /**< First index this Volume */ 155 uint32_t LastIndex; /**< Last index this Volume */ 156 uint32_t StartFile; /**< File for start of data */ 157 uint32_t EndFile; /**< End file on Volume */ 158 uint32_t StartBlock; /**< start block on tape */ 159 uint32_t EndBlock; /**< last block */ 160 uint64_t JobBytes; /**< job bytes */ 161 }; 162 163 164 /** 165 * Volume Parameter structure 166 */ 167 struct VolumeParameters { 168 char VolumeName[MAX_NAME_LENGTH]; /**< Volume name */ 169 char MediaType[MAX_NAME_LENGTH]; /**< Media Type */ 170 char Storage[MAX_NAME_LENGTH]; /**< Storage name */ 171 uint32_t VolIndex; /**< Volume seqence no. */ 172 uint32_t FirstIndex; /**< First index this Volume */ 173 uint32_t LastIndex; /**< Last index this Volume */ 174 int32_t Slot; /**< Slot */ 175 uint64_t StartAddr; /**< Start address */ 176 uint64_t EndAddr; /**< End address */ 177 int32_t InChanger; /**< InChanger flag */ 178 uint64_t JobBytes; /**< job bytes */ 179 // uint32_t Copy; /**< identical copy */ 180 // uint32_t Stripe; /**< RAIT strip number */ 181 }; 182 183 /** 184 * Attributes record -- NOT same as in database because 185 * in general, this "record" creates multiple database 186 * records (e.g. pathname, filename, fileattributes). 187 */ 188 struct AttributesDbRecord { 189 char* fname; /**< full path & filename */ 190 char* link; /**< link if any */ 191 char* attr; /**< attributes statp */ 192 uint32_t FileIndex; 193 uint32_t Stream; 194 uint32_t FileType; 195 uint32_t DeltaSeq; 196 JobId_t JobId; 197 DBId_t ClientId; 198 DBId_t PathId; 199 FileId_t FileId; 200 char* Digest; 201 int DigestType; 202 uint64_t Fhinfo; /**< NDMP fh_info for DAR*/ 203 uint64_t Fhnode; /**< NDMP fh_node for DAR*/ 204 }; 205 206 /** 207 * Restore object database record 208 */ 209 struct RestoreObjectDbRecord { 210 char* object_name; 211 char* object; 212 char* plugin_name; 213 uint32_t object_len; 214 uint32_t object_full_len; 215 uint32_t object_index; 216 int32_t object_compression; 217 uint32_t FileIndex; 218 uint32_t Stream; 219 uint32_t FileType; 220 JobId_t JobId; 221 DBId_t RestoreObjectId; 222 }; 223 224 /** 225 * File record -- same format as database 226 */ 227 struct FileDbRecord { 228 FileId_t FileId; 229 uint32_t FileIndex; 230 JobId_t JobId; 231 DBId_t PathId; 232 JobId_t MarkId; 233 uint32_t DeltaSeq; 234 char LStat[256]; 235 char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; 236 int DigestType; /**< NO_SIG/MD5_SIG/SHA1_SIG */ 237 }; 238 239 /** 240 * Pool record -- same format as database 241 */ 242 struct PoolDbRecord { 243 DBId_t PoolId; 244 char Name[MAX_NAME_LENGTH]; /**< Pool name */ 245 uint32_t NumVols; /**< total number of volumes */ 246 uint32_t MaxVols; /**< max allowed volumes */ 247 int32_t LabelType; /**< BAREOS/ANSI/IBM */ 248 int32_t UseOnce; /**< set to use once only */ 249 int32_t UseCatalog; /**< set to use catalog */ 250 int32_t AcceptAnyVolume; /**< set to accept any volume sequence */ 251 int32_t AutoPrune; /**< set to prune automatically */ 252 int32_t Recycle; /**< default Vol recycle flag */ 253 uint32_t ActionOnPurge; /**< action on purge, e.g. truncate the disk volume */ 254 utime_t VolRetention; /**< retention period in seconds */ 255 utime_t VolUseDuration; /**< time in secs volume can be used */ 256 uint32_t MaxVolJobs; /**< Max Jobs on Volume */ 257 uint32_t MaxVolFiles; /**< Max files on Volume */ 258 uint64_t MaxVolBytes; /**< Max bytes on Volume */ 259 DBId_t RecyclePoolId; /**< RecyclePool destination when media is purged */ 260 DBId_t ScratchPoolId; /**< ScratchPool source when media is needed */ 261 char PoolType[MAX_NAME_LENGTH]; 262 char LabelFormat[MAX_NAME_LENGTH]; 263 uint32_t MinBlocksize; /**< Minimum Block Size */ 264 uint32_t MaxBlocksize; /**< Maximum Block Size */ 265 266 /* 267 * Extra stuff not in DB 268 */ 269 faddr_t rec_addr; 270 }; 271 272 /** 273 * Device record 274 */ 275 struct DeviceDbRecord { 276 DBId_t DeviceId; 277 char Name[MAX_NAME_LENGTH]; /**< Device name */ 278 DBId_t MediaTypeId; /**< MediaType */ 279 DBId_t StorageId; /**< Storage id if autochanger */ 280 uint32_t DevMounts; /**< Number of times mounted */ 281 uint32_t DevErrors; /**< Number of read/write errors */ 282 uint64_t DevReadBytes; /**< Number of bytes read */ 283 uint64_t DevWriteBytes; /**< Number of bytes written */ 284 uint64_t DevReadTime; /**< time spent reading volume */ 285 uint64_t DevWriteTime; /**< time spent writing volume */ 286 uint64_t DevReadTimeSincCleaning; /**< read time since cleaning */ 287 uint64_t DevWriteTimeSincCleaning; /**< write time since cleaning */ 288 time_t CleaningDate; /**< time last cleaned */ 289 utime_t CleaningPeriod; /**< time between cleanings */ 290 }; 291 292 /** 293 * Storage database record 294 */ 295 struct StorageDbRecord { 296 DBId_t StorageId; 297 char Name[MAX_NAME_LENGTH]; /**< Device name */ 298 int AutoChanger; /**< Set if autochanger */ 299 300 /* 301 * Extra stuff not in DB 302 */ 303 bool created; /**< set if created by db_create ... */ 304 }; 305 306 /** 307 * mediatype database record 308 */ 309 struct MediaTypeDbRecord { 310 DBId_t MediaTypeId; 311 char MediaType[MAX_NAME_LENGTH]; /**< MediaType string */ 312 int ReadOnly; /**< Set if read-only */ 313 }; 314 315 /** 316 * Media record -- same as the database 317 */ 318 struct MediaDbRecord { 319 DBId_t MediaId; /**< Unique volume id */ 320 char VolumeName[MAX_NAME_LENGTH]; /**< Volume name */ 321 char MediaType[MAX_NAME_LENGTH]; /**< Media type */ 322 char EncrKey[MAX_NAME_LENGTH]; /**< Encryption Key */ 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 (BAREOS/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 uint32_t VolWrites; /**< Number of writes */ 335 uint32_t VolReads; /**< Number of reads */ 336 uint64_t VolBytes; /**< Number of bytes written */ 337 uint64_t MaxVolBytes; /**< Max bytes to write to Volume */ 338 uint64_t VolCapacityBytes; /**< capacity estimate */ 339 uint64_t VolReadTime; /**< time spent reading volume */ 340 uint64_t VolWriteTime; /**< time spent writing volume */ 341 utime_t VolRetention; /**< Volume retention in seconds */ 342 utime_t VolUseDuration; /**< time in secs volume can be used */ 343 uint32_t ActionOnPurge; /**< action on purge, e.g. truncate the disk volume */ 344 uint32_t MaxVolJobs; /**< Max Jobs on Volume */ 345 uint32_t MaxVolFiles; /**< Max files on Volume */ 346 int32_t Recycle; /**< recycle yes/no */ 347 int32_t Slot; /**< slot in changer */ 348 int32_t Enabled; /**< 0=disabled, 1=enabled, 2=archived */ 349 int32_t InChanger; /**< Volume currently in changer */ 350 DBId_t StorageId; /**< Storage record Id */ 351 uint32_t EndFile; /**< Last file on volume */ 352 uint32_t EndBlock; /**< Last block on volume */ 353 uint32_t RecycleCount; /**< Number of times recycled */ 354 uint32_t MinBlocksize; /**< Minimum Block Size */ 355 uint32_t MaxBlocksize; /**< Maximum Block Size */ 356 char VolStatus[20]; /**< Volume status */ 357 DBId_t DeviceId; /**< Device where Vol last written */ 358 DBId_t LocationId; /**< Where Volume is -- user defined */ 359 DBId_t ScratchPoolId; /**< Where to move if scratch */ 360 DBId_t RecyclePoolId; /**< Where to move when recycled */ 361 362 /* 363 * Extra stuff not in DB 364 */ 365 faddr_t rec_addr; /**< found record address */ 366 367 /* 368 * Since the database returns times as strings, this is how we pass them back. 369 */ 370 char cFirstWritten[MAX_TIME_LENGTH]; /**< FirstWritten returned from DB */ 371 char cLastWritten[MAX_TIME_LENGTH]; /**< LastWritten returned from DB */ 372 char cLabelDate[MAX_TIME_LENGTH]; /**< LabelData returned from DB */ 373 char cInitialWrite[MAX_TIME_LENGTH]; /**< InitialWrite returned from DB */ 374 bool set_first_written; 375 bool set_label_date; 376 }; 377 378 /** 379 * Client record -- same as the database 380 */ 381 struct ClientDbRecord { 382 DBId_t ClientId; /**< Unique Client id */ 383 int AutoPrune; 384 utime_t GraceTime; /**< Time remaining on gracetime */ 385 uint32_t QuotaLimit; /**< The total softquota supplied if over grace */ 386 utime_t FileRetention; 387 utime_t JobRetention; 388 char Name[MAX_NAME_LENGTH]; /**< Client name */ 389 char Uname[256]; /**< Uname for client */ 390 }; 391 392 /** 393 * Counter record -- same as in database 394 */ 395 struct CounterDbRecord { 396 char Counter[MAX_NAME_LENGTH]; 397 int32_t MinValue; 398 int32_t MaxValue; 399 int32_t CurrentValue; 400 char WrapCounter[MAX_NAME_LENGTH]; 401 }; 402 403 /** 404 * FileSet record -- same as the database 405 */ 406 struct FileSetDbRecord { 407 DBId_t FileSetId; /**< Unique FileSet id */ 408 char FileSet[MAX_NAME_LENGTH]; /**< FileSet name */ 409 char* FileSetText; /**< FileSet as Text */ 410 char MD5[50]; /**< MD5 signature of include/exclude */ 411 time_t CreateTime; /**< Date created */ 412 /* 413 * This is where we return CreateTime 414 */ 415 char cCreateTime[MAX_TIME_LENGTH]; /**< CreateTime as returned from DB */ 416 /* 417 * Not in DB but returned by db_create_fileset() 418 */ 419 bool created; /**< set when record newly created */ 420 }; 421 422 /** 423 * Device Statistics record -- same as in database 424 */ 425 struct DeviceStatisticsDbRecord { 426 DBId_t DeviceId; /**< Device record id */ 427 time_t SampleTime; /**< Timestamp statistic was captured */ 428 uint64_t ReadTime; /**< Time spent reading volume */ 429 uint64_t WriteTime; /**< Time spent writing volume */ 430 uint64_t ReadBytes; /**< Number of bytes read */ 431 uint64_t WriteBytes; /**< Number of bytes written */ 432 uint64_t SpoolSize; /**< Number of bytes spooled */ 433 uint32_t NumWaiting; /**< Number of Jobs waiting for device */ 434 uint32_t NumWriters; /**< Number of writers to device */ 435 DBId_t MediaId; /**< MediaId used */ 436 uint64_t VolCatBytes; /**< Volume Bytes */ 437 uint64_t VolCatFiles; /**< Volume Files */ 438 uint64_t VolCatBlocks; /**< Volume Blocks */ 439 }; 440 441 /** 442 * TapeAlert record -- same as in database 443 */ 444 struct TapealertStatsDbRecord { 445 DBId_t DeviceId; /**< Device record id */ 446 time_t SampleTime; /**< Timestamp statistic was captured */ 447 uint64_t AlertFlags; /**< Tape Alerts raised */ 448 }; 449 450 /** 451 * Job Statistics record -- same as in database 452 */ 453 struct JobStatisticsDbRecord { 454 DBId_t DeviceId; /**< Device record id */ 455 time_t SampleTime; /**< Timestamp statistic was captured */ 456 JobId_t JobId; /**< Job record id */ 457 uint32_t JobFiles; /**< Number of Files in Job */ 458 uint64_t JobBytes; /**< Number of Bytes in Job */ 459 }; 460 461 /** 462 * Call back context for getting a 32/64 bit value from the database 463 */ 464 class db_int64_ctx { 465 public: 466 int64_t value; /**< value returned */ 467 int count; /**< number of values seen */ 468 db_int64_ctx()469 db_int64_ctx() : value(0), count(0) {} ~db_int64_ctx()470 ~db_int64_ctx() {} 471 472 private: 473 db_int64_ctx(const db_int64_ctx&); /**< prohibit pass by value */ 474 db_int64_ctx& operator=( 475 const db_int64_ctx&); /**< prohibit class assignment */ 476 }; 477 478 /** 479 * Call back context for getting a list of comma separated strings from the 480 * database 481 */ 482 class db_list_ctx { 483 public: 484 POOLMEM* list; /* list */ 485 int count; /* number of values seen */ 486 db_list_ctx()487 db_list_ctx() 488 { 489 list = GetPoolMemory(PM_FNAME); 490 reset(); 491 } ~db_list_ctx()492 ~db_list_ctx() 493 { 494 FreePoolMemory(list); 495 list = NULL; 496 } reset()497 void reset() 498 { 499 *list = 0; 500 count = 0; 501 } add(const db_list_ctx & str)502 void add(const db_list_ctx& str) 503 { 504 if (str.count > 0) { 505 if (*list) { PmStrcat(list, ","); } 506 PmStrcat(list, str.list); 507 count += str.count; 508 } 509 } add(const char * str)510 void add(const char* str) 511 { 512 if (count > 0) { PmStrcat(list, ","); } 513 PmStrcat(list, str); 514 count++; 515 } 516 517 private: 518 db_list_ctx(const db_list_ctx&); /**< prohibit pass by value */ 519 db_list_ctx& operator=(const db_list_ctx&); /**< prohibit class assignment */ 520 }; 521 522 typedef enum 523 { 524 SQL_INTERFACE_TYPE_MYSQL = 0, 525 SQL_INTERFACE_TYPE_POSTGRESQL = 1, 526 SQL_INTERFACE_TYPE_SQLITE3 = 2, 527 SQL_INTERFACE_TYPE_INGRES = 3, 528 SQL_INTERFACE_TYPE_DBI = 4 529 } SQL_INTERFACETYPE; 530 531 typedef enum 532 { 533 SQL_TYPE_MYSQL = 0, 534 SQL_TYPE_POSTGRESQL = 1, 535 SQL_TYPE_SQLITE3 = 2, 536 SQL_TYPE_INGRES = 3, 537 SQL_TYPE_UNKNOWN = 99 538 } SQL_DBTYPE; 539 540 typedef void(DB_LIST_HANDLER)(void*, const char*); 541 typedef int(DB_RESULT_HANDLER)(void*, int, char**); 542 543 #define DbLock(mdb) mdb->LockDb(__FILE__, __LINE__) 544 #define DbUnlock(mdb) mdb->UnlockDb(__FILE__, __LINE__) 545 546 class pathid_cache; 547 548 /* 549 * Initial size of query hash table and hint for number of pages. 550 */ 551 #define QUERY_INITIAL_HASH_SIZE 1024 552 #define QUERY_HTABLE_PAGES 128 553 554 /** 555 * Current database version number for all drivers 556 */ 557 #define BDB_VERSION 2171 558 559 #ifdef _BDB_PRIV_INTERFACE_ 560 /* 561 * Generic definition of a sql_row. 562 */ 563 typedef char** SQL_ROW; 564 565 /* 566 * Generic definition of a a sql_field. 567 */ 568 typedef struct sql_field { 569 char* name; /* name of column */ 570 int max_length; /* max length */ 571 uint32_t type; /* type */ 572 uint32_t flags; /* flags */ 573 } SQL_FIELD; 574 #endif 575 576 class BareosDb 577 : public SmartAlloc 578 , public BareosDbQueryEnum { 579 protected: 580 /* 581 * Members 582 */ 583 brwlock_t lock_; /**< Transaction lock */ 584 dlink link_; /**< Queue control */ 585 SQL_INTERFACETYPE db_interface_type_; /**< Type of backend used */ 586 SQL_DBTYPE db_type_; /**< Database type */ 587 uint32_t ref_count_; /**< Reference count */ 588 bool connected_; /**< Connection made to db */ 589 bool have_batch_insert_; /**< Have batch insert support ? */ 590 bool try_reconnect_; /**< Try reconnecting DB connection ? */ 591 bool exit_on_fatal_; /**< Exit on FATAL DB errors ? */ 592 char* db_driver_; /**< Database driver */ 593 char* db_driverdir_; /**< Database driver dir */ 594 char* db_name_; /**< Database name */ 595 char* db_user_; /**< Database user */ 596 char* db_address_; /**< Host name address */ 597 char* db_socket_; /**< Socket for local access */ 598 char* db_password_; /**< Database password */ 599 char* last_query_text_; /**< Last query text obtained from query table */ 600 int db_port_; /**< Port for host name address */ 601 int cached_path_len; /**< Length of cached path */ 602 int changes; /**< Changes during transaction */ 603 int fnl; /**< File name length */ 604 int pnl; /**< Path name length */ 605 bool disabled_batch_insert_; /**< Explicitly disabled batch insert mode ? */ 606 bool is_private_; /**< Private connection ? */ 607 uint32_t cached_path_id; /**< Cached path id */ 608 uint32_t last_hash_key_; /**< Last hash key lookup on query table */ 609 POOLMEM* fname; /**< Filename only */ 610 POOLMEM* path; /**< Path only */ 611 POOLMEM* cached_path; /**< Cached path name */ 612 POOLMEM* esc_name; /**< Escaped file name */ 613 POOLMEM* esc_path; /**< Escaped path name */ 614 POOLMEM* esc_obj; /**< Escaped restore object */ 615 POOLMEM* cmd; /**< SQL command string */ 616 POOLMEM* errmsg; /**< Nicely edited error message */ 617 const char** queries; /**< table of query texts */ 618 static const char* query_names[]; /**< table of query names */ 619 620 private: 621 /* 622 * Methods 623 */ 624 int GetFilenameRecord(JobControlRecord* jcr); 625 bool GetFileRecord(JobControlRecord* jcr, 626 JobDbRecord* jr, 627 FileDbRecord* fdbr); 628 bool CreateBatchFileAttributesRecord(JobControlRecord* jcr, 629 AttributesDbRecord* ar); 630 bool CreateFilenameRecord(JobControlRecord* jcr, AttributesDbRecord* ar); 631 bool CreateFileRecord(JobControlRecord* jcr, AttributesDbRecord* ar); 632 void CleanupBaseFile(JobControlRecord* jcr); 633 void BuildPathHierarchy(JobControlRecord* jcr, 634 pathid_cache& ppathid_cache, 635 char* org_pathid, 636 char* path); 637 bool UpdatePathHierarchyCache(JobControlRecord* jcr, 638 pathid_cache& ppathid_cache, 639 JobId_t JobId); 640 void FillQueryVaList(POOLMEM*& query, 641 BareosDb::SQL_QUERY_ENUM predefined_query, 642 va_list arg_ptr); 643 void FillQueryVaList(PoolMem& query, 644 BareosDb::SQL_QUERY_ENUM predefined_query, 645 va_list arg_ptr); 646 647 public: 648 /* 649 * Methods 650 */ BareosDb()651 BareosDb() {} ~BareosDb()652 virtual ~BareosDb() {} get_db_name(void)653 const char* get_db_name(void) { return db_name_; } get_db_user(void)654 const char* get_db_user(void) { return db_user_; } IsConnected(void)655 bool IsConnected(void) { return connected_; } BatchInsertAvailable(void)656 bool BatchInsertAvailable(void) { return have_batch_insert_; } IsPrivate(void)657 bool IsPrivate(void) { return is_private_; } SetPrivate(bool IsPrivate)658 void SetPrivate(bool IsPrivate) { is_private_ = IsPrivate; } IncrementRefcount(void)659 void IncrementRefcount(void) { ref_count_++; } 660 661 /* bvfs.c */ 662 bool BvfsUpdatePathHierarchyCache(JobControlRecord* jcr, char* jobids); 663 void BvfsUpdateCache(JobControlRecord* jcr); 664 int BvfsLsDirs(PoolMem& query, void* ctx); 665 int BvfsBuildLsFileQuery(PoolMem& query, 666 DB_RESULT_HANDLER* ResultHandler, 667 void* ctx); 668 669 /* sql.c */ 670 char* strerror(); 671 bool CheckMaxConnections(JobControlRecord* jcr, uint32_t max_concurrent_jobs); 672 bool CheckTablesVersion(JobControlRecord* jcr); 673 bool QueryDB(const char* file, 674 int line, 675 JobControlRecord* jcr, 676 const char* select_cmd); 677 bool InsertDB(const char* file, 678 int line, 679 JobControlRecord* jcr, 680 const char* select_cmd); 681 int DeleteDB(const char* file, 682 int line, 683 JobControlRecord* jcr, 684 const char* DeleteCmd); 685 bool UpdateDB(const char* file, 686 int line, 687 JobControlRecord* jcr, 688 const char* UpdateCmd, 689 int nr_afr); 690 int GetSqlRecordMax(JobControlRecord* jcr); 691 void SplitPathAndFile(JobControlRecord* jcr, const char* fname); 692 void ListDashes(OutputFormatter* send); 693 int ListResult(void* vctx, int nb_col, char** row); 694 int ListResult(JobControlRecord* jcr, 695 OutputFormatter* send, 696 e_list_type type); 697 bool OpenBatchConnection(JobControlRecord* jcr); 698 void DbDebugPrint(FILE* fp); 699 700 /* sql_create.c */ 701 bool CreatePathRecord(JobControlRecord* jcr, AttributesDbRecord* ar); 702 bool CreateFileAttributesRecord(JobControlRecord* jcr, 703 AttributesDbRecord* ar); 704 bool CreateJobRecord(JobControlRecord* jcr, JobDbRecord* jr); 705 bool CreateMediaRecord(JobControlRecord* jcr, MediaDbRecord* media_dbr); 706 bool CreateClientRecord(JobControlRecord* jcr, ClientDbRecord* cr); 707 bool CreateFilesetRecord(JobControlRecord* jcr, FileSetDbRecord* fsr); 708 bool CreatePoolRecord(JobControlRecord* jcr, PoolDbRecord* pool_dbr); 709 bool CreateJobmediaRecord(JobControlRecord* jcr, JobMediaDbRecord* jr); 710 bool CreateCounterRecord(JobControlRecord* jcr, CounterDbRecord* cr); 711 bool CreateDeviceRecord(JobControlRecord* jcr, DeviceDbRecord* dr); 712 bool CreateStorageRecord(JobControlRecord* jcr, StorageDbRecord* sr); 713 bool CreateMediatypeRecord(JobControlRecord* jcr, MediaTypeDbRecord* mr); 714 bool WriteBatchFileRecords(JobControlRecord* jcr); 715 bool CreateAttributesRecord(JobControlRecord* jcr, AttributesDbRecord* ar); 716 bool CreateRestoreObjectRecord(JobControlRecord* jcr, 717 RestoreObjectDbRecord* ar); 718 bool CreateBaseFileAttributesRecord(JobControlRecord* jcr, 719 AttributesDbRecord* ar); 720 bool CommitBaseFileAttributesRecord(JobControlRecord* jcr); 721 bool CreateBaseFileList(JobControlRecord* jcr, char* jobids); 722 bool CreateQuotaRecord(JobControlRecord* jcr, ClientDbRecord* cr); 723 bool CreateNdmpLevelMapping(JobControlRecord* jcr, 724 JobDbRecord* jr, 725 char* filesystem); 726 bool CreateNdmpEnvironmentString(JobControlRecord* jcr, 727 JobDbRecord* jr, 728 char* name, 729 char* value); 730 bool CreateJobStatistics(JobControlRecord* jcr, JobStatisticsDbRecord* jsr); 731 bool CreateDeviceStatistics(JobControlRecord* jcr, 732 DeviceStatisticsDbRecord* dsr); 733 bool CreateTapealertStatistics(JobControlRecord* jcr, 734 TapealertStatsDbRecord* tsr); 735 736 /* sql_delete.c */ 737 bool DeletePoolRecord(JobControlRecord* jcr, PoolDbRecord* pool_dbr); 738 bool DeleteMediaRecord(JobControlRecord* jcr, MediaDbRecord* mr); 739 bool PurgeMediaRecord(JobControlRecord* jcr, MediaDbRecord* mr); 740 741 /* sql_find.c */ 742 bool FindLastJobStartTime(JobControlRecord* jcr, 743 JobDbRecord* jr, 744 POOLMEM*& stime, 745 char* job, 746 int JobLevel); 747 bool FindJobStartTime(JobControlRecord* jcr, 748 JobDbRecord* jr, 749 POOLMEM*& stime, 750 char* job); 751 bool FindLastJobid(JobControlRecord* jcr, const char* Name, JobDbRecord* jr); 752 int FindNextVolume(JobControlRecord* jcr, 753 int index, 754 bool InChanger, 755 MediaDbRecord* mr, 756 const char* unwanted_volumes); 757 bool FindFailedJobSince(JobControlRecord* jcr, 758 JobDbRecord* jr, 759 POOLMEM* stime, 760 int& JobLevel); 761 762 /* sql_get.c */ 763 bool GetVolumeJobids(JobControlRecord* jcr, 764 MediaDbRecord* mr, 765 db_list_ctx* lst); 766 bool GetBaseFileList(JobControlRecord* jcr, 767 bool use_md5, 768 DB_RESULT_HANDLER* ResultHandler, 769 void* ctx); 770 int GetPathRecord(JobControlRecord* jcr); 771 int GetPathRecord(JobControlRecord* jcr, const char* new_path); 772 bool GetPoolRecord(JobControlRecord* jcr, PoolDbRecord* pdbr); 773 bool GetStorageRecord(JobControlRecord* jcr, StorageDbRecord* sdbr); 774 bool GetJobRecord(JobControlRecord* jcr, JobDbRecord* jr); 775 int GetJobVolumeNames(JobControlRecord* jcr, 776 JobId_t JobId, 777 POOLMEM*& VolumeNames); 778 bool GetFileAttributesRecord(JobControlRecord* jcr, 779 char* filename, 780 JobDbRecord* jr, 781 FileDbRecord* fdbr); 782 int GetFilesetRecord(JobControlRecord* jcr, FileSetDbRecord* fsr); 783 bool GetMediaRecord(JobControlRecord* jcr, MediaDbRecord* mr); 784 int GetNumMediaRecords(JobControlRecord* jcr); 785 int GetNumPoolRecords(JobControlRecord* jcr); 786 int GetPoolIds(JobControlRecord* jcr, int* num_ids, DBId_t** ids); 787 bool GetClientIds(JobControlRecord* jcr, int* num_ids, DBId_t** ids); 788 int GetStorageIds(JobControlRecord* jcr, int* num_ids, DBId_t** ids); 789 bool PrepareMediaSqlQuery(JobControlRecord* jcr, 790 MediaDbRecord* mr, 791 PoolMem& volumes); 792 bool GetMediaIds(JobControlRecord* jcr, 793 MediaDbRecord* mr, 794 PoolMem& volumes, 795 int* num_ids, 796 DBId_t** ids); 797 int GetJobVolumeParameters(JobControlRecord* jcr, 798 JobId_t JobId, 799 VolumeParameters** VolParams); 800 bool GetClientRecord(JobControlRecord* jcr, ClientDbRecord* cdbr); 801 bool GetCounterRecord(JobControlRecord* jcr, CounterDbRecord* cr); 802 bool GetQueryDbids(JobControlRecord* jcr, PoolMem& query, dbid_list& ids); 803 bool GetFileList(JobControlRecord* jcr, 804 char* jobids, 805 bool use_md5, 806 bool use_delta, 807 DB_RESULT_HANDLER* ResultHandler, 808 void* ctx); 809 bool GetBaseJobid(JobControlRecord* jcr, JobDbRecord* jr, JobId_t* jobid); 810 bool AccurateGetJobids(JobControlRecord* jcr, 811 JobDbRecord* jr, 812 db_list_ctx* jobids); 813 bool GetUsedBaseJobids(JobControlRecord* jcr, 814 POOLMEM* jobids, 815 db_list_ctx* result); 816 bool GetQuotaRecord(JobControlRecord* jcr, ClientDbRecord* cr); 817 bool get_quota_jobbytes(JobControlRecord* jcr, 818 JobDbRecord* jr, 819 utime_t JobRetention); 820 bool get_quota_jobbytes_nofailed(JobControlRecord* jcr, 821 JobDbRecord* jr, 822 utime_t JobRetention); 823 int GetNdmpLevelMapping(JobControlRecord* jcr, 824 JobDbRecord* jr, 825 char* filesystem); 826 bool GetNdmpEnvironmentString(const std::string& query, 827 DB_RESULT_HANDLER* ResultHandler, 828 void* ctx); 829 bool GetNdmpEnvironmentString(const VolumeSessionInfo& vsi, 830 int32_t FileIndex, 831 DB_RESULT_HANDLER* ResultHandler, 832 void* ctx); 833 bool GetNdmpEnvironmentString(JobId_t JobId, 834 DB_RESULT_HANDLER* ResultHandler, 835 void* ctx); 836 bool GetNdmpEnvironmentString(JobId_t JobId, 837 int32_t FileIndex, 838 DB_RESULT_HANDLER* ResultHandler, 839 void* ctx); 840 bool PrepareMediaSqlQuery(JobControlRecord* jcr, 841 MediaDbRecord* mr, 842 PoolMem* querystring, 843 PoolMem& volumes); 844 bool VerifyMediaIdsFromSingleStorage(JobControlRecord* jcr, 845 dbid_list& mediaIds); 846 847 /* sql_list.c */ 848 void ListPoolRecords(JobControlRecord* jcr, 849 PoolDbRecord* pr, 850 OutputFormatter* sendit, 851 e_list_type type); 852 void ListJobRecords(JobControlRecord* jcr, 853 JobDbRecord* jr, 854 const char* range, 855 const char* clientname, 856 int jobstatus, 857 int joblevel, 858 const char* volumename, 859 const char* poolname, 860 utime_t since_time, 861 bool last, 862 bool count, 863 OutputFormatter* sendit, 864 e_list_type type); 865 void ListJobTotals(JobControlRecord* jcr, 866 JobDbRecord* jr, 867 OutputFormatter* sendit); 868 void ListFilesForJob(JobControlRecord* jcr, 869 uint32_t jobid, 870 OutputFormatter* sendit); 871 void ListFilesets(JobControlRecord* jcr, 872 JobDbRecord* jr, 873 const char* range, 874 OutputFormatter* sendit, 875 e_list_type type); 876 void ListStorageRecords(JobControlRecord* jcr, 877 OutputFormatter* sendit, 878 e_list_type type); 879 void ListMediaRecords(JobControlRecord* jcr, 880 MediaDbRecord* mdbr, 881 const char* range, 882 bool count, 883 OutputFormatter* sendit, 884 e_list_type type); 885 void ListJobmediaRecords(JobControlRecord* jcr, 886 JobId_t JobId, 887 OutputFormatter* sendit, 888 e_list_type type); 889 void ListVolumesOfJobid(JobControlRecord* jcr, 890 JobId_t JobId, 891 OutputFormatter* sendit, 892 e_list_type type); 893 void ListJoblogRecords(JobControlRecord* jcr, 894 JobId_t JobId, 895 const char* range, 896 bool count, 897 OutputFormatter* sendit, 898 e_list_type type); 899 void ListLogRecords(JobControlRecord* jcr, 900 const char* clientname, 901 const char* range, 902 bool reverse, 903 OutputFormatter* sendit, 904 e_list_type type); 905 void ListJobstatisticsRecords(JobControlRecord* jcr, 906 uint32_t JobId, 907 OutputFormatter* sendit, 908 e_list_type type); 909 bool ListSqlQuery(JobControlRecord* jcr, 910 const char* query, 911 OutputFormatter* sendit, 912 e_list_type type, 913 bool verbose); 914 bool ListSqlQuery(JobControlRecord* jcr, 915 SQL_QUERY_ENUM query, 916 OutputFormatter* sendit, 917 e_list_type type, 918 bool verbose); 919 bool ListSqlQuery(JobControlRecord* jcr, 920 const char* query, 921 OutputFormatter* sendit, 922 e_list_type type, 923 const char* description, 924 bool verbose = false); 925 bool ListSqlQuery(JobControlRecord* jcr, 926 SQL_QUERY_ENUM query, 927 OutputFormatter* sendit, 928 e_list_type type, 929 const char* description, 930 bool verbose); 931 void ListClientRecords(JobControlRecord* jcr, 932 char* clientname, 933 OutputFormatter* sendit, 934 e_list_type type); 935 void ListCopiesRecords(JobControlRecord* jcr, 936 const char* range, 937 const char* jobids, 938 OutputFormatter* sendit, 939 e_list_type type); 940 void ListBaseFilesForJob(JobControlRecord* jcr, 941 JobId_t jobid, 942 OutputFormatter* sendit); 943 944 /* SqlQuery.c */ 945 const char* get_predefined_query_name(SQL_QUERY_ENUM query); 946 const char* get_predefined_query(SQL_QUERY_ENUM query); 947 948 void FillQuery(SQL_QUERY_ENUM predefined_query, ...); 949 void FillQuery(POOLMEM*& query, SQL_QUERY_ENUM predefined_query, ...); 950 void FillQuery(PoolMem& query, SQL_QUERY_ENUM predefined_query, ...); 951 952 bool SqlQuery(SQL_QUERY_ENUM query, ...); 953 bool SqlQuery(const char* query, int flags = 0); 954 bool SqlQuery(const char* query, DB_RESULT_HANDLER* ResultHandler, void* ctx); 955 956 /* sql_update.c */ 957 bool UpdateJobStartRecord(JobControlRecord* jcr, JobDbRecord* jr); 958 bool UpdateJobEndRecord(JobControlRecord* jcr, JobDbRecord* jr); 959 bool UpdateClientRecord(JobControlRecord* jcr, ClientDbRecord* cr); 960 bool UpdatePoolRecord(JobControlRecord* jcr, PoolDbRecord* pr); 961 bool UpdateStorageRecord(JobControlRecord* jcr, StorageDbRecord* sr); 962 bool UpdateMediaRecord(JobControlRecord* jcr, MediaDbRecord* mr); 963 bool UpdateMediaDefaults(JobControlRecord* jcr, MediaDbRecord* mr); 964 bool UpdateCounterRecord(JobControlRecord* jcr, CounterDbRecord* cr); 965 bool UpdateQuotaGracetime(JobControlRecord* jcr, JobDbRecord* jr); 966 bool UpdateQuotaSoftlimit(JobControlRecord* jcr, JobDbRecord* jr); 967 bool ResetQuotaRecord(JobControlRecord* jcr, ClientDbRecord* jr); 968 bool UpdateNdmpLevelMapping(JobControlRecord* jcr, 969 JobDbRecord* jr, 970 char* filesystem, 971 int level); 972 bool AddDigestToFileRecord(JobControlRecord* jcr, 973 FileId_t FileId, 974 char* digest, 975 int type); 976 bool MarkFileRecord(JobControlRecord* jcr, FileId_t FileId, JobId_t JobId); 977 void MakeInchangerUnique(JobControlRecord* jcr, MediaDbRecord* mr); 978 int UpdateStats(JobControlRecord* jcr, utime_t age); 979 980 /* Low level methods */ 981 bool MatchDatabase(const char* db_driver, 982 const char* db_name, 983 const char* db_address, 984 int db_port); 985 BareosDb* CloneDatabaseConnection(JobControlRecord* jcr, 986 bool mult_db_connections, 987 bool get_pooled_connection = true, 988 bool need_private = false); GetTypeIndex(void)989 int GetTypeIndex(void) { return db_type_; } 990 const char* GetType(void); 991 void LockDb(const char* file, int line); 992 void UnlockDb(const char* file, int line); 993 void PrintLockInfo(FILE* fp); 994 995 /* Virtual low level methods */ ThreadCleanup(void)996 virtual void ThreadCleanup(void) {} 997 virtual void EscapeString(JobControlRecord* jcr, 998 char* snew, 999 char* old, 1000 int len); 1001 virtual char* EscapeObject(JobControlRecord* jcr, char* old, int len); 1002 virtual void UnescapeObject(JobControlRecord* jcr, 1003 char* from, 1004 int32_t expected_len, 1005 POOLMEM*& dest, 1006 int32_t* len); 1007 1008 /* Pure virtual low level methods */ 1009 virtual bool OpenDatabase(JobControlRecord* jcr) = 0; 1010 virtual void CloseDatabase(JobControlRecord* jcr) = 0; 1011 virtual bool ValidateConnection(void) = 0; 1012 virtual void StartTransaction(JobControlRecord* jcr) = 0; 1013 virtual void EndTransaction(JobControlRecord* jcr) = 0; 1014 1015 /* By default, we use db_sql_query */ BigSqlQuery(const char * query,DB_RESULT_HANDLER * ResultHandler,void * ctx)1016 virtual bool BigSqlQuery(const char* query, 1017 DB_RESULT_HANDLER* ResultHandler, 1018 void* ctx) 1019 { 1020 return SqlQuery(query, ResultHandler, ctx); 1021 } 1022 1023 #ifdef _BDB_PRIV_INTERFACE_ 1024 /* 1025 * Backend methods 1026 */ 1027 private: 1028 virtual int SqlNumRows(void) = 0; 1029 virtual void SqlFieldSeek(int field) = 0; 1030 virtual int SqlNumFields(void) = 0; 1031 virtual void SqlFreeResult(void) = 0; 1032 virtual SQL_ROW SqlFetchRow(void) = 0; 1033 virtual bool SqlQueryWithoutHandler(const char* query, int flags = 0) = 0; 1034 virtual bool SqlQueryWithHandler(const char* query, 1035 DB_RESULT_HANDLER* ResultHandler, 1036 void* ctx) = 0; 1037 virtual const char* sql_strerror(void) = 0; 1038 virtual void SqlDataSeek(int row) = 0; 1039 virtual int SqlAffectedRows(void) = 0; 1040 virtual uint64_t SqlInsertAutokeyRecord(const char* query, 1041 const char* table_name) = 0; 1042 virtual SQL_FIELD* SqlFetchField(void) = 0; 1043 virtual bool SqlFieldIsNotNull(int field_type) = 0; 1044 virtual bool SqlFieldIsNumeric(int field_type) = 0; 1045 virtual bool SqlBatchStart(JobControlRecord* jcr) = 0; 1046 virtual bool SqlBatchEnd(JobControlRecord* jcr, const char* error) = 0; 1047 virtual bool SqlBatchInsert(JobControlRecord* jcr, 1048 AttributesDbRecord* ar) = 0; 1049 #endif 1050 }; 1051 1052 #ifdef _BDB_PRIV_INTERFACE_ 1053 #include "bdb_priv.h" 1054 #endif 1055 1056 /* SqlQuery Query Flags */ 1057 #define QF_STORE_RESULT 0x01 1058 1059 /* flush the batch insert connection every x changes */ 1060 #define BATCH_FLUSH 800000 1061 1062 /* Use for better error location printing */ 1063 #define UPDATE_DB(jcr, cmd) UpdateDB(__FILE__, __LINE__, jcr, cmd, 1) 1064 #define UPDATE_DB_NO_AFR(jcr, cmd) UpdateDB(__FILE__, __LINE__, jcr, cmd, 0) 1065 #define INSERT_DB(jcr, cmd) InsertDB(__FILE__, __LINE__, jcr, cmd) 1066 #define QUERY_DB(jcr, cmd) QueryDB(__FILE__, __LINE__, jcr, cmd) 1067 #define DELETE_DB(jcr, cmd) DeleteDB(__FILE__, __LINE__, jcr, cmd) 1068 1069 /** 1070 * Pooled backend connection. 1071 */ 1072 struct SqlPoolEntry { 1073 int id; /**< Unique ID, connection numbering can have holes and the pool is 1074 not sorted on it */ 1075 int reference_count; /**< Reference count for this entry */ 1076 time_t last_update; /**< When was this connection last updated either used or 1077 put back on the pool */ 1078 BareosDb* db_handle; /**< Connection handle to the database */ 1079 dlink link; /**< list management */ 1080 }; 1081 1082 /** 1083 * Pooled backend list descriptor (one defined per backend defined in config) 1084 */ 1085 struct SqlPoolDescriptor { 1086 dlist* pool_entries; /**< Linked list of all pool entries */ 1087 bool active; /**< Is this an active pool, after a config reload an pool is 1088 made inactive */ 1089 time_t last_update; /**< When was this pool last updated */ 1090 int min_connections; /**< Minimum number of connections in the connection pool 1091 */ 1092 int max_connections; /**< Maximum number of connections in the connection pool 1093 */ 1094 int increment_connections; /**< Increase/Decrease the number of connection in 1095 the pool with this value */ 1096 int idle_timeout; /**< Number of seconds to wait before tearing down a 1097 connection */ 1098 int validate_timeout; /**< Number of seconds after which an idle connection 1099 should be validated */ 1100 int nr_connections; /**< Number of active connections in the pool */ 1101 dlink link; /**< list management */ 1102 }; 1103 1104 #include "include/jcr.h" 1105 1106 /** 1107 * Object used in db_list_xxx function 1108 */ 1109 class ListContext { 1110 public: 1111 char line[256]; /**< Used to print last dash line */ 1112 int32_t num_rows; 1113 1114 e_list_type type; /**< Vertical/Horizontal */ 1115 OutputFormatter* send; /**< send data back */ 1116 bool once; /**< Used to print header one time */ 1117 BareosDb* mdb; 1118 JobControlRecord* jcr; 1119 empty()1120 void empty() 1121 { 1122 once = false; 1123 line[0] = '\0'; 1124 } 1125 send_dashes()1126 void send_dashes() 1127 { 1128 if (*line) { send->Decoration(line); } 1129 } 1130 ListContext(JobControlRecord * j,BareosDb * m,OutputFormatter * h,e_list_type t)1131 ListContext(JobControlRecord* j, 1132 BareosDb* m, 1133 OutputFormatter* h, 1134 e_list_type t) 1135 { 1136 line[0] = '\0'; 1137 once = false; 1138 num_rows = 0; 1139 type = t; 1140 send = h; 1141 jcr = j; 1142 mdb = m; 1143 } 1144 }; 1145 1146 /** 1147 * Some functions exported by sql.c for use within the cats directory. 1148 */ 1149 int ListResult(void* vctx, int cols, char** row); 1150 int ListResult(JobControlRecord* jcr, 1151 BareosDb* mdb, 1152 OutputFormatter* send, 1153 e_list_type type); 1154 #endif /* BAREOS_CATS_CATS_H_ */ 1155