Kern's ToDo List
- 23 February 2008
+ 03 March 2008
Document:
- Add Catalog = to Pool resource so that pools will exist
in only one catalog -- currently Pools are "global".
- Add TLS to bat (should be done).
-
Notes: ./.
+ Item 1: Possibilty to schedule Jobs on last Friday of the month
+ Origin: Carsten Menke <bootsy52 at gmx dot net>
+ Date: 02 March 2008
+ Status:
+
+ What: Currently if you want to run your monthly Backups on the last
+ Friday of each month this is only possible with workarounds (e.g
+ scripting) (As some months got 4 Fridays and some got 5 Fridays)
+ The same is true if you plan to run your yearly Backups on the last
+ Friday of the year. It would be nice to have the ability to use the builtin
+ scheduler for this.
+
+ Why: In many companies the last working day of the week is Friday (or
+ Saturday), so to get the most data of the month onto the monthly tape, the
+ employees are advised to insert the tape for the monthly backups on the last
+ friday of the month.
+
+ Notes: To give this a complete functionality it would be nice if the "first"
+ and "last" Keywords could be implemented in the scheduler, so it is also
+ possible to run monthy backups at the first friday of the month and many things
+ more. So if the syntax would expand to this {first|last} {Month|Week|Day|Mo-Fri}
+ of the {Year|Month|Week} you would be able to run really flexible jobs.
+
+ To got a certain Job run on the last Friday of the Month for example one could
+ then write
+
+ Run = pool=Monthly last Fri of the Month at 23:50
+
+ ## Yearly Backup
+
+ Run = pool=Yearly last Fri of the Year at 23:50
+
+ ## Certain Jobs the last Week of a Month
+
+ Run = pool=LastWeek last Week of the Month at 23:50
+
+ ## Monthly Backup on the last day of the month
+
+ Run = pool=Monthly last Day of the Month at 23:50
========== Already implemented ================================
-/*
- * Bacula Catalog Database Find record interface routines
- *
- * Note, generally, these routines are more complicated
- * that a simple search by name or id. Such simple
- * request are in get.c
- *
- * Kern Sibbald, December 2000
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Bacula Catalog Database Find record interface routines
+ *
+ * Note, generally, these routines are more complicated
+ * that a simple search by name or id. Such simple
+ * request are in get.c
+ *
+ * Kern Sibbald, December 2000
+ *
+ * Version $Id$
+ */
/* The following is necessary so that we do not include
pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */
/* If no Id given, we must find corresponding job */
if (jr->JobId == 0) {
- /* Differential is since last Full backup */
+ /* Differential is since last Full backup */
Mmsg(mdb->cmd,
"SELECT StartTime FROM Job WHERE JobStatus='T' AND Type='%c' AND "
"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s "
{"differentialmaxwaittime", store_time, ITEM(res_job.DiffMaxWaitTime), 0, 0, 0},
{"maxwaittime", store_time, ITEM(res_job.MaxWaitTime), 0, 0, 0},
{"maxstartdelay",store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0},
- {"maxfullage", store_time, ITEM(res_job.MaxFullAge), 0, 0, 0},
+ {"maxfullinterval", store_time, ITEM(res_job.MaxFullInterval), 0, 0, 0},
+ {"maxdiffinterval", store_time, ITEM(res_job.MaxDiffInterval), 0, 0, 0},
{"jobretention", store_time, ITEM(res_job.JobRetention), 0, 0, 0},
{"prefixlinks", store_bool, ITEM(res_job.PrefixLinks), 0, ITEM_DEFAULT, false},
{"prunejobs", store_bool, ITEM(res_job.PruneJobs), 0, ITEM_DEFAULT, false},
{"runscript", store_runscript, ITEM(res_job.RunScripts), 0, ITEM_NO_EQUALS, 0},
{"selectiontype", store_migtype, ITEM(res_job.selection_type), 0, 0, 0},
{"accurate", store_bool, ITEM(res_job.accurate), 0,0,0},
+ {"allowduplicatejobs", store_bool, ITEM(res_job.AllowDuplicateJobs), 0, ITEM_DEFAULT, false},
+ {"allowhigherduplicates", store_bool, ITEM(res_job.AllowHigherDuplicates), 0, ITEM_DEFAULT, true},
+ {"cancelqueuedduplicates", store_bool, ITEM(res_job.CancelQueuedDuplicates), 0, ITEM_DEFAULT, true},
+ {"cancelrunningduplicates", store_bool, ITEM(res_job.CancelRunningDuplicates), 0, ITEM_DEFAULT, false},
{NULL, NULL, {0}, 0, 0, 0}
};
utime_t MaxStartDelay; /* max start delay in seconds */
utime_t RescheduleInterval; /* Reschedule interval */
utime_t JobRetention; /* job retention period in seconds */
- utime_t MaxFullAge; /* Max age of full to avoid upgrade */
+ utime_t MaxFullInterval; /* Maximum time interval between Fulls */
+ utime_t MaxDiffInterval; /* Maximum time interval between Diffs */
+ utime_t DuplicateJobProximity; /* Permitted time between duplicicates */
uint32_t MaxConcurrentJobs; /* Maximum concurrent jobs */
int64_t spool_size; /* Size of spool file for this job */
int RescheduleTimes; /* Number of times to reschedule job */
bool enabled; /* Set if job enabled */
bool OptimizeJobScheduling; /* Set if we should optimize Job scheduling */
bool accurate; /* Set if it is an accurate backup job */
+ bool AllowDuplicateJobs; /* Allow duplicate jobs */
+ bool AllowHigherDuplicates; /* Permit Higher Level */
+ bool CancelQueuedDuplicates; /* Cancel queued jobs */
+ bool CancelRunningDuplicates; /* Cancel Running jobs */
MSGS *messages; /* How and where to send messages */
SCHED *schedule; /* When -- Automatic schedule */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
void get_level_since_time(JCR *jcr, char *since, int since_len)
{
int JobLevel;
- bool FullOk;
- utime_t now, LastFull;
+ bool have_full;
+ bool do_full = false;
+ bool do_diff = false;
+ time_t now;
+ utime_t full_time, diff_time;
since[0] = 0;
/* If job cloned and a since time already given, use it */
jcr->stime = get_pool_memory(PM_MESSAGE);
}
jcr->stime[0] = 0;
- /* Lookup the last FULL backup job to get the time/date for a
+ /*
+ * Lookup the last FULL backup job to get the time/date for a
* differential or incremental save.
*/
switch (jcr->JobLevel) {
case L_DIFFERENTIAL:
case L_INCREMENTAL:
- /* Look up start time of last job */
+ /* Look up start time of last Full job */
+ now = time(NULL);
jcr->jr.JobId = 0; /* flag for db_find_job_start time */
- FullOk = db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime);
+ have_full = db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime);
+#ifdef xxx
/* If there was a successful job, make sure it is recent enough */
- if (FullOk && jcr->job->MaxFullAge > 0) {
- now = btime_to_utime(get_current_btime());
- LastFull = str_to_utime(jcr->stime);
- FullOk = ((now - LastFull) < jcr->job->MaxFullAge);
+ if (jcr->JobLevel == L_INCREMENTAL && have_full && jcr->job->MaxDiffInterval > 0) {
+ /* Lookup last diff job */
+ jcr->jr.JobId = 0;
+ /* ***FIXME*** must find diff start time and not destroy jcr->stime */
+ if (db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime)) {
+ diff_time = str_to_utime(jcr->stime);
+ do_diff = ((now - diff_time) <= jcr->job->MaxDiffInterval);
+ }
+ }
+#endif
+ if (have_full && jcr->job->MaxFullInterval > 0) {
+ full_time = str_to_utime(jcr->stime);
+ do_full = ((now - full_time) <= jcr->job->MaxFullInterval);
}
- if (!FullOk) {
- /* No recent job found, so upgrade this one to Full */
+ if (!have_full || do_full) {
+ /* No recent Full job found, so upgrade this one to Full */
Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db));
Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n"));
bsnprintf(since, since_len, _(" (upgraded from %s)"),
level_to_str(jcr->JobLevel));
jcr->JobLevel = jcr->jr.JobLevel = L_FULL;
+ } else if (do_diff) {
+ /* No recent diff job found, so upgrade this one to Full */
+ Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n"));
+ bsnprintf(since, since_len, _(" (upgraded from %s)"),
+ level_to_str(jcr->JobLevel));
+ jcr->JobLevel = jcr->jr.JobLevel = L_DIFFERENTIAL;
} else {
if (jcr->job->rerun_failed_levels) {
if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) {
bs->send();
}
-static void sendit(const char *msg, int len, void *arg)
+static void sendit(const char *msg, int len, void *bs)
{
- BSOCK *bs = (BSOCK *)arg;
- memcpy(bs->msg, msg, len+1);
- bs->msglen = len+1;
- bs->send();
+ sendit(msg, len, (BSOCK *)bs);
}
static void sendit(POOL_MEM &msg, int len, BSOCK *bs)
General:
03Mar08
+kes Implement 'MaxFullInterval' and start 'MaxDiffInterval' based on
+ some ideas in patch from Scott Bailey.
+kes Begin implementation of duplicate Job control.
+kes Fix some of Win32 build after recent additions.
kes Apply patch from Frank Kardel that implements 'honor no dump flag',
which causes the FD to detect whether or not the OS has the
honor no dump bit (*BSD systems), and if so, to skip backing up
kes Tweak plugin code.
17Feb08
kes Plugin debug code + tweak a couple bat dialog layouts
-16Feb08
-kes Apply Max Full Age patch submitted by Scott Bailey
- <scott dot bailey at eds dot com>
14Feb08
kes Fix creating first JobMedia record during Migration to include
proper index. This caused slow restores of migrated jobs.