}
make_estimate(jcr);
bnet_fsend(dir, OKest, jcr->num_files_examined,
- edit_uint64(jcr->JobBytes, ed2));
+ edit_uint64_with_commas(jcr->JobBytes, ed2));
bnet_sig(dir, BNET_EOD);
return 1;
}
static void add_fname_to_list(JCR *jcr, char *fname, int list)
{
- char *p;
- if (list == INC_LIST) {
- add_fname_to_include_list((FF_PKT *)jcr->ff, 1, fname);
- } else {
- /* Skip leading options -- currently ignored */
- for (p=fname; *p && *p != ' '; p++)
- { }
- /* Skip spaces */
- for ( ; *p && *p == ' '; p++)
- { }
- add_fname_to_exclude_list((FF_PKT *)jcr->ff, p);
+ char *p, *q;
+ BPIPE *bpipe;
+ POOLMEM *fn;
+ FILE *ffd;
+ char buf[1000];
+ int optlen;
+ int stat;
+
+ /* Skip leading options -- currently ignored */
+ for (p=fname; *p && *p != ' '; p++)
+ { }
+ /* Skip spaces, and q points to first space */
+ for (q=NULL; *p && *p == ' '; p++) {
+ if (!q) {
+ q = p;
+ }
+ }
+
+ switch (*p) {
+ case '|':
+ fn = get_pool_memory(PM_FNAME);
+ fn = edit_job_codes(jcr, fn, p, "");
+ bpipe = open_bpipe(fn, 0, "r");
+ free_pool_memory(fn);
+ if (!bpipe) {
+ Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
+ p, strerror(errno));
+ return;
+ }
+ /* Copy File options */
+ if (list == INC_LIST) {
+ *q = 0; /* terminate options */
+ strcpy(buf, fname);
+ strcat(buf, " ");
+ optlen = strlen(buf);
+ } else {
+ optlen = 0;
+ }
+ while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) {
+ strip_trailing_junk(buf);
+ if (list == INC_LIST) {
+ add_fname_to_include_list((FF_PKT *)jcr->ff, 1, buf);
+ } else {
+ add_fname_to_exclude_list((FF_PKT *)jcr->ff, buf);
+ }
+ }
+ if ((stat=close_bpipe(bpipe)) != 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. RtnStat=%d ERR=%s\n"),
+ p, stat, strerror(errno));
+ return;
+ }
+ break;
+ case '<':
+ p++; /* skip over < */
+ if ((ffd = fopen(p, "r")) == NULL) {
+ Jmsg(jcr, M_FATAL, 0, _("Cannot open %s file: %s. ERR=%s\n"),
+ list==INC_LIST?"included":"excluded", p, strerror(errno));
+ return;
+ }
+ /* Copy File options */
+ if (list == INC_LIST) {
+ *q = 0; /* terminate options */
+ strcpy(buf, fname);
+ strcat(buf, " ");
+ optlen = strlen(buf);
+ } else {
+ optlen = 0;
+ }
+ while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) {
+ strip_trailing_junk(buf);
+ if (list == INC_LIST) {
+ add_fname_to_include_list((FF_PKT *)jcr->ff, 1, buf);
+ } else {
+ add_fname_to_exclude_list((FF_PKT *)jcr->ff, buf);
+ }
+ }
+ fclose(ffd);
+ break;
+ default:
+ if (list == INC_LIST) {
+ add_fname_to_include_list((FF_PKT *)jcr->ff, 1, fname);
+ } else {
+ add_fname_to_exclude_list((FF_PKT *)jcr->ff, p);
+ }
+ break;
}
}
static int level_cmd(JCR *jcr)
{
BSOCK *dir = jcr->dir_bsock;
- POOLMEM *level;
+ POOLMEM *level, *buf = NULL;
struct tm tm;
time_t mtime;
int mtime_only;
level = get_memory(dir->msglen+1);
Dmsg1(110, "level_cmd: %s", dir->msg);
if (sscanf(dir->msg, "level = %s ", level) != 1) {
- pm_strcpy(&jcr->errmsg, dir->msg);
- Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
- free_memory(level);
- return 0;
+ goto bail_out;
}
/* Base backup requested? */
if (strcmp(level, "base") == 0) {
/*
* Backup requested since <date> <time>
* This form is also used for incremental and differential
+ * This code is deprecated. See since_utime for new code.
*/
} else if (strcmp(level, "since") == 0) {
jcr->JobLevel = L_SINCE;
if (sscanf(dir->msg, "level = since %d-%d-%d %d:%d:%d mtime_only=%d",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
&tm.tm_hour, &tm.tm_min, &tm.tm_sec, &mtime_only) != 7) {
- pm_strcpy(&jcr->errmsg, dir->msg);
- Jmsg1(jcr, M_FATAL, 0, _("Bad scan of date/time: %s\n"), jcr->errmsg);
- free_memory(level);
- return 0;
+ goto bail_out;
}
tm.tm_year -= 1900;
tm.tm_mon -= 1;
jcr->incremental = 1; /* set incremental or decremental backup */
jcr->mtime = mtime; /* set since time */
jcr->mtime_only = mtime_only; /* and what to compare */
+ /*
+ * We get his UTC since time, then sync the clocks and correct it
+ * to agree with our clock.
+ */
+ } else if (strcmp(level, "since_utime") == 0) {
+ buf = get_memory(dir->msglen+1);
+ utime_t since_time, adj;
+ btime_t his_time, bt_start, rt=0, bt_adj=0;
+ jcr->JobLevel = L_SINCE;
+ if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
+ buf, &mtime_only) != 2) {
+ goto bail_out;
+ }
+ since_time = str_to_uint64(buf); /* this is the since time */
+ char ed1[50], ed2[50];
+ /*
+ * Sync clocks by polling him for the time. We take
+ * 10 samples of his time throwing out the first two.
+ */
+ for (int i=0; i<10; i++) {
+ bt_start = get_current_btime();
+ bnet_sig(dir, BNET_BTIME); /* poll for time */
+ if (bnet_recv(dir) <= 0) { /* get response */
+ goto bail_out;
+ }
+ if (sscanf(dir->msg, "btime %s", buf) != 1) {
+ goto bail_out;
+ }
+ if (i < 2) { /* toss first two results */
+ continue;
+ }
+ his_time = str_to_uint64(buf);
+ rt = get_current_btime() - bt_start; /* compute round trip time */
+ bt_adj -= his_time - bt_start - rt/2;
+ Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
+ }
+
+ bt_adj = bt_adj / 8; /* compute average time */
+ Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
+ adj = btime_to_utime(bt_adj);
+ since_time += adj; /* adjust for clock difference */
+ if (adj != 0) {
+ Jmsg(jcr, M_INFO, 0, _("Since time adjusted by %d seconds.\n"), adj);
+ }
+ bnet_sig(dir, BNET_EOD);
+
+ Dmsg2(100, "adj = %d since_time=%d\n", (int)adj, (int)since_time);
+ jcr->incremental = 1; /* set incremental or decremental backup */
+ jcr->mtime = since_time; /* set since time */
+ jcr->mtime_only = mtime_only; /* and what to compare */
} else {
Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level);
free_memory(level);
return 0;
}
free_memory(level);
+ if (buf) {
+ free_memory(buf);
+ }
return bnet_fsend(dir, OKlevel);
+
+bail_out:
+ pm_strcpy(&jcr->errmsg, dir->msg);
+ Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
+ free_memory(level);
+ if (buf) {
+ free_memory(buf);
+ }
+ return 0;
}
/*
jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
} else if (strcasecmp(level, "data") == 0){
jcr->JobLevel = L_VERIFY_DATA;
+ } else if (strcasecmp(level, "disk_to_catalog") == 0) {
+ jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
} else {
bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
return 0;
/* Inform Storage daemon that we are done */
bnet_sig(sd, BNET_TERMINATE);
+ break;
+ case L_VERIFY_DISK_TO_CATALOG:
+ do_verify(jcr);
break;
default:
bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
if (jcr->RestoreBootstrap) {
unlink(jcr->RestoreBootstrap);
free_pool_memory(jcr->RestoreBootstrap);
+ jcr->RestoreBootstrap = NULL;
}
if (jcr->last_fname) {
free_pool_memory(jcr->last_fname);
char buf[2000];
BSOCK *sd = jcr->store_bsock;
char *bootstrap = "bootstrap\n";
+ int stat = 0;
Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
if (!jcr->RestoreBootstrap) {
Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
jcr->RestoreBootstrap, strerror(errno));
set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ goto bail_out;
}
pm_strcpy(&sd->msg, bootstrap);
sd->msglen = strlen(sd->msg);
fclose(bs);
if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ goto bail_out;
}
- return 1;
+ stat = 1;
+
+bail_out:
+ if (jcr->RestoreBootstrap) {
+ unlink(jcr->RestoreBootstrap);
+ free_pool_memory(jcr->RestoreBootstrap);
+ jcr->RestoreBootstrap = NULL;
+ }
+
+ return stat;
}