return true;
}
+/* Take all base jobs from job resource and find the
+ * last L_BASE jobid.
+ */
+static bool get_base_jobids(JCR *jcr, POOLMEM *jobids)
+{
+ JOB_DBR jr;
+ JOB *job;
+ JobId_t id;
+ char str_jobid[50];
+
+ if (!jcr->job->base) {
+ return false; /* no base job, stop accurate */
+ }
+
+ memset(&jr, 0, sizeof(JOB_DBR));
+ jr.StartTime = jcr->jr.StartTime;
+
+ foreach_alist(job, jcr->job->base) {
+ bstrncpy(jr.Name, job->name(), sizeof(jr.Name));
+ db_get_base_jobid(jcr, jcr->db, &jr, &id);
+
+ if (id) {
+ if (jobids[0]) {
+ pm_strcat(jobids, ",");
+ }
+ pm_strcat(jobids, edit_uint64(id, str_jobid));
+ }
+ }
+
+ return *jobids != '\0';
+}
+
/*
- * Foreach files in currrent list, send "/path/fname\0LStat" to FD
+ * Foreach files in currrent list, send "/path/fname\0LStat\0MD5" to FD
*/
static int accurate_list_handler(void *ctx, int num_fields, char **row)
{
return 1;
}
- if (row[2] > 0) { /* discard when file_index == 0 */
- jcr->file_bsock->fsend("%s%s%c%s", row[0], row[1], 0, row[4]);
+ if (row[2] == 0) { /* discard when file_index == 0 */
+ return 0;
+ }
+
+ /* sending with checksum */
+ if (num_fields == 6 && row[5][0] && row[5][1]) { /* skip checksum = '0' */
+ jcr->file_bsock->fsend("%s%s%c%s%c%s",
+ row[0], row[1], 0, row[4], 0, row[5]);
+ } else {
+ jcr->file_bsock->fsend("%s%s%c%s",
+ row[0], row[1], 0, row[4]);
}
return 0;
}
/*
* Send current file list to FD
* DIR -> FD : accurate files=xxxx
- * DIR -> FD : /path/to/file\0Lstat
- * DIR -> FD : /path/to/dir/\0Lstat
+ * DIR -> FD : /path/to/file\0Lstat\0MD5
+ * DIR -> FD : /path/to/dir/\0Lstat\0MD5
* ...
* DIR -> FD : EOD
*/
bool send_accurate_current_files(JCR *jcr)
{
POOL_MEM buf;
+ bool ret=true;
db_list_ctx jobids;
db_list_ctx nb;
- if (!jcr->accurate || job_canceled(jcr) || jcr->get_JobLevel()==L_FULL) {
+ if (!jcr->accurate || job_canceled(jcr)) {
+ return true;
+ }
+ /* In base level, no previous job is used */
+ if (jcr->get_JobLevel() == L_BASE) {
return true;
}
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
- if (jobids.count == 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
- return false;
+ if (jcr->get_JobLevel() == L_FULL) {
+ /* On Full mode, if no previous base job, no accurate things */
+ if (!get_base_jobids(jcr, jobids)) {
+ goto bail_out;
+ }
+ jcr->HasBase = true;
+ Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids);
+
+ } else {
+ /* For Incr/Diff level, we search for older jobs */
+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
+
+ /* We are in Incr/Diff, but no Full to build the accurate list... */
+ if (*jobids == 0) {
+ ret=false;
+ Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
+ goto bail_out;
+ }
}
+
if (jcr->JobId) { /* display the message only for real jobs */
Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n"));
}
+
/* to be able to allocate the right size for htable */
Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)", jobids.list);
db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb);
Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion");
return false;
}
+
+ if (jcr->HasBase) {
+ jcr->nb_base_files = str_to_int64(nb);
+ db_create_base_file_list(jcr, jcr->db, jobids);
+ db_get_base_file_list(jcr, jcr->db,
+ accurate_list_handler, (void *)jcr);
- db_get_file_list(jcr, jcr->db_batch, jobids.list, accurate_list_handler, (void *)jcr);
+ } else {
+ db_get_file_list(jcr, jcr->db_batch, jobids,
+ accurate_list_handler, (void *)jcr);
+ }
/* TODO: close the batch connexion ? (can be used very soon) */
jcr->file_bsock->signal(BNET_EOD);
- return true;
+bail_out:
+ return ret;
}
/*
/* Pickup Job termination data */
stat = wait_for_job_termination(jcr);
db_write_batch_file_records(jcr); /* used by bulk batch file insert */
+
+ if (jcr->HasBase &&
+ !db_commit_base_file_attributes_record(jcr, jcr->db))
+ {
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+ }
+
if (stat == JS_Terminated) {
backup_cleanup(jcr, stat);
return true;
jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
+ if (jcr->HasBase) {
+ Dmsg3(0, "Base files/Used files %lld/%lld=%.2f%%\n", jcr->nb_base_files,
+ jcr->nb_base_files_used,
+ jcr->nb_base_files_used*100.0/jcr->nb_base_files);
+ }
// bmicrosleep(15, 0); /* for debugging SIGHUP */
Jmsg(jcr, msg_type, 0, _("%s %s %s (%s): %s\n"