Skip to content

Commit

Permalink
Implement plugin options passing.
Browse files Browse the repository at this point in the history
Implement a new feature to pass plugin option as part of the restore process.
Most of the plugin options input was already implemented but for the restore
the options were never pushed to the file daemon. We should pass it to the
filed and raise a bEventPluginCommand event. This way a user can pass in extra
hints to the plugin for the restore process. Currently the plugin only gets
passed in the plugin options that were defined at the moment the backup was made.

The options defined by the user at restore time are passed before the actual
options saved at backup time are passed so the plugin should take care to ignore
any of the options passed in as part of the backup stream being restored
when it already got a override at restore time.

We increased the FD protocol number to 52 to be able to detect if the file daemon
understand the new protocol keyword.

Along the way we tweaked the layout of fileset traversal code somewhat. Added
some spaces and fixed the scoping of the variables somewhat. So you understand
what is going on. And fixed the comments in the filed plugin code.

Fixes #207: Implement plugin options passing.
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent ede332d commit 7c1006b
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 121 deletions.
1 change: 1 addition & 0 deletions src/dird/dird.h
Expand Up @@ -120,5 +120,6 @@ typedef struct s_vol_list {
#define FD_VERSION_4 4
#define FD_VERSION_5 5
#define FD_VERSION_51 51
#define FD_VERSION_52 52

#include "protos.h"
122 changes: 88 additions & 34 deletions src/dird/fd_cmds.c
Expand Up @@ -46,12 +46,16 @@ static char jobcmd[] =
/* Note, mtime_only is not used here -- implemented as file option */
static char levelcmd[] =
"level = %s%s%s mtime_only=%d %s%s\n";
static char runscript[] =
static char runscriptcmd[] =
"Run OnSuccess=%u OnFailure=%u AbortOnError=%u When=%u Command=%s\n";
static char runbeforenow[] =
static char runbeforenowcmd[] =
"RunBeforeNow\n";
static char restoreobjectendcmd[] =
"restoreobject end\n";
static char bandwidthcmd[] =
"setbandwidth=%lld Job=%s\n";
static char pluginoptionscmd[] =
"pluginoptions %s\n";

/* Responses received from File daemon */
static char OKinc[] =
Expand All @@ -68,6 +72,8 @@ static char OKRestoreObject[] =
"2000 OK ObjectRestored\n";
static char OKBandwidth[] =
"2000 OK Bandwidth\n";
static char OKPluginOptions[] =
"2000 OK PluginOptions\n";

/* Forward referenced functions */
static bool send_list_item(JCR *jcr, const char *code, char *item, BSOCK *fd);
Expand Down Expand Up @@ -251,16 +257,15 @@ static bool send_fileset(JCR *jcr)
int num;
bool include = true;

for ( ;; ) {
while (1) {
if (include) {
num = fileset->num_includes;
} else {
num = fileset->num_excludes;
}
for (int i=0; i<num; i++) {
for (int i = 0; i < num; i++) {
char *item;
INCEXE *ie;
int j, k;

if (include) {
ie = fileset->include_items[i];
Expand All @@ -269,108 +274,136 @@ static bool send_fileset(JCR *jcr)
ie = fileset->exclude_items[i];
fd->fsend("E\n");
}

if (ie->ignoredir) {
fd->fsend("Z %s\n", ie->ignoredir);
}
for (j=0; j<ie->num_opts; j++) {
FOPTS *fo = ie->opts_list[j];

for (int j = 0; j < ie->num_opts; j++) {
FOPTS *fo = ie->opts_list[j];
bool enhanced_wild = false;
for (k=0; fo->opts[k]!='\0'; k++) {

for (int k = 0; fo->opts[k] != '\0'; k++) {
if (fo->opts[k]=='W') {
enhanced_wild = true;
break;
}
}

/* Strip out compression option Zn if disallowed for this Storage */
/*
* Strip out compression option Zn if disallowed for this Storage
*/
if (store && !store->AllowCompress) {
char newopts[MAX_FOPTS];
bool done=false; /* print warning only if compression enabled in FS */
int j = 0;
for (k=0; fo->opts[k]!='\0'; k++) {
/* Z compress option is followed by the single-digit compress level or 'o' */
int l = 0;

for (int k = 0; fo->opts[k] != '\0'; k++) {
/*
* Z compress option is followed by the single-digit compress level or 'o'
*/
if (fo->opts[k]=='Z') {
done=true;
done = true;
k++; /* skip option and level */
} else {
newopts[j] = fo->opts[k];
j++;
newopts[l] = fo->opts[k];
l++;
}
}
newopts[j] = '\0';
newopts[l] = '\0';

if (done) {
Jmsg(jcr, M_INFO, 0,
_("FD compression disabled for this Job because AllowCompress=No in Storage resource.\n") );
_("FD compression disabled for this Job because AllowCompress=No in Storage resource.\n") );
}
/* Send the new trimmed option set without overwriting fo->opts */

/*
* Send the new trimmed option set without overwriting fo->opts
*/
fd->fsend("O %s\n", newopts);
} else {
/* Send the original options */
/*
* Send the original options
*/
fd->fsend("O %s\n", fo->opts);
}

for (k=0; k<fo->regex.size(); k++) {
for (int k = 0; k < fo->regex.size(); k++) {
fd->fsend("R %s\n", fo->regex.get(k));
}
for (k=0; k<fo->regexdir.size(); k++) {

for (int k = 0; k < fo->regexdir.size(); k++) {
fd->fsend("RD %s\n", fo->regexdir.get(k));
}
for (k=0; k<fo->regexfile.size(); k++) {

for (int k = 0; k < fo->regexfile.size(); k++) {
fd->fsend("RF %s\n", fo->regexfile.get(k));
}
for (k=0; k<fo->wild.size(); k++) {

for (int k = 0; k<fo->wild.size(); k++) {
fd->fsend("W %s\n", fo->wild.get(k));
}
for (k=0; k<fo->wilddir.size(); k++) {

for (int k = 0; k < fo->wilddir.size(); k++) {
fd->fsend("WD %s\n", fo->wilddir.get(k));
}
for (k=0; k<fo->wildfile.size(); k++) {

for (int k = 0; k < fo->wildfile.size(); k++) {
fd->fsend("WF %s\n", fo->wildfile.get(k));
}
for (k=0; k<fo->wildbase.size(); k++) {

for (int k = 0; k < fo->wildbase.size(); k++) {
fd->fsend("W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k));
}
for (k=0; k<fo->base.size(); k++) {

for (int k = 0; k < fo->base.size(); k++) {
fd->fsend("B %s\n", fo->base.get(k));
}
for (k=0; k<fo->fstype.size(); k++) {

for (int k = 0; k < fo->fstype.size(); k++) {
fd->fsend("X %s\n", fo->fstype.get(k));
}
for (k=0; k<fo->drivetype.size(); k++) {

for (int k = 0; k < fo->drivetype.size(); k++) {
fd->fsend("XD %s\n", fo->drivetype.get(k));
}

if (fo->plugin) {
fd->fsend("G %s\n", fo->plugin);
}

if (fo->reader) {
fd->fsend("D %s\n", fo->reader);
}

if (fo->writer) {
fd->fsend("T %s\n", fo->writer);
}

fd->fsend("N\n");
}

for (j=0; j<ie->name_list.size(); j++) {
for (int j = 0; j < ie->name_list.size(); j++) {
item = (char *)ie->name_list.get(j);
if (!send_list_item(jcr, "F ", item, fd)) {
goto bail_out;
}
}
fd->fsend("N\n");
for (j=0; j<ie->plugin_list.size(); j++) {

for (int j = 0; j < ie->plugin_list.size(); j++) {
item = (char *)ie->plugin_list.get(j);
if (!send_list_item(jcr, "P ", item, fd)) {
goto bail_out;
}
}
fd->fsend("N\n");
}

if (!include) { /* If we just did excludes */
break; /* all done */
}

include = false; /* Now do excludes */
}

Expand Down Expand Up @@ -540,7 +573,7 @@ int send_runscripts_commands(JCR *jcr)

Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);

fd->fsend(runscript,
fd->fsend(runscriptcmd,
cmd->on_success,
cmd->on_failure,
cmd->fail_on_error,
Expand Down Expand Up @@ -573,7 +606,7 @@ int send_runscripts_commands(JCR *jcr)
* Tell the FD to execute the ClientRunBeforeJob
*/
if (has_before_jobs) {
fd->fsend(runbeforenow);
fd->fsend(runbeforenowcmd);
if (!response(jcr, fd, OKRunBeforeNow, "RunBeforeNow", DISPLAY_ERROR)) {
goto bail_out;
}
Expand Down Expand Up @@ -652,6 +685,27 @@ static int restore_object_handler(void *ctx, int num_fields, char **row)
return 0;
}

bool send_plugin_options(JCR *jcr)
{
BSOCK *fd = jcr->file_bsock;
POOLMEM *msg;

if (jcr->plugin_options) {
msg = get_pool_memory(PM_FNAME);
pm_strcpy(msg, jcr->plugin_options);
bash_spaces(msg);

fd->fsend(pluginoptionscmd, msg);
free_pool_memory(msg);

if (!response(jcr, fd, OKPluginOptions, "PluginOptions", DISPLAY_ERROR)) {
Jmsg(jcr, M_FATAL, 0, _("Plugin options failed.\n"));
return false;
}
}
return true;
}

bool send_restore_objects(JCR *jcr)
{
char ed1[50];
Expand Down Expand Up @@ -682,7 +736,7 @@ bool send_restore_objects(JCR *jcr)
*/
if (octx.count > 0) {
fd = jcr->file_bsock;
fd->fsend("restoreobject end\n");
fd->fsend(restoreobjectendcmd);
if (!response(jcr, fd, OKRestoreObject, "RestoreObject", DISPLAY_ERROR)) {
Jmsg(jcr, M_FATAL, 0, _("RestoreObject failed.\n"));
return false;
Expand Down
1 change: 1 addition & 0 deletions src/dird/protos.h
Expand Up @@ -101,6 +101,7 @@ void get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
char *link, char *attr, int stream);
int send_runscripts_commands(JCR *jcr);
bool send_plugin_options(JCR *jcr);
bool send_restore_objects(JCR *jcr);
bool cancel_file_daemon_job(UAContext *ua, JCR *jcr);
void do_native_client_status(UAContext *ua, CLIENTRES *client, char *cmd);
Expand Down
11 changes: 11 additions & 0 deletions src/dird/restore.c
Expand Up @@ -315,10 +315,21 @@ static inline bool do_native_restore_bootstrap(JCR *jcr)
if (!send_runscripts_commands(jcr)) {
goto bail_out;
}

if (!send_restore_objects(jcr)) {
Dmsg0(000, "FAIL: Send restore objects\n");
goto bail_out;
}

/*
* Only FD version 52 and later understand the sending of plugin options.
*/
if (jcr->FDVersion >= FD_VERSION_52) {
if (!send_plugin_options(jcr)) {
Dmsg0(000, "FAIL: Send plugin options\n");
goto bail_out;
}
}
}

fd->fsend("%s", restore_cmd.c_str());
Expand Down
2 changes: 0 additions & 2 deletions src/dird/ua_run.c
Expand Up @@ -1820,8 +1820,6 @@ static bool scan_command_line_arguments(UAContext *ua, RUN_CTX &rc)
kw_ok = true;
break;
case 26: /* pluginoptions */
ua->send_msg(_("Plugin Options not yet implemented.\n"));
return false;
if (rc.plugin_options) {
ua->send_msg(_("Plugin Options specified twice.\n"));
return false;
Expand Down
3 changes: 2 additions & 1 deletion src/filed/authenticate.c
Expand Up @@ -40,11 +40,12 @@ const int dbglvl = 50;
* 5 24Nov11 - Added new restore object command format (pluginname) 6.0
*
* 51 21Mar13 - Added reverse datachannel initialization
* 52 13Jul13 - Added plugin options
*/
static char OK_hello_compat[] =
"2000 OK Hello 5\n";
static char OK_hello[] =
"2000 OK Hello 51\n";
"2000 OK Hello 52\n";

static char Dir_sorry[] =
"2999 Authentication failed.\n";
Expand Down

0 comments on commit 7c1006b

Please sign in to comment.