/* Take all base jobs from job resource and find the
* last L_BASE jobid.
*/
-static bool get_base_jobids(JCR *jcr, POOLMEM *jobids)
+static bool get_base_jobids(JCR *jcr, db_list_ctx *jobids)
{
JOB_DBR jr;
JOB *job;
db_get_base_jobid(jcr, jcr->db, &jr, &id);
if (id) {
- if (jobids[0]) {
- pm_strcat(jobids, ",");
+ if (jobids->count) {
+ pm_strcat(jobids->list, ",");
}
- pm_strcat(jobids, edit_uint64(id, str_jobid));
+ pm_strcat(jobids->list, edit_uint64(id, str_jobid));
+ jobids->count++;
}
}
- return *jobids != '\0';
+ return jobids->count > 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 (jcr->use_accurate_chksum
+ && num_fields == 6
+ && row[5][0] /* skip checksum = '0' */
+ && row[5][1])
+ {
+ 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;
}
+/* In this procedure, we check if the current fileset is using checksum
+ * FileSet-> Include-> Options-> Accurate/Verify/BaseJob=checksum
+ * This procedure uses jcr->HasBase, so it must be call after the initialization
+ */
+static bool is_checksum_needed_by_fileset(JCR *jcr)
+{
+ FILESET *f;
+ INCEXE *inc;
+ FOPTS *fopts;
+ bool in_block=false;
+ bool have_basejob_option=false;
+ if (!jcr->job || !jcr->job->fileset) {
+ return false;
+ }
+
+ f = jcr->job->fileset;
+
+ for (int i=0; i < f->num_includes; i++) { /* Parse all Include {} */
+ inc = f->include_items[i];
+
+ for (int j=0; j < inc->num_opts; j++) { /* Parse all Options {} */
+ fopts = inc->opts_list[j];
+
+ for (char *k=fopts->opts; *k ; k++) { /* Try to find one request */
+ switch (*k) {
+ case 'V': /* verify */
+ in_block = (jcr->get_JobType() == JT_VERIFY); /* not used now */
+ break;
+ case 'J': /* Basejob keyword */
+ have_basejob_option = in_block = jcr->HasBase;
+ break;
+ case 'C': /* Accurate keyword */
+ in_block = (jcr->get_JobLevel() != L_FULL);
+ break;
+ case ':': /* End of keyword */
+ in_block = false;
+ break;
+ case '5': /* MD5 */
+ case '1': /* SHA1 */
+ if (in_block) {
+ Dmsg0(50, "Checksum will be sent to FD\n");
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ /* By default for BaseJobs, we send the checksum */
+ if (!have_basejob_option && jcr->HasBase) {
+ return true;
+ }
+
+ Dmsg0(50, "Checksum will be sent to FD\n");
+ return false;
+}
+
/*
* 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
*/
{
POOL_MEM buf;
bool ret=true;
+ db_list_ctx jobids;
+ db_list_ctx nb;
if (!jcr->accurate || job_canceled(jcr)) {
return true;
if (jcr->get_JobLevel() == L_BASE) {
return true;
}
-
- POOLMEM *nb = get_pool_memory(PM_FNAME);
- POOLMEM *jobids = get_pool_memory(PM_FNAME);
- nb[0] = jobids[0] = '\0';
-
+
if (jcr->get_JobLevel() == L_FULL) {
/* On Full mode, if no previous base job, no accurate things */
- if (!get_base_jobids(jcr, jobids)) {
+ if (!get_base_jobids(jcr, &jobids)) {
goto bail_out;
}
jcr->HasBase = true;
- Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids);
+ Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids.list);
} else {
/* For Incr/Diff level, we search for older jobs */
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
+ 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) {
+ if (jobids.count == 0) {
ret=false;
Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
goto bail_out;
}
}
+ /* Don't send and store the checksum if fileset doesn't require it */
+ jcr->use_accurate_chksum = is_checksum_needed_by_fileset(jcr);
+
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);
- db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb);
- Dmsg2(0, "jobids=%s nb=%s\n", jobids, nb);
- jcr->file_bsock->fsend("accurate files=%s\n", nb);
+ 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);
+ Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list);
+ jcr->file_bsock->fsend("accurate files=%s\n", nb.list);
if (!db_open_batch_connexion(jcr, jcr->db)) {
- ret = false;
- Jmsg0(jcr, M_FATAL, 0, "Can't get dedicate sql connexion");
- goto bail_out;
+ 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);
+ jcr->nb_base_files = str_to_int64(nb.list);
+ db_create_base_file_list(jcr, jcr->db, jobids.list);
db_get_base_file_list(jcr, jcr->db,
accurate_list_handler, (void *)jcr);
} else {
- db_get_file_list(jcr, jcr->db_batch, jobids,
+ db_get_file_list(jcr, jcr->db_batch, jobids.list,
accurate_list_handler, (void *)jcr);
}
jcr->file_bsock->signal(BNET_EOD);
bail_out:
- free_pool_memory(jobids);
- free_pool_memory(nb);
-
return ret;
}
CLIENT_DBR cr;
double kbps, compression;
utime_t RunTime;
+ POOL_MEM base_info;
if (jcr->get_JobLevel() == L_VIRTUAL_FULL) {
vbackup_cleanup(jcr, TermCode);
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);
+ Mmsg(base_info, " 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 */
" SD Bytes Written: %s (%sB)\n"
" Rate: %.1f KB/s\n"
" Software Compression: %s\n"
+"%s" /* Basefile info */
" VSS: %s\n"
" Encryption: %s\n"
" Accurate: %s\n"
edit_uint64_with_suffix(jcr->SDJobBytes, ec6),
kbps,
compress,
+ base_info.c_str(),
jcr->VSS?_("yes"):_("no"),
jcr->Encrypt?_("yes"):_("no"),
jcr->accurate?_("yes"):_("no"),