diff --git a/core/src/dird/catreq.cc b/core/src/dird/catreq.cc index b9dc5f533bc..119347be5da 100644 --- a/core/src/dird/catreq.cc +++ b/core/src/dird/catreq.cc @@ -3,7 +3,7 @@ Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2016 Planets Communications B.V. - Copyright (C) 2013-2022 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -167,28 +167,22 @@ void CatalogRequest(JobControlRecord* jcr, BareosSocket* bs) UnbashSpaces(mr.VolumeName); if (jcr->db->GetMediaRecord(jcr, &mr)) { const char* reason = NULL; /* detailed reason for rejection */ - /* - * If we are reading, accept any volume (reason == NULL) + /* If we are reading, accept any volume (reason == NULL) * If we are writing, check if the Volume is valid - * for this job, and do a recycle if necessary - */ + * for this job, and do a recycle if necessary */ if (writing) { - /* - * SD wants to write this Volume, so make + /* SD wants to write this Volume, so make * sure it is suitable for this job, i.e. * Pool matches, and it is either Append or Recycle - * and Media Type matches and Pool allows any volume. - */ + * and Media Type matches and Pool allows any volume. */ if (mr.PoolId != jcr->dir_impl->jr.PoolId) { reason = _("not in Pool"); } else if (!bstrcmp(mr.MediaType, jcr->dir_impl->res.write_storage->media_type)) { reason = _("not correct MediaType"); } else { - /* - * Now try recycling if necessary - * reason set non-NULL if we cannot use it - */ + /* Now try recycling if necessary + * reason set non-NULL if we cannot use it */ CheckIfVolumeValidOrRecyclable(jcr, &mr, &reason); } } @@ -215,11 +209,9 @@ void CatalogRequest(JobControlRecord* jcr, BareosSocket* bs) &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime, &sdmr.VolWriteTime, &VolFirstWritten) == 18) { - /* - * Request to update Media record. Comes typically at the end + /* Request to update Media record. Comes typically at the end * of a Storage daemon Job Session, when labeling/relabeling a - * Volume, or when an EOF mark is written. - */ + * Volume, or when an EOF mark is written. */ DbLocker _{jcr->db}; Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, mr.VolStatus, sdmr.VolStatus); @@ -267,19 +259,15 @@ void CatalogRequest(JobControlRecord* jcr, BareosSocket* bs) Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); - /* - * Check if the volume has been written by the job, - * and update the LastWritten field if needed. - */ + /* Check if the volume has been written by the job, + * and update the LastWritten field if needed. */ if (mr.VolBlocks != sdmr.VolBlocks && VolLastWritten != 0) { mr.LastWritten = VolLastWritten; } - /* - * Update to point to the last device used to write the Volume. + /* Update to point to the last device used to write the Volume. * However, do so only if we are writing the tape, i.e. - * the number of VolWrites has increased. - */ + * the number of VolWrites has increased. */ if (jcr->dir_impl->res.write_storage && sdmr.VolWrites > mr.VolWrites) { Dmsg2(050, "Update StorageId old=%d new=%d\n", mr.StorageId, jcr->dir_impl->res.write_storage->StorageId); @@ -307,10 +295,8 @@ void CatalogRequest(JobControlRecord* jcr, BareosSocket* bs) Dmsg2(400, "UpdateMediaRecord. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName); - /* - * Update the database, then before sending the response to the SD, - * check if the Volume has expired. - */ + /* Update the database, then before sending the response to the SD, + * check if the Volume has expired. */ if (!jcr->db->UpdateMediaRecord(jcr, &mr)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error updating Media record. %s"), jcr->db->strerror()); @@ -412,11 +398,9 @@ static void UpdateAttribute(JobControlRecord* jcr, jcr->db->StartTransaction(jcr); /* start transaction if not already open */ ar = jcr->ar; - /* - * Start by scanning directly in the message buffer to get Stream + /* Start by scanning directly in the message buffer to get Stream * there may be a cached attr so we cannot yet write into - * jcr->attr or jcr->ar - */ + * jcr->attr or jcr->ar */ p = msg; SkipNonspaces(&p); /* UpdCat */ SkipSpaces(&p); @@ -433,8 +417,7 @@ static void UpdateAttribute(JobControlRecord* jcr, unser_uint32(reclen); /* Record length */ p += UnserLength(p); /* Raw record follows */ - /** - * At this point p points to the raw record, which varies according + /* At this point p points to the raw record, which varies according * to what kind of a record (Stream) was sent. Note, the integer * fields at the beginning of these "raw" records are in ASCII with * spaces between them so one can use scanf or manual scanning to @@ -458,8 +441,7 @@ static void UpdateAttribute(JobControlRecord* jcr, * Object_compression * Plugin_name * Object_name - * Binary Object data - */ + * Binary Object data */ Dmsg1(400, "UpdCat msg=%s\n", msg); Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d reclen=%d\n", @@ -525,11 +507,9 @@ static void UpdateAttribute(JobControlRecord* jcr, jcr->cached_attribute = true; - /* - * Fhinfo and Fhnode are not sent from the SD, + /* Fhinfo and Fhnode are not sent from the SD, * they exist only in NDMP 2-Way backups so we - * set them to 0 here - */ + * set them to 0 here */ ar->Fhinfo = 0; ar->Fhnode = 0; @@ -617,6 +597,10 @@ static void UpdateAttribute(JobControlRecord* jcr, len = CRYPTO_DIGEST_SHA512_SIZE; type = CRYPTO_DIGEST_SHA512; break; + case STREAM_XXH128_DIGEST: + len = CRYPTO_DIGEST_XXH128_SIZE; + type = CRYPTO_DIGEST_XXH128; + break; default: Jmsg(jcr, M_ERROR, 0, _("Catalog error updating file digest. Unsupported digest " diff --git a/core/src/dird/dird_conf.cc b/core/src/dird/dird_conf.cc index 9cda704a4bb..09d3dbc2f9f 100644 --- a/core/src/dird/dird_conf.cc +++ b/core/src/dird/dird_conf.cc @@ -1920,6 +1920,10 @@ void FilesetResource::PrintConfigIncludeExcludeOptions( p++; break; #endif + case '4': + send.KeyQuotedString("Signature", "XXH128"); + p++; + break; default: send.KeyQuotedString("Signature", "SHA1"); break; diff --git a/core/src/dird/inc_conf.cc b/core/src/dird/inc_conf.cc index e1610133389..8ec5ec0508a 100644 --- a/core/src/dird/inc_conf.cc +++ b/core/src/dird/inc_conf.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. - Copyright (C) 2013-2022 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -150,6 +150,7 @@ static struct s_fs_opt FS_options[] {"sha1", INC_KW_DIGEST, "S"}, {"sha256", INC_KW_DIGEST, "S2"}, {"sha512", INC_KW_DIGEST, "S3"}, + {"xxh128", INC_KW_DIGEST, "S4"}, {"gzip", INC_KW_COMPRESSION, "Z6"}, {"gzip1", INC_KW_COMPRESSION, "Z1"}, {"gzip2", INC_KW_COMPRESSION, "Z2"}, @@ -992,11 +993,9 @@ void StoreInc(LEX* lc, ResourceItem* item, int index, int pass) { int token; - /* - * Decide if we are doing a new Include or an old include. The + /* Decide if we are doing a new Include or an old include. The * new Include is followed immediately by open brace, whereas the - * old include has options following the Include. - */ + * old include has options following the Include. */ token = LexGetToken(lc, BCT_SKIP_EOL); if (token == BCT_BOB) { StoreNewinc(lc, item, index, pass); diff --git a/core/src/dird/testfind.cc b/core/src/dird/testfind.cc index b723b303f0c..262074615c9 100644 --- a/core/src/dird/testfind.cc +++ b/core/src/dird/testfind.cc @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. - Copyright (C) 2016-2022 Bareos GmbH & Co. KG + Copyright (C) 2016-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -157,9 +157,7 @@ int main(int argc, char* const* argv) MessagesResource* msg; - foreach_res (msg, R_MSGS) { - InitMsg(NULL, msg); - } + foreach_res (msg, R_MSGS) { InitMsg(NULL, msg); } jcr = NewDirectorJcr(TestfindFreeJcr); jcr->dir_impl->res.fileset @@ -598,6 +596,10 @@ static void SetOptions(findFOPTS* fo, const char* opts) p++; break; #endif + case '4': + SetBit(FO_XXH128, fo->flags); + p++; + break; default: /* Automatically downgrade to SHA-1 if an unsupported * SHA variant is specified */ diff --git a/core/src/filed/accurate.cc b/core/src/filed/accurate.cc index a169418d9ca..6ae31e16d78 100644 --- a/core/src/filed/accurate.cc +++ b/core/src/filed/accurate.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Planets Communications B.V. - Copyright (C) 2013-2022 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -178,12 +178,10 @@ bool AccurateCheckFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt) goto bail_out; } - /** - * Restore original name so we can check the actual file when we check + /* Restore original name so we can check the actual file when we check * the accurate options later on. This is mostly important for the * CalculateAndCompareFileChksum() function as that needs to calulate - * the checksum of the real file and not try to open the stripped pathname. - */ + * the checksum of the real file and not try to open the stripped pathname. */ UnstripPath(ff_pkt); ff_pkt->accurate_found = true; @@ -211,10 +209,8 @@ bool AccurateCheckFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt) } break; case 'p': /** Permissions bits */ - /** - * TODO: If something change only in perm, user, group - * Backup only the attribute stream - */ + /* TODO: If something change only in perm, user, group + * Backup only the attribute stream */ if (statc.st_mode != ff_pkt->statp.st_mode) { Dmsg3(debuglevel - 1, "%s st_mode differ. Cat: %04o File: %04o\n", fname, @@ -289,7 +285,8 @@ bool AccurateCheckFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt) && (BitIsSet(FO_MD5, ff_pkt->flags) || BitIsSet(FO_SHA1, ff_pkt->flags) || BitIsSet(FO_SHA256, ff_pkt->flags) - || BitIsSet(FO_SHA512, ff_pkt->flags)))) { + || BitIsSet(FO_SHA512, ff_pkt->flags) + || BitIsSet(FO_XXH128, ff_pkt->flags)))) { if (!*payload->chksum && !jcr->rerunning) { Jmsg(jcr, M_WARNING, 0, _("Cannot verify checksum for %s\n"), ff_pkt->fname); @@ -309,10 +306,8 @@ bool AccurateCheckFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt) } } - /** - * In Incr/Diff accurate mode, we mark all files as seen - * When in Full+Base mode, we mark only if the file match exactly - */ + /* In Incr/Diff accurate mode, we mark all files as seen + * When in Full+Base mode, we mark only if the file match exactly */ if (jcr->getJobLevel() == L_FULL) { if (!status) { // Compute space saved with basefile. @@ -378,10 +373,8 @@ bool AccurateCmd(JobControlRecord* jcr) chksum_length = strlen(chksum); delta_seq = str_to_int32(chksum + chksum_length + 1); - /** - * Sanity check total length of the received msg must be at least - * total of the 3 lengths calculated + 3 (\0) - */ + /* Sanity check total length of the received msg must be at least + * total of the 3 lengths calculated + 3 (\0) */ if ((fname_length + lstat_length + chksum_length + 3) > dir->message_length) { continue; diff --git a/core/src/filed/backup.cc b/core/src/filed/backup.cc index eb551c4c6d6..0bb2daf9c97 100644 --- a/core/src/filed/backup.cc +++ b/core/src/filed/backup.cc @@ -301,6 +301,9 @@ static inline bool SetupEncryptionDigests(b_save_ctx& bsctx) } else if (BitIsSet(FO_SHA512, bsctx.ff_pkt->flags)) { bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_SHA512); bsctx.digest_stream = STREAM_SHA512_DIGEST; + } else if (BitIsSet(FO_XXH128, bsctx.ff_pkt->flags)) { + bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_XXH128); + bsctx.digest_stream = STREAM_XXH128_DIGEST; } // Did digest initialization fail? diff --git a/core/src/filed/fileset.cc b/core/src/filed/fileset.cc index 99582a50011..468f37abedd 100644 --- a/core/src/filed/fileset.cc +++ b/core/src/filed/fileset.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. - Copyright (C) 2013-2022 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -280,12 +280,10 @@ void AddFileset(JobControlRecord* jcr, const char* item) return; } - /** - * The switch tests the code for validity. + /* The switch tests the code for validity. * The subcode is always good if it is a space, otherwise we must confirm. * We set state to state_error first assuming the subcode is invalid, - * requiring state to be set in cases below that handle subcodes. - */ + * requiring state to be set in cases below that handle subcodes. */ if (subcode != ' ') { state = state_error; Dmsg0(100, "Set state=error or double code.\n"); @@ -364,10 +362,8 @@ bool TermFileset(JobControlRecord* jcr) fileset = jcr->fd_impl->ff->fileset; #ifdef HAVE_WIN32 - /* - * Expand the fileset to include all drive letters when the fileset includes a - * File = / entry. - */ + /* Expand the fileset to include all drive letters when the fileset includes a + * File = / entry. */ if (!expand_win32_fileset(jcr->fd_impl->ff->fileset)) { return false; } // Exclude entries in NotToBackup registry key @@ -581,11 +577,13 @@ static int SetOptions(findFOPTS* fo, const char* opts) p++; break; #endif + case '4': + SetBit(FO_XXH128, fo->flags); + p++; + break; default: - /* - * If 2 or 3 is seen here, SHA2 is not configured, so eat the - * option, and drop back to SHA-1. - */ + /* If 2 or 3 is seen here, SHA2 is not configured, so eat the + * option, and drop back to SHA-1. */ if (p[1] == '2' || p[1] == '3') { p++; } SetBit(FO_SHA1, fo->flags); break; diff --git a/core/src/filed/restore.cc b/core/src/filed/restore.cc index b6edc083f02..905256069d3 100644 --- a/core/src/filed/restore.cc +++ b/core/src/filed/restore.cc @@ -976,6 +976,7 @@ void DoRestore(JobControlRecord* jcr) case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: + case STREAM_XXH128_DIGEST: break; case STREAM_PROGRAM_NAMES: diff --git a/core/src/filed/verify.cc b/core/src/filed/verify.cc index b53faee0e01..656e48ad473 100644 --- a/core/src/filed/verify.cc +++ b/core/src/filed/verify.cc @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. - Copyright (C) 2016-2022 Bareos GmbH & Co. KG + Copyright (C) 2016-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -200,8 +200,7 @@ static int VerifyFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt, bool) PmStrcpy(jcr->fd_impl->last_fname, ff_pkt->fname); jcr->unlock(); - /* - * Send file attributes to Director + /* Send file attributes to Director * File_index * Stream * Verify Options @@ -209,8 +208,7 @@ static int VerifyFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt, bool) * Encoded attributes * Link name (if type==FT_LNK) * For a directory, link is the same as fname, but with trailing - * slash. For a linked file, link is the link. - */ + * slash. For a linked file, link is the link. */ // Send file attributes to Director (note different format than for Storage) Dmsg2(400, "send Attributes inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname); if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) { @@ -239,7 +237,8 @@ static int VerifyFile(JobControlRecord* jcr, FindFilesPacket* ff_pkt, bool) if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && (BitIsSet(FO_MD5, ff_pkt->flags) || BitIsSet(FO_SHA1, ff_pkt->flags) || BitIsSet(FO_SHA256, ff_pkt->flags) - || BitIsSet(FO_SHA512, ff_pkt->flags))) { + || BitIsSet(FO_SHA512, ff_pkt->flags) + || BitIsSet(FO_XXH128, ff_pkt->flags))) { int digest_stream = STREAM_NONE; DIGEST* digest = NULL; char* digest_buf = NULL; @@ -387,10 +386,8 @@ static bool calculate_file_chksum(JobControlRecord* jcr, char** digest_buf, const char** digest_name) { - /* - * Create our digest context. - * If this fails, the digest will be set to NULL and not used. - */ + /* Create our digest context. + * If this fails, the digest will be set to NULL and not used. */ if (BitIsSet(FO_MD5, ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); *digest_stream = STREAM_MD5_DIGEST; @@ -403,6 +400,9 @@ static bool calculate_file_chksum(JobControlRecord* jcr, } else if (BitIsSet(FO_SHA512, ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); *digest_stream = STREAM_SHA512_DIGEST; + } else if (BitIsSet(FO_XXH128, ff_pkt->flags)) { + *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_XXH128); + *digest_stream = STREAM_XXH128_DIGEST; } // compute MD5 or SHA1 hash diff --git a/core/src/filed/verify_vol.cc b/core/src/filed/verify_vol.cc index 9a812445e3d..2254eba75f8 100644 --- a/core/src/filed/verify_vol.cc +++ b/core/src/filed/verify_vol.cc @@ -243,6 +243,16 @@ void DoVerifyVolume(JobControlRecord* jcr) dir->msg); break; + case STREAM_XXH128_DIGEST: + BinToBase64(digest, sizeof(digest), (char*)sd->msg, + CRYPTO_DIGEST_XXH128_SIZE, true); + Dmsg2(400, "send inx=%d XXH128=%s\n", jcr->JobFiles, digest); + dir->fsend("%d %d %s *XXH128-%d*", jcr->JobFiles, STREAM_XXH128_DIGEST, + digest, jcr->JobFiles); + Dmsg2(20, "filed>dir: XXH128 len=%d: msg=%s\n", dir->message_length, + dir->msg); + break; + case STREAM_RESTORE_OBJECT: jcr->lock(); jcr->JobFiles++; diff --git a/core/src/findlib/bfile.cc b/core/src/findlib/bfile.cc index 6af595566ab..9a8428a358b 100644 --- a/core/src/findlib/bfile.cc +++ b/core/src/findlib/bfile.cc @@ -134,6 +134,8 @@ const char* stream_to_ascii(int stream) return _("SHA256 digest"); case STREAM_SHA512_DIGEST: return _("SHA512 digest"); + case STREAM_XXH128_DIGEST: + return _("XXH128 digest"); case STREAM_SIGNED_DIGEST: return _("Signed digest"); case STREAM_ENCRYPTED_FILE_DATA: @@ -452,6 +454,7 @@ bool IsRestoreStreamSupported(int stream) case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: # endif + case STREAM_XXH128_DIGEST: # ifdef HAVE_CRYPTO case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_FILE_DATA: @@ -1020,6 +1023,7 @@ bool IsRestoreStreamSupported(int stream) case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: # endif + case STREAM_XXH128_DIGEST: # ifdef HAVE_CRYPTO case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_FILE_DATA: diff --git a/core/src/findlib/match.cc b/core/src/findlib/match.cc index 3903d72ea14..e0b4d0f1fc3 100644 --- a/core/src/findlib/match.cc +++ b/core/src/findlib/match.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. - Copyright (C) 2013-2019 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -278,11 +278,13 @@ void AddFnameToIncludeList(FindFilesPacket* ff, int prefixed, const char* fname) rp++; break; #endif + case '4': + SetBit(FO_XXH128, inc->options); + rp++; + break; default: - /* - * If 2 or 3 is seen here, SHA2 is not configured, so - * eat the option, and drop back to SHA-1. - */ + /* If 2 or 3 is seen here, SHA2 is not configured, so + * eat the option, and drop back to SHA-1. */ if (rp[1] == '2' || rp[1] == '3') { rp++; } SetBit(FO_SHA1, inc->options); break; @@ -477,10 +479,8 @@ bool FileIsIncluded(FindFilesPacket* ff, const char* file) } continue; } - /* - * No wild cards. We accept a match to the - * end of any component. - */ + /* No wild cards. We accept a match to the + * end of any component. */ Dmsg2(900, "pat=%s file=%s\n", inc->fname, file); len = strlen(file); if (inc->len == len && bstrcmp(inc->fname, file)) { return true; } @@ -520,10 +520,8 @@ bool FileIsExcluded(FindFilesPacket* ff, const char* file) const char* p; #if defined(HAVE_WIN32) - /* - * ***NB*** this removes the drive from the exclude - * rule. Why????? - */ + /* ***NB*** this removes the drive from the exclude + * rule. Why????? */ if (file[1] == ':') { file += 2; } #endif @@ -547,21 +545,17 @@ bool ParseSizeMatch(const char* size_match_pattern, bool retval = false; char *private_copy, *bp; - /* - * Make a private copy of the input string. + /* Make a private copy of the input string. * As we manipulate the input and size_to_uint64 - * eats its input. - */ + * eats its input. */ private_copy = strdup(size_match_pattern); // Empty the matching arguments. *size_matching = s_sz_matching{}; - /* - * See if the size is a range e.g. there is a - in the + /* See if the size is a range e.g. there is a - in the * match pattern. As a size of a file can never be negative - * this is a workable solution. - */ + * this is a workable solution. */ if ((bp = strchr(private_copy, '-')) != NULL) { *bp++ = '\0'; size_matching->type = size_match_range; diff --git a/core/src/include/fileopts.h b/core/src/include/fileopts.h index 28bfd34d5bb..5ca04f1e61b 100644 --- a/core/src/include/fileopts.h +++ b/core/src/include/fileopts.h @@ -3,7 +3,7 @@ Copyright (C) 2001-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. - Copyright (C) 2013-2021 Bareos GmbH & Co. KG + Copyright (C) 2013-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -71,11 +71,12 @@ enum FO_PLUGIN = 29, /**< Plugin data stream -- return to plugin on restore */ FO_OFFSETS = 30, /**< Keep I/O file offsets */ FO_NO_AUTOEXCL = 31, /**< Don't use autoexclude methods */ - FO_FORCE_ENCRYPT = 32 /**< Force encryption */ + FO_FORCE_ENCRYPT = 32, /**< Force encryption */ + FO_XXH128 = 33, /**< Do xxHash128 checksum */ }; // Keep this set to the last entry in the enum. -#define FO_MAX FO_FORCE_ENCRYPT +#define FO_MAX FO_XXH128 // Make sure you have enough bits to store all above bit fields. #define FOPTS_BYTES NbytesForBits(FO_MAX + 1) diff --git a/core/src/include/streams.h b/core/src/include/streams.h index a966a58afa7..2550045311f 100644 --- a/core/src/include/streams.h +++ b/core/src/include/streams.h @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. - Copyright (C) 2016-2021 Bareos GmbH & Co. KG + Copyright (C) 2016-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -105,6 +105,8 @@ #define STREAM_ENCRYPTED_FILE_COMPRESSED_DATA 32 /**< Encrypted, compressed data */ #define STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA 33 /**< Encrypted, compressed Win32 BackupRead data */ +#define STREAM_XXH128_DIGEST 40 /**< xxHash128 digest for the file */ + #define STREAM_NDMP_SEPARATOR 999 /**< NDMP separator between multiple data streams of one job */ /** diff --git a/core/src/stored/bextract.cc b/core/src/stored/bextract.cc index dc734ae45d0..508a33c5e31 100644 --- a/core/src/stored/bextract.cc +++ b/core/src/stored/bextract.cc @@ -647,6 +647,7 @@ static bool RecordCb(DeviceControlRecord* dcr, DeviceRecord* rec) case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: + case STREAM_XXH128_DIGEST: break; case STREAM_SIGNED_DIGEST: diff --git a/core/src/stored/bscan.cc b/core/src/stored/bscan.cc index 0a9a577733e..9df110a40fb 100644 --- a/core/src/stored/bscan.cc +++ b/core/src/stored/bscan.cc @@ -890,6 +890,13 @@ static bool RecordCb(DeviceControlRecord* dcr, DeviceRecord* rec) UpdateDigestRecord(db, digest, rec, CRYPTO_DIGEST_SHA512); break; + case STREAM_XXH128_DIGEST: + BinToBase64(digest, sizeof(digest), (char*)rec->data, + CRYPTO_DIGEST_XXH128_SIZE, true); + if (verbose > 1) { Pmsg1(000, _("Got XXH128 record: %s\n"), digest); } + UpdateDigestRecord(db, digest, rec, CRYPTO_DIGEST_XXH128); + break; + case STREAM_ENCRYPTED_SESSION_DATA: // TODO landonf: Investigate crypto support in bscan if (verbose > 1) { Pmsg0(000, _("Got signed digest record\n")); } diff --git a/core/src/stored/record.cc b/core/src/stored/record.cc index ca5bcb03430..00417841208 100644 --- a/core/src/stored/record.cc +++ b/core/src/stored/record.cc @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. - Copyright (C) 2016-2022 Bareos GmbH & Co. KG + Copyright (C) 2016-2023 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -202,6 +202,10 @@ static const char* record_digest_to_str(PoolMem& resultbuffer, BinToBase64(digest, sizeof(digest), (char*)rec->data, CRYPTO_DIGEST_SHA512_SIZE, true); break; + case STREAM_XXH128_DIGEST: + BinToBase64(digest, sizeof(digest), (char*)rec->data, + CRYPTO_DIGEST_XXH128_SIZE, true); + break; default: return ""; } @@ -275,6 +279,8 @@ const char* stream_to_ascii(char* buf, int stream, int fi) return "contSHA256"; case STREAM_SHA512_DIGEST: return "contSHA512"; + case STREAM_XXH128_DIGEST: + return "contXXH128"; case STREAM_SIGNED_DIGEST: return "contSIGNED-DIGEST"; case STREAM_ENCRYPTED_SESSION_DATA: @@ -344,6 +350,8 @@ const char* stream_to_ascii(char* buf, int stream, int fi) return "SHA256"; case STREAM_SHA512_DIGEST: return "SHA512"; + case STREAM_XXH128_DIGEST: + return "XXH128"; case STREAM_SIGNED_DIGEST: return "SIGNED-DIGEST"; case STREAM_ENCRYPTED_SESSION_DATA: @@ -433,6 +441,7 @@ static const char* get_record_short_info(PoolMem& resultbuffer, case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: + case STREAM_XXH128_DIGEST: record_digest_to_str(resultbuffer, rec); break; case STREAM_PLUGIN_NAME: { @@ -647,12 +656,10 @@ bool DeviceControlRecord::WriteRecord() goto bail_out; } - /* - * The record got translated when we got an after_rec pointer after calling + /* The record got translated when we got an after_rec pointer after calling * the bSdEventWriteRecordTranslation plugin event. If no translation has * taken place we just point the after_rec pointer to same DeviceRecord as in - * the before_rec pointer. - */ + * the before_rec pointer. */ if (!after_rec) { after_rec = before_rec; } else { @@ -713,10 +720,8 @@ bool WriteRecordToBlock(DeviceControlRecord* dcr, DeviceRecord* rec) char buf1[100], buf2[100]; DeviceBlock* block = dcr->block; - /* - * After this point the record is in nrec not rec e.g. its either converted - * or is just a pointer to the same as the rec pointer being passed in. - */ + /* After this point the record is in nrec not rec e.g. its either converted + * or is just a pointer to the same as the rec pointer being passed in. */ while (1) { ASSERT(block->binbuf == (uint32_t)(block->bufp - block->buf)); @@ -741,28 +746,23 @@ bool WriteRecordToBlock(DeviceControlRecord* dcr, DeviceRecord* rec) // Write header n = WriteHeaderToBlock(block, rec, rec->Stream); if (n < 0) { - /* - * the header did not fit into the block, so flush the current + /* the header did not fit into the block, so flush the current * block and come back to st_header and try again on the next block. */ return false; } if (BlockWriteNavail(block) == 0) { - /* - * The header fit, but no bytes of data will fit, + /* The header fit, but no bytes of data will fit, * so flush this block and start the next block with a - * continuation header. - */ + * continuation header. */ rec->state = st_header_cont; return false; } - /* - * The header fit, and at least one byte of data will fit, + /* The header fit, and at least one byte of data will fit, * so move to the st_data state and start filling the block - * with data bytes - */ + * with data bytes */ rec->state = st_data; continue; @@ -770,55 +770,43 @@ bool WriteRecordToBlock(DeviceControlRecord* dcr, DeviceRecord* rec) // Write continuation header n = WriteHeaderToBlock(block, rec, -rec->Stream); if (n < 0) { - /* - * The continuation header wouldn't fit, which is impossible - * unless something is broken - */ + /* The continuation header wouldn't fit, which is impossible + * unless something is broken */ Emsg0(M_ABORT, 0, _("couldn't write continuation header\n")); } - /* - * After successfully writing a continuation header, we always start - * writing data, even if none will fit into this block. - */ + /* After successfully writing a continuation header, we always start + * writing data, even if none will fit into this block. */ rec->state = st_data; if (BlockWriteNavail(block) == 0) { - /* - * The header fit, but no bytes of data will fit, + /* The header fit, but no bytes of data will fit, * so flush the block and start the next block with - * data bytes - */ + * data bytes */ return false; /* Partial transfer */ } continue; case st_data: - /* - * Write normal data + /* Write normal data * * Part of it may have already been transferred, and we - * may not have enough room to transfer the whole this time. - */ + * may not have enough room to transfer the whole this time. */ if (rec->remainder > 0) { n = WriteDataToBlock(block, rec); if (n < 0) { - /* - * error appending data to block should be impossible - * unless something is broken - */ + /* error appending data to block should be impossible + * unless something is broken */ Emsg0(M_ABORT, 0, _("data write error\n")); } rec->remainder -= n; if (rec->remainder > 0) { - /* - * Could not fit all of the data bytes into this block, so + /* Could not fit all of the data bytes into this block, so * flush the current block, and start the next block with a - * continuation header - */ + * continuation header */ rec->state = st_header_cont; return false; } @@ -884,10 +872,8 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) rec->Block = ((Device*)(dcr->block->dev))->EndBlock; rec->File = ((Device*)(dcr->block->dev))->EndFile; - /* - * Get the header. There is always a full header, otherwise we find it in the - * next block. - */ + /* Get the header. There is always a full header, otherwise we find it in the + * next block. */ Dmsg3(450, "Block=%d Ver=%d size=%u\n", dcr->block->BlockNumber, dcr->block->BlockVer, dcr->block->block_len); if (dcr->block->BlockVer == 1) { @@ -916,10 +902,8 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) dcr->block->binbuf -= rhl; remlen -= rhl; - /* - * If we are looking for more (remainder!=0), we reject anything - * where the VolSessionId and VolSessionTime don't agree - */ + /* If we are looking for more (remainder!=0), we reject anything + * where the VolSessionId and VolSessionTime don't agree */ if (rec->remainder && (rec->VolSessionId != VolSessionId || rec->VolSessionTime != VolSessionTime)) { @@ -928,10 +912,8 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) return false; /* This is from some other Session */ } - /* - * If Stream is negative, it means that this is a continuation - * of a previous partially written record. - */ + /* If Stream is negative, it means that this is a continuation + * of a previous partially written record. */ if (Stream < 0) { /* continuation record? */ Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n", rec->remainder); @@ -964,14 +946,12 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) stream_to_ascii(buf2, rec->Stream, rec->FileIndex), data_bytes, remlen, rec->data_len); } else { - /* - * No more records in this block because the number + /* No more records in this block because the number * of remaining bytes are less than a record header * length, so return empty handed, but indicate that * he must read again. By returning, we allow the * higher level routine to fetch the next block and - * then reread. - */ + * then reread. */ Dmsg0(450, "read_record_block: nothing\n"); SetBit(REC_NO_HEADER, rec->state_bits); SetBit(REC_BLOCK_EMPTY, rec->state_bits); @@ -981,10 +961,8 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) /* Sanity check */ if (data_bytes >= MAX_BLOCK_LENGTH) { - /* - * Something is wrong, force read of next block, abort - * continuing with this block. - */ + /* Something is wrong, force read of next block, abort + * continuing with this block. */ SetBit(REC_NO_HEADER, rec->state_bits); SetBit(REC_BLOCK_EMPTY, rec->state_bits); EmptyBlock(dcr->block); @@ -996,14 +974,12 @@ bool ReadRecordFromBlock(DeviceControlRecord* dcr, DeviceRecord* rec) rec->data = CheckPoolMemorySize(rec->data, rec->data_len + data_bytes); - /* - * At this point, we have read the header, now we + /* At this point, we have read the header, now we * must transfer as much of the data record as * possible taking into account: 1. A partial * data record may have previously been transferred, * 2. The current block may not contain the whole data - * record. - */ + * record. */ if (remlen >= data_bytes) { // Got whole record memcpy(rec->data + rec->data_len, dcr->block->bufp, data_bytes);