return bRC_OK;
}
-/*
- * The method works as a dispatcher for expected commands received from backend.
- * It handles a three commands associated with file attributes/metadata:
- * - FNAME:... - the next file to backup
- * - ACL - next data will be acl data, so perform_read_acl()
- * - XATTR - next data will be xattr data, so perform_read_xattr()
- * and additionally when no more files to backup it handles EOD.
+/**
+ * @brief The method works as a dispatcher for expected commands received from backend.
+ * It handles a number of commands available at main dispatcher loop.
*
- * in:
- * bpContext - for Bacula debug and jobinfo messages
- * out:
- * bRC_OK - when plugin read the command, dispatched a work and setup flags
- * bRC_Error - on any error during backup
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @return bRC bRC_OK - when plugin read the command, dispatched a work and setup flags
+ * bRC_Error - on any error during backup
*/
bRC METAPLUGIN::perform_read_metacommands(bpContext *ctx)
{
perform_accurate_check_get(ctx);
continue;
}
+ if (scan_parameter_str(cmd, "ACCEPT:", fname)){
+ /* got AcceptFile() query */
+ perform_accept_file(ctx);
+ continue;
+ }
if (bstrcmp(cmd.c_str(), "ACL")){
/* got ACL header */
perform_read_acl(ctx);
return bRC_OK;
}
+/**
+ * @brief Perform a check if selected file should be accepted to backup.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @return bRC bRC_OK when success, bRC_Error if not
+ */
+bRC METAPLUGIN::perform_accept_file(bpContext *ctx)
+{
+ if (strlen(fname.c_str()) == 0){
+ // input variable is not valid
+ return bRC_Error;
+ }
+
+ DMSG0(ctx, DDEBUG, "perform_accept_file()\n");
+
+ POOL_MEM cmd(PM_FNAME);
+ struct save_pkt sp;
+ memset(&sp, 0, sizeof(sp));
+
+ metaplugin::attributes::Status status = metaplugin::attributes::read_attributes_command(ctx, backend.ctx, cmd, &sp);
+ switch(status)
+ {
+ case metaplugin::attributes::Invalid_File_Type:
+ JMSG2(ctx, M_ERROR, "Invalid file type: %c for %s\n", sp.type, fname.c_str());
+ return bRC_Error;
+
+ case metaplugin::attributes::Invalid_Stat_Packet:
+ JMSG1(ctx, backend.ctx->jmsg_err_level(), "Invalid stat packet: %s\n", cmd.c_str());
+ return bRC_Error;
+
+ case metaplugin::attributes::Status_OK:
+ {
+ // success we can perform accurate check for stat packet
+ sp.fname = fname.c_str();
+ bRC rc = bfuncs->AcceptFile(ctx, &sp);
+
+ POOL_MEM checkstatus(PM_NAME);
+ Mmsg(checkstatus, "%s\n", rc == bRC_Skip ? "SKIP" : "OK");
+ DMSG1(ctx, DINFO, "perform_accept_file(): %s", checkstatus.c_str());
+
+ if (!backend.ctx->write_command(ctx, checkstatus)) {
+ DMSG0(ctx, DERROR, "Cannot send AcceptFile() response to backend\n");
+ JMSG0(ctx, backend.ctx->jmsg_err_level(), "Cannot send AcceptFile() response to backend\n");
+ return bRC_Error;
+ }
+ }
+ break;
+
+ default:
+ JMSG2(ctx, M_ERROR, "Invalid accept file protocol: %d for %s\n", status, fname.c_str());
+ return bRC_Error;
+ }
+
+ return bRC_OK;
+}
+
/**
* @brief
*
bRC perform_file_index_query(bpContext *ctx);
bRC perform_accurate_check(bpContext *ctx);
bRC perform_accurate_check_get(bpContext *ctx);
+ bRC perform_accept_file(bpContext *ctx);
// bRC perform_write_metadata_info(bpContext *ctx, struct meta_pkt *mp);
metadata_type scan_metadata_type(bpContext *ctx, const POOL_MEM &cmd);
const char *prepare_metadata_type(metadata_type type);
Bacula(R) is a registered trademark of Kern Sibbald.
*/
/**
- * @file metaplugin_stat.cpp
+ * @file metaplugin_attributes.cpp
* @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
* @brief This is a Backend attributes (STAT, TSTAMP) command handling subroutines for metaplugin.
* @version 1.0.0
{
namespace attributes
{
+ /**
+ * @brief Scans an input command and handles STAT sttributes.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @param cmd a command buffer to scan and analyze
+ * @param sp save packet to fill - output
+ * @return Status Status_OK when data managed
+ * Status_Handled when data managed and TSTAMP command is not required
+ * Not_Command when it was not this command
+ */
Status read_scan_stat_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp)
{
char type;
if (strncmp(cmd.c_str(), "STAT:/", 6) == 0)
{
- DMSG0(ctx, DDEBUG, "read_scan_stat_command():new stat(2)\n");
POOL_MEM param(PM_FNAME);
// handle stat(2) for this file
scan_parameter_str(cmd, "STAT:", param);
+ DMSG1(ctx, DDEBUG, "read_scan_stat_command():stat:%s\n", param.c_str());
int rc = stat(param.c_str(), &sp->statp);
if (rc < 0)
{
return Invalid_Stat_Packet;
}
// stat is working as expected
- DMSG1(ctx, DDEBUG, "read_scan_stat_command():stat: %o\n", sp->statp.st_mode & S_IFMT);
+ DMSG1(ctx, DDEBUG, "read_scan_stat_command():stat: %o\n", sp->statp.st_mode);
switch (sp->statp.st_mode & S_IFMT)
{
case S_IFDIR:
return Not_Command;
}
+ /**
+ * @brief Scans an input command and handles TSTAMP sttributes.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @param cmd a command buffer to scan and analyze
+ * @param sp save packet to fill - output
+ * @return Status Status_OK when data managed
+ * Not_Command when it was not this command
+ */
Status read_scan_tstamp_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp)
{
time_t _atime;
return Not_Command;
}
+ /**
+ * @brief Prepare a STAT command based on selected data.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @param cmd the command buffer - output
+ * @param rp restore packet to use
+ * @return Status Status_OK
+ */
Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp)
{
/* STAT:... */
return Status_OK;
}
+ /**
+ * @brief Prepares a TSTAMP command based on selected data.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @param cmd the command buffer - output
+ * @param rp restore packet to use
+ * @return Status Status_OK
+ */
Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp)
{
/* TSTAMP:... */
return Status_OK;
}
-} // attributes
-} // metaplugin
+ /**
+ * @brief Reads a file attributes sequence (STAT, TSTAMP) used at different sections.
+ *
+ * @param ctx bpContext - for Bacula debug and jobinfo messages
+ * @param ptcomm backend communication class - the current context
+ * @param cmd the buffer for command handled
+ * @param sp save packet to fill when file attributes handled
+ * @return Status Status_OK when file attributes commands handled, Status_Error on any error, other depends on enum.
+ */
+ Status read_attributes_command(bpContext *ctx, PTCOMM *ptcomm, POOL_MEM &cmd, struct save_pkt *sp)
+ {
+ DMSG0(ctx, DDEBUG, "read_attributes_command()\n");
+
+ // supported sequence is `STAT` followed by `TSTAMP`
+ if (ptcomm->read_command(ctx, cmd) < 0) {
+ // error
+ return Status_Error;
+ }
+
+ Status status = read_scan_stat_command(ctx, cmd, sp);
+ switch(status)
+ {
+ case Status_OK:
+ // go with TSATMP command
+ if (ptcomm->read_command(ctx, cmd) < 0) {
+ // error
+ return Status_Error;
+ }
+ status = read_scan_tstamp_command(ctx, cmd, sp);
+ break;
+
+ case Status_Handled:
+ status = Status_OK;
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+ }
+
+} // namespace attributes
+} // namespace metaplugin
Bacula(R) is a registered trademark of Kern Sibbald.
*/
/**
- * @file metaplugin_stat.h
+ * @file metaplugin_attributes.h
* @author Radosław Korzeniewski (radoslaw@korzeniewski.net)
* @brief This is a Backend `STAT` command handling subroutines for metaplugin.
* @version 1.0.0
* @copyright Copyright (c) 2021 All rights reserved. IP transferred to Bacula Systems according to agreement.
*/
-#ifndef _METAPLUGIN_STAT_H_
-#define _METAPLUGIN_STAT_H_
+#ifndef _METAPLUGIN_ATTRIBUTES_H_
+#define _METAPLUGIN_ATTRIBUTES_H_
#include "pluginlib.h"
+#include "ptcomm.h"
namespace metaplugin
Invalid_File_Type,
Status_Handled,
Not_Command,
+ Status_Error,
} Status;
Status read_scan_stat_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp);
Status make_stat_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp);
Status read_scan_tstamp_command(bpContext *ctx, POOL_MEM &cmd, struct save_pkt *sp);
Status make_tstamp_command(bpContext *ctx, POOL_MEM &cmd, const restore_pkt *rp);
+ Status read_attributes_command(bpContext *ctx, PTCOMM *ptcomm, POOL_MEM &cmd, struct save_pkt *sp);
} // attributes
} // metaplugin
-#endif // _METAPLUGIN_STAT_H_
+#endif // _METAPLUGIN_ATTRIBUTES_H_
write_plugin('D', "/* here comes another file line */");
write_plugin('I', "TEST7-Other-End");
signal_eod();
+
+ // check acceptfile() skip
+ write_plugin('C', "ACCEPT:/exclude/file1\n");
+ write_plugin('C', "STAT:F 1048576 200 200 100640 1\n");
+ write_plugin('C', "TSTAMP:1504271937 1504271937 1504271937\n");
+ read_plugin(buf);
+ write_plugin('I', "TEST ACCEPT Response\n");
+ write_plugin('I', buf);
+ if (strncmp(buf, "SKIP", 4) == 0)
+ {
+ write_plugin('I', "TEST ACCEPT Response OK (ACCEPT_FILE_OK)\n");
+ }
+
+ // check acceptfile() ok
+ write_plugin('C', "ACCEPT:/etc/passwd\n");
+ write_plugin('C', "STAT:F 1048576 200 200 100640 1\n");
+ write_plugin('C', "TSTAMP:1504271937 1504271937 1504271937\n");
+ read_plugin(buf);
+ write_plugin('I', "TEST ACCEPT Response\n");
+ write_plugin('I', buf);
+ if (strncmp(buf, "OK", 2) == 0)
+ {
+ write_plugin('I', "TEST ACCEPT Response OK (ACCEPT_FILE_OK)\n");
+ }
+
+ // check acceptfile() with STAT(2) on file
+ write_plugin('C', "ACCEPT:/etc/passwd\n");
+ write_plugin('C', "STAT:/etc/passwd\n");
+ read_plugin(buf);
+ write_plugin('I', "TEST ACCEPT Response\n");
+ write_plugin('I', buf);
+ if (strncmp(buf, "OK", 2) == 0)
+ {
+ write_plugin('I', "TEST ACCEPT Response OK (ACCEPT_FILE_OK)\n");
+ }
}
bool seen = false;
Plugin = "kubernetes:"
Plugin = "kubernetes: regress_backup_other_file"
}
+ Exclude {
+ File = "/exclude/file1"
+ }
}
Job {
BFILE4=$(grep "$Plugin/bucket" ${cwd}/tmp/log5.out | grep -c file.xattr)
BFILE5=$(grep "$Plugin/bucket" ${cwd}/tmp/log5.out | grep -c vmsnap.iso)
BFILE6=$(grep "$Plugin/bucket" ${cwd}/tmp/log5.out | grep -c vm222-other-file.iso)
+BACCEPT=$(grep -c "ACCEPT_FILE_OK" ${cwd}/tmp/log5.out)
BEND=$(grep -w -c "TESTEND" ${cwd}/tmp/log5.out)
-if [ "x$RET" != "xT" ] || [ "$BFILE1" -ne 2 ] || [ "$BFILE2" -ne 2 ] || [ "$BFILE3" -ne 2 ] || [ "$BFILE4" -ne 2 ] || [ "$BFILE5" -ne 2 ] || [ "$BFILE6" -ne 1 ] || [ "$BEND" -ne 2 ]
+if [ "x$RET" != "xT" ] || [ "$BFILE1" -ne 2 ] || [ "$BFILE2" -ne 2 ] || [ "$BFILE3" -ne 2 ] || [ "$BFILE4" -ne 2 ] || [ "$BFILE5" -ne 2 ] || [ "$BFILE6" -ne 1 ] || [ "$BEND" -ne 2 ] || [ "$BACCEPT" -ne 3 ]
then
- echo "log5" "$RET" "$BFILE1" "$BFILE2" "$BFILE3" "$BFILE4" "$BFILE5" "$BFILE6" "$BEND"
+ echo "log5" "$RET" "$BFILE1" "$BFILE2" "$BFILE3" "$BFILE4" "$BFILE5" "$BFILE6" "$BACCEPT" "$BEND"
bstat=$((bstat+8))
fi
Plugin = "openshift:"
Plugin = "openshift: regress_backup_other_file"
}
+ Exclude {
+ File = "/exclude/file1"
+ }
}
Job {
Plugin = "rhv:"
Plugin = "rhv: regress_backup_other_file"
}
+ Exclude {
+ File = "/exclude/file1"
+ }
}
Job {
Plugin = "swift:"
Plugin = "swift: regress_backup_other_file"
}
+ Exclude {
+ File = "/exclude/file1"
+ }
}
Job {