Skip to content

Commit

Permalink
Merge pull request #577 from arogge/dev/arogge/bareos-19.2/xattr-bug
Browse files Browse the repository at this point in the history
allow backup/restore of cephfs mounts (Backport for Bareos 19.2)
  • Loading branch information
arogge committed Aug 26, 2020
2 parents ee666d5 + c8f85d6 commit 2536984
Show file tree
Hide file tree
Showing 74 changed files with 974 additions and 188 deletions.
34 changes: 34 additions & 0 deletions cmake/BareosCheckAcl.cmake
@@ -0,0 +1,34 @@
# BAREOS® - Backup Archiving REcovery Open Sourced
#
# Copyright (C) 2020-2020 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 License as
# published by the Free Software Foundation and included in the file LICENSE.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# Extract version information and commit timestamp if run in a git checkout

find_program(SETFACL_PROG setfacl)
find_program(GETFACL_PROG getfacl)

set(SETFACL_WORKS NO)
if(SETFACL_PROG AND GETFACL_PROG)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/acl-test-file.txt" "Just a testfile")
exec_program(${SETFACL_PROG}
${CMAKE_CURRENT_BINARY_DIR}
ARGS "-m user:0:rw- acl-test-file.txt"
RETURN_VALUE SETFACL_RETURN)
if(SETFACL_RETURN EQUAL 0)
set(SETFACL_WORKS YES)
endif()
endif()

34 changes: 34 additions & 0 deletions cmake/BareosCheckXattr.cmake
@@ -0,0 +1,34 @@
# BAREOS® - Backup Archiving REcovery Open Sourced
#
# Copyright (C) 2020-2020 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 License as
# published by the Free Software Foundation and included in the file LICENSE.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# Extract version information and commit timestamp if run in a git checkout

find_program(SETFATTR_PROG setfattr)
find_program(GETFATTR_PROG getfattr)

set(SETFATTR_WORKS NO)
if(SETFATTR_PROG AND GETFATTR_PROG)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/xattr-test-file.txt" "Just a testfile")
exec_program(${SETFATTR_PROG}
${CMAKE_CURRENT_BINARY_DIR}
ARGS "--name=user.cmake-check --value=xattr-value xattr-test-file.txt"
RETURN_VALUE SETFATTR_RETURN)
if(SETFATTR_RETURN EQUAL 0)
set(SETFATTR_WORKS YES)
endif()
endif()

36 changes: 21 additions & 15 deletions core/src/dird/ua_purge.cc
Expand Up @@ -44,9 +44,12 @@
#include "dird/ua_prune.h"
#include "dird/ua_purge.h"
#include "include/auth_protocol_types.h"
#include "lib/bstringlist.h"
#include "lib/edit.h"
#include "lib/util.h"

#include <algorithm>

namespace directordaemon {

/* Forward referenced functions */
Expand Down Expand Up @@ -326,7 +329,7 @@ static bool PurgeJobsFromClient(UaContext* ua, ClientResource* client)
/**
* Remove File records from a list of JobIds
*/
void PurgeFilesFromJobs(UaContext* ua, char* jobs)
void PurgeFilesFromJobs(UaContext* ua, const char* jobs)
{
PoolMem query(PM_MESSAGE);

Expand Down Expand Up @@ -355,28 +358,31 @@ void PurgeFilesFromJobs(UaContext* ua, char* jobs)
*/
void PurgeJobListFromCatalog(UaContext* ua, del_ctx& del)
{
PoolMem jobids(PM_MESSAGE);
char ed1[50];

for (int i = 0; del.num_ids;) {
std::vector<JobId_t> jobid_list{};
Dmsg1(150, "num_ids=%d\n", del.num_ids);
PmStrcat(jobids, "");
for (int j = 0; j < 1000 && del.num_ids > 0; j++) {
del.num_ids--;
if (del.JobId[i] == 0 || ua->jcr->JobId == del.JobId[i]) {
Dmsg2(150, "skip JobId[%d]=%d\n", i, (int)del.JobId[i]);
i++;
Dmsg2(150, "skip JobId[%d]=%llu\n", i, del.JobId[i]);
++i;
continue;
}
if (*jobids.c_str() != 0) { PmStrcat(jobids, ","); }
PmStrcat(jobids, edit_int64(del.JobId[i++], ed1));
Dmsg1(150, "Add id=%s\n", ed1);
del.num_del++;
jobid_list.push_back(del.JobId[i]);
Dmsg1(150, "Add id=%llu\n", del.JobId[i]);
++i;
++del.num_del;
}
Dmsg1(150, "num_ids=%d\n", del.num_ids);
std::sort(jobid_list.begin(), jobid_list.end());
BStringList jobids{};
std::transform(jobid_list.begin(), jobid_list.end(),
std::back_inserter(jobids),
[](JobId_t jobid) { return std::to_string(jobid); });

Jmsg(ua->jcr, M_INFO, 0, _("Purging the following JobIds: %s\n"),
jobids.c_str());
PurgeJobsFromCatalog(ua, jobids.c_str());
jobids.Join(',').c_str());
PurgeJobsFromCatalog(ua, jobids.Join(',').c_str());
}
}

Expand Down Expand Up @@ -449,7 +455,7 @@ static bool PurgeQuotaFromClient(UaContext* ua, ClientResource* client)
* => Search through PriorJobId in jobid and
* PriorJobId in PriorJobId (jobid)
*/
void UpgradeCopies(UaContext* ua, char* jobs)
void UpgradeCopies(UaContext* ua, const char* jobs)
{
PoolMem query(PM_MESSAGE);

Expand Down Expand Up @@ -478,7 +484,7 @@ void UpgradeCopies(UaContext* ua, char* jobs)
/**
* Remove all records from catalog for a list of JobIds
*/
void PurgeJobsFromCatalog(UaContext* ua, char* jobs)
void PurgeJobsFromCatalog(UaContext* ua, const char* jobs)
{
PoolMem query(PM_MESSAGE);

Expand Down
4 changes: 2 additions & 2 deletions core/src/dird/ua_purge.h
Expand Up @@ -30,8 +30,8 @@ bool IsVolumePurged(UaContext* ua, MediaDbRecord* mr, bool force = false);
bool MarkMediaPurged(UaContext* ua, MediaDbRecord* mr);
void PurgeFilesFromVolume(UaContext* ua, MediaDbRecord* mr);
bool PurgeJobsFromVolume(UaContext* ua, MediaDbRecord* mr, bool force = false);
void PurgeFilesFromJobs(UaContext* ua, char* jobs);
void PurgeJobsFromCatalog(UaContext* ua, char* jobs);
void PurgeFilesFromJobs(UaContext* ua, const char* jobs);
void PurgeJobsFromCatalog(UaContext* ua, const char* jobs);
void PurgeJobListFromCatalog(UaContext* ua, del_ctx& del);
void PurgeFilesFromJobList(UaContext* ua, del_ctx& del);

Expand Down
19 changes: 7 additions & 12 deletions core/src/filed/backup.cc
Expand Up @@ -47,6 +47,7 @@
#include "lib/btimers.h"
#include "lib/parse_conf.h"
#include "lib/util.h"
#include "include/make_unique.h"

namespace filedaemon {

Expand Down Expand Up @@ -144,17 +145,15 @@ bool BlastDataToStorageDaemon(JobControlRecord* jcr,
StartHeartbeatMonitor(jcr);

if (have_acl) {
jcr->impl->acl_data = (acl_data_t*)malloc(sizeof(acl_data_t));
memset(jcr->impl->acl_data, 0, sizeof(acl_data_t));
jcr->impl->acl_data = std::make_unique<AclData>();
jcr->impl->acl_data->u.build =
(acl_build_data_t*)malloc(sizeof(acl_build_data_t));
memset(jcr->impl->acl_data->u.build, 0, sizeof(acl_build_data_t));
jcr->impl->acl_data->u.build->content = GetPoolMemory(PM_MESSAGE);
}

if (have_xattr) {
jcr->impl->xattr_data = (xattr_data_t*)malloc(sizeof(xattr_data_t));
memset(jcr->impl->xattr_data, 0, sizeof(xattr_data_t));
jcr->impl->xattr_data = std::make_unique<XattrData>();
jcr->impl->xattr_data->u.build =
(xattr_build_data_t*)malloc(sizeof(xattr_build_data_t));
memset(jcr->impl->xattr_data->u.build, 0, sizeof(xattr_build_data_t));
Expand Down Expand Up @@ -191,15 +190,11 @@ bool BlastDataToStorageDaemon(JobControlRecord* jcr,
if (have_acl && jcr->impl->acl_data) {
FreePoolMemory(jcr->impl->acl_data->u.build->content);
free(jcr->impl->acl_data->u.build);
free(jcr->impl->acl_data);
jcr->impl->acl_data = NULL;
}

if (have_xattr && jcr->impl->xattr_data) {
FreePoolMemory(jcr->impl->xattr_data->u.build->content);
free(jcr->impl->xattr_data->u.build);
free(jcr->impl->xattr_data);
jcr->impl->xattr_data = NULL;
}

if (jcr->impl->big_buf) {
Expand Down Expand Up @@ -467,9 +462,9 @@ static inline bool DoBackupAcl(JobControlRecord* jcr, FindFilesPacket* ff_pkt)
jcr->impl->acl_data->last_fname = jcr->impl->last_fname;

if (jcr->IsPlugin()) {
retval = PluginBuildAclStreams(jcr, jcr->impl->acl_data, ff_pkt);
retval = PluginBuildAclStreams(jcr, jcr->impl->acl_data.get(), ff_pkt);
} else {
retval = BuildAclStreams(jcr, jcr->impl->acl_data, ff_pkt);
retval = BuildAclStreams(jcr, jcr->impl->acl_data.get(), ff_pkt);
}

switch (retval) {
Expand All @@ -493,9 +488,9 @@ static inline bool DoBackupXattr(JobControlRecord* jcr, FindFilesPacket* ff_pkt)
jcr->impl->xattr_data->last_fname = jcr->impl->last_fname;

if (jcr->IsPlugin()) {
retval = PluginBuildXattrStreams(jcr, jcr->impl->xattr_data, ff_pkt);
retval = PluginBuildXattrStreams(jcr, jcr->impl->xattr_data.get(), ff_pkt);
} else {
retval = BuildXattrStreams(jcr, jcr->impl->xattr_data, ff_pkt);
retval = BuildXattrStreams(jcr, jcr->impl->xattr_data.get(), ff_pkt);
}

switch (retval) {
Expand Down
8 changes: 4 additions & 4 deletions core/src/filed/fd_plugins.cc
Expand Up @@ -1383,7 +1383,7 @@ bool PluginSetAttributes(JobControlRecord* jcr,
* Plugin specific callback for getting ACL information.
*/
bacl_exit_code PluginBuildAclStreams(JobControlRecord* jcr,
acl_data_t* acl_data,
AclData* acl_data,
FindFilesPacket* ff_pkt)
{
Plugin* plugin;
Expand Down Expand Up @@ -1430,7 +1430,7 @@ bacl_exit_code PluginBuildAclStreams(JobControlRecord* jcr,
* Plugin specific callback for setting ACL information.
*/
bacl_exit_code plugin_parse_acl_streams(JobControlRecord* jcr,
acl_data_t* acl_data,
AclData* acl_data,
int stream,
char* content,
uint32_t content_length)
Expand Down Expand Up @@ -1472,7 +1472,7 @@ bacl_exit_code plugin_parse_acl_streams(JobControlRecord* jcr,
* Plugin specific callback for getting XATTR information.
*/
BxattrExitCode PluginBuildXattrStreams(JobControlRecord* jcr,
struct xattr_data_t* xattr_data,
struct XattrData* xattr_data,
FindFilesPacket* ff_pkt)
{
Plugin* plugin;
Expand Down Expand Up @@ -1600,7 +1600,7 @@ BxattrExitCode PluginBuildXattrStreams(JobControlRecord* jcr,
* Plugin specific callback for setting XATTR information.
*/
BxattrExitCode PluginParseXattrStreams(JobControlRecord* jcr,
struct xattr_data_t* xattr_data,
struct XattrData* xattr_data,
int stream,
char* content,
uint32_t content_length)
Expand Down
8 changes: 4 additions & 4 deletions core/src/filed/fd_plugins.h
Expand Up @@ -282,18 +282,18 @@ bool PluginSetAttributes(JobControlRecord* jcr,
Attributes* attr,
BareosWinFilePacket* ofd);
bacl_exit_code PluginBuildAclStreams(JobControlRecord* jcr,
acl_data_t* acl_data,
AclData* acl_data,
FindFilesPacket* ff_pkt);
bacl_exit_code plugin_parse_acl_streams(JobControlRecord* jcr,
acl_data_t* acl_data,
AclData* acl_data,
int stream,
char* content,
uint32_t content_length);
BxattrExitCode PluginBuildXattrStreams(JobControlRecord* jcr,
struct xattr_data_t* xattr_data,
struct XattrData* xattr_data,
FindFilesPacket* ff_pkt);
BxattrExitCode PluginParseXattrStreams(JobControlRecord* jcr,
struct xattr_data_t* xattr_data,
struct XattrData* xattr_data,
int stream,
char* content,
uint32_t content_length);
Expand Down
8 changes: 4 additions & 4 deletions core/src/filed/jcr_private.h
Expand Up @@ -26,8 +26,8 @@

#include "include/bareos.h"

struct acl_data_t;
struct xattr_data_t;
struct AclData;
struct XattrData;

namespace filedaemon {
class BareosAccurateFilelist;
Expand All @@ -51,8 +51,8 @@ struct JobControlRecordPrivate {
uint32_t num_files_examined{}; /**< Files examined this job */
POOLMEM* last_fname{}; /**< Last file saved/verified */
POOLMEM* job_metadata{}; /**< VSS job metadata */
acl_data_t* acl_data{}; /**< ACLs for backup/restore */
xattr_data_t* xattr_data{}; /**< Extended Attributes for backup/restore */
std::unique_ptr<AclData> acl_data{}; /**< ACLs for backup/restore */
std::unique_ptr<XattrData> xattr_data{}; /**< Extended Attributes for backup/restore */
int32_t last_type{}; /**< Type of last file saved/verified */
bool incremental{}; /**< Set if incremental for SINCE */
utime_t mtime{}; /**< Begin time for SINCE */
Expand Down
27 changes: 10 additions & 17 deletions core/src/filed/restore.cc
Expand Up @@ -46,6 +46,7 @@
#include "lib/bsock.h"
#include "lib/edit.h"
#include "lib/parse_conf.h"
#include "include/make_unique.h"

#ifdef HAVE_WIN32
#include "win32/findlib/win32.h"
Expand Down Expand Up @@ -226,12 +227,12 @@ static inline bool do_reStoreAcl(JobControlRecord* jcr,
jcr->impl->acl_data->last_fname = jcr->impl->last_fname;
switch (stream) {
case STREAM_ACL_PLUGIN:
retval = plugin_parse_acl_streams(jcr, jcr->impl->acl_data, stream,
retval = plugin_parse_acl_streams(jcr, jcr->impl->acl_data.get(), stream,
content, content_length);
break;
default:
retval = parse_acl_streams(jcr, jcr->impl->acl_data, stream, content,
content_length);
retval = parse_acl_streams(jcr, jcr->impl->acl_data.get(), stream,
content, content_length);
break;
}

Expand Down Expand Up @@ -271,12 +272,12 @@ static inline bool do_restore_xattr(JobControlRecord* jcr,
jcr->impl->xattr_data->last_fname = jcr->impl->last_fname;
switch (stream) {
case STREAM_XATTR_PLUGIN:
retval = PluginParseXattrStreams(jcr, jcr->impl->xattr_data, stream,
retval = PluginParseXattrStreams(jcr, jcr->impl->xattr_data.get(), stream,
content, content_length);
break;
default:
retval = ParseXattrStreams(jcr, jcr->impl->xattr_data, stream, content,
content_length);
retval = ParseXattrStreams(jcr, jcr->impl->xattr_data.get(), stream,
content, content_length);
break;
}

Expand Down Expand Up @@ -490,15 +491,13 @@ void DoRestore(JobControlRecord* jcr)
binit(&rctx.forkbfd);
attr = rctx.attr = new_attr(jcr);
if (have_acl) {
jcr->impl->acl_data = (acl_data_t*)malloc(sizeof(acl_data_t));
memset(jcr->impl->acl_data, 0, sizeof(acl_data_t));
jcr->impl->acl_data = std::make_unique<AclData>();
jcr->impl->acl_data->u.parse =
(acl_parse_data_t*)malloc(sizeof(acl_parse_data_t));
memset(jcr->impl->acl_data->u.parse, 0, sizeof(acl_parse_data_t));
}
if (have_xattr) {
jcr->impl->xattr_data = (xattr_data_t*)malloc(sizeof(xattr_data_t));
memset(jcr->impl->xattr_data, 0, sizeof(xattr_data_t));
jcr->impl->xattr_data = std::make_unique<XattrData>();
jcr->impl->xattr_data->u.parse =
(xattr_parse_data_t*)malloc(sizeof(xattr_parse_data_t));
memset(jcr->impl->xattr_data->u.parse, 0, sizeof(xattr_parse_data_t));
Expand Down Expand Up @@ -1193,16 +1192,10 @@ void DoRestore(JobControlRecord* jcr)
rctx.fork_cipher_ctx.buf = NULL;
}

if (have_acl && jcr->impl->acl_data) {
free(jcr->impl->acl_data->u.parse);
free(jcr->impl->acl_data);
jcr->impl->acl_data = NULL;
}
if (have_acl && jcr->impl->acl_data) { free(jcr->impl->acl_data->u.parse); }

if (have_xattr && jcr->impl->xattr_data) {
free(jcr->impl->xattr_data->u.parse);
free(jcr->impl->xattr_data);
jcr->impl->xattr_data = NULL;
}

/*
Expand Down

0 comments on commit 2536984

Please sign in to comment.