The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
/* If this job doesn't exist anymore in the configuration, delete it */
if (GetResWithName(R_JOB, row[0]) == NULL) {
- return 1;
+ return 0;
}
/* If this fileset doesn't exist anymore in the configuration, delete it */
if (GetResWithName(R_FILESET, row[1]) == NULL) {
- return 1;
+ return 0;
}
/* If this client doesn't exist anymore in the configuration, delete it */
if (GetResWithName(R_CLIENT, row[2]) == NULL) {
- return 1;
+ return 0;
}
/* Don't compute accurate things for Verify jobs */
if (*row[5] == 'V') {
- return 1;
+ return 0;
}
res = (struct accurate_check_ctx*) malloc(sizeof(struct accurate_check_ctx));
char ed1[50], ed2[50];
alist *jobids_check=NULL;
struct accurate_check_ctx *elt;
- db_list_ctx jobids;
+ db_list_ctx jobids, tempids;
JOB_DBR jr;
db_lock(ua->db);
+ memset(&del, 0, sizeof(del));
memset(&cr, 0, sizeof(cr));
bstrncpy(cr.Name, client->name(), sizeof(cr.Name));
edit_int64(now - period, ed1); /* Jobs older than ed1 are good candidates */
edit_int64(cr.ClientId, ed2);
- memset(&del, 0, sizeof(del));
del.max_ids = 100;
del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
del.PurgedFiles = (char *)malloc(del.max_ids);
/*
* Select all files that are older than the JobRetention period
- * and stuff them into the "DeletionCandidates" table.
+ * and add them into the "DeletionCandidates" table.
*/
Mmsg(query,
"INSERT INTO DelCandidates "
"SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus "
"FROM Job "
- "WHERE Type IN ('B', 'C', 'M', 'V', 'D', 'R', 'c', 'm') "
+ "WHERE Type IN ('B', 'C', 'M', 'V', 'D', 'R', 'c', 'm', 'g') "
"AND JobTDate<%s AND ClientId=%s",
ed1, ed2);
"JOIN Job USING (JobId) "
"JOIN Client USING (ClientId) "
"JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId) "
- "WHERE Type NOT IN ('D', 'R', 'c', 'm') " /* Discard Admin, Restore, Copy, Migration */
+ "WHERE Job.Type IN ('B') " /* Look only Backup jobs */
+ "AND Job.JobStatus IN ('T', 'W') " /* Look only useful jobs */
);
/* The job_select_handler will skip jobs or filesets that are no longer
/* To find useful jobs, we do like an incremental */
jr.JobLevel = L_INCREMENTAL;
foreach_alist(elt, jobids_check) {
- jr.ClientId = elt->ClientId;
+ jr.ClientId = elt->ClientId; /* should be always the same */
jr.FileSetId = elt->FileSetId;
- db_accurate_get_jobids(ua->jcr, ua->db, &jr, &jobids);
+ db_accurate_get_jobids(ua->jcr, ua->db, &jr, &tempids);
+ jobids.cat(tempids);
}
- /* Discard latest Verify level=InitCatalog job */
+ /* Discard latest Verify level=InitCatalog job
+ * TODO: can have multiple fileset
+ */
Mmsg(query,
"SELECT JobId, JobTDate "
"FROM Job "
/* We also need to exclude all basejobs used */
db_get_used_base_jobids(ua->jcr, ua->db, jobids.list, &jobids);
- /* Removing exceptions from the DelCandidates list */
- Mmsg(query, "DELETE FROM DelCandidates WHERE JobId IN (%s)", jobids.list);
+ /* Removing useful jobs from the DelCandidates list */
+ Mmsg(query, "DELETE FROM DelCandidates "
+ "WHERE JobId IN (%s) " /* JobId used in accurate */
+ "AND JobFiles!=0", /* Discard when JobFiles=0 */
+ jobids.list);
+
if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
ua->error_msg("%s", db_strerror(ua->db));
goto bail_out; /* Don't continue if the list isn't clean */
Dmsg1(60, "jobids to exclude = %s\n", jobids.list);
}
- /* Prune garbage jobs (JobStatus not successful) */
- Mmsg(query,
- "INSERT INTO DelCandidates "
- "SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus "
- "FROM Job "
- "WHERE ( JobFiles=0 "
- "OR JobStatus NOT IN ('T', 'W') "
- ") "
- "AND JobTDate < %s "
- "AND ClientId = %s ",
- ed1, ed2);
-
- Dmsg1(150, "Query=%s\n", query.c_str());
- if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
- ua->error_msg("%s", db_strerror(ua->db));
- }
-
/* We use DISTINCT because we can have two times the same job */
Mmsg(query,
"SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "