- Backup conf/exe (all daemons)
- Backup up system state
- Detect state change of system (verify)
+- Synthetic Full, Diff, Inc (Virtual, Reconstructed)
+- SD to SD
+- Modules for Databases, Exchange, ...
Priority:
- How does restore JobId=nnn work? (Dirk)
if (jr->JobId == 0) {
Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
"PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
-"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId "
+"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId,"
+"SchedTime,RealEndTime "
"FROM Job WHERE Job='%s'", jr->Job);
} else {
Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
"PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
-"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId "
+"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId,"
+"SchedTime,RealEndTime "
"FROM Job WHERE JobId=%s",
edit_int64(jr->JobId, ed1));
}
jr->JobId = str_to_int64(row[16]);
}
jr->FileSetId = str_to_int64(row[17]);
+ bstrncpy(jr->cSchedTime, row[3]!=NULL?row[18]:"", sizeof(jr->cSchedTime));
+ bstrncpy(jr->cRealEndTime, row[3]!=NULL?row[19]:"", sizeof(jr->cRealEndTime));
+ jr->StartTime = str_to_utime(jr->cStartTime);
+ jr->SchedTime = str_to_utime(jr->cSchedTime);
+ jr->EndTime = str_to_utime(jr->cEndTime);
+ jr->RealEndTime = str_to_utime(jr->cRealEndTime);
sql_free_result(mdb);
db_unlock(mdb);
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
- bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
+ bstrncpy(cr.Name, jcr->client->name(), sizeof(cr.Name));
if (!db_get_client_record(jcr, jcr->db, &cr)) {
Jmsg(jcr, M_WARNING, 0, _("Error getting Client record for Job report: ERR=%s"),
db_strerror(jcr->db));
return false;
}
sd = jcr->store_bsock;
- pm_strcpy(device_name, dev->hdr.name);
+ pm_strcpy(device_name, dev->name());
bash_spaces(device_name);
bnet_fsend(sd, query_device, device_name.c_str());
Dmsg1(100, ">stored: %s\n", sd->msg);
/*
* Now send JobId and permissions, and get back the authorization key.
*/
- pm_strcpy(job_name, jcr->job->hdr.name);
+ pm_strcpy(job_name, jcr->job->name());
bash_spaces(job_name);
- pm_strcpy(client_name, jcr->client->hdr.name);
+ pm_strcpy(client_name, jcr->client->name());
bash_spaces(client_name);
- pm_strcpy(fileset_name, jcr->fileset->hdr.name);
+ pm_strcpy(fileset_name, jcr->fileset->name());
bash_spaces(fileset_name);
if (jcr->fileset->MD5[0] == 0) {
bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5));
DEVICE *dev;
/* Loop over alternative storage Devices until one is OK */
foreach_alist(dev, storage->device) {
- pm_strcpy(device_name, dev->hdr.name);
+ pm_strcpy(device_name, dev->name());
bash_spaces(device_name);
bnet_fsend(sd, use_device, device_name.c_str());
Dmsg1(100, ">stored: %s", sd->msg);
DEVICE *dev;
/* Loop over alternative storage Devices until one is OK */
foreach_alist(dev, storage->device) {
- pm_strcpy(device_name, dev->hdr.name);
+ pm_strcpy(device_name, dev->name());
bash_spaces(device_name);
bnet_fsend(sd, use_device, device_name.c_str());
Dmsg1(100, ">stored: %s", sd->msg);
LockRes();
foreach_res(dev, R_DEVICE) {
if (!update_device_res(jcr, dev)) {
- Dmsg1(900, "Error updating device=%s\n", dev->hdr.name);
+ Dmsg1(900, "Error updating device=%s\n", dev->name());
} else {
- Dmsg1(900, "Updated Device=%s\n", dev->hdr.name);
+ Dmsg1(900, "Updated Device=%s\n", dev->name());
}
}
UnlockRes();
int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
bool select_pool_dbr(UAContext *ua, POOL_DBR *pr, char *argk="pool");
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+bool select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
void start_prompt(UAContext *ua, const char *msg);
void add_prompt(UAContext *ua, const char *prompt);
int get_storage_slot(UAContext *ua, STORE *store);
int get_media_type(UAContext *ua, char *MediaType, int max_media);
bool get_pool_dbr(UAContext *ua, POOL_DBR *pr, char *argk="pool");
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+bool get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
POOL *get_pool_resource(UAContext *ua);
POOL *select_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
break;
}
+ Dmsg1(100, "Cmd: %s\n", cmd);
ua->gui = true;
if (ua->api) user->signal(BNET_CMD_BEGIN);
ok = (*commands[i].func)(ua, cmd); /* go execute command */
have_date = true;
break;
case 2: /* before */
- if (!has_value(ua, i)) {
+ if (have_date || !has_value(ua, i)) {
return 0;
}
if (str_to_utime(ua->argv[i]) == 0) {
done = false;
break;
case 4: /* Select the most recent backups */
- bstrutime(date, sizeof(date), now);
+ if (!have_date) {
+ bstrutime(date, sizeof(date), now);
+ }
if (!select_backups_before_date(ua, rx, date)) {
return 0;
}
break;
case 5: /* select backup at specified time */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
+ if (!have_date) {
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
}
if (!select_backups_before_date(ua, rx, date)) {
return 0;
}
break;
case 6: /* Enter files */
- bstrutime(date, sizeof(date), now);
+ if (!have_date) {
+ bstrutime(date, sizeof(date), now);
+ }
if (!get_client_name(ua, rx)) {
return 0;
}
}
return 2;
case 7: /* enter files backed up before specified time */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
+ if (!have_date) {
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
}
if (!get_client_name(ua, rx)) {
return 0;
return 2;
case 8: /* Find JobIds for current backup */
- bstrutime(date, sizeof(date), now);
+ if (!have_date) {
+ bstrutime(date, sizeof(date), now);
+ }
if (!select_backups_before_date(ua, rx, date)) {
return 0;
}
break;
case 9: /* Find JobIds for give date */
- if (!get_date(ua, date, sizeof(date))) {
- return 0;
+ if (!have_date) {
+ if (!get_date(ua, date, sizeof(date))) {
+ return 0;
+ }
}
if (!select_backups_before_date(ua, rx, date)) {
return 0;
if (*rx->JobIds == 0 || *rx->JobIds == '.') {
return 0; /* nothing entered, return */
}
- bstrutime(date, sizeof(date), now);
+ if (!have_date) {
+ bstrutime(date, sizeof(date), now);
+ }
if (!get_client_name(ua, rx)) {
return 0;
}
char pool_select[MAX_NAME_LENGTH];
int i;
-
/* Create temp tables */
db_sql_query(ua->db, uar_del_temp, NULL, NULL);
db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
ua->error_msg("%s\n", db_strerror(ua->db));
goto bail_out;
}
+
/* Note, this is needed because I don't seem to get the callback
* from the call just above.
*/
* returns: 0 on error
* 1 on success and fills in CLIENT_DBR
*/
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr)
+bool get_client_dbr(UAContext *ua, CLIENT_DBR *cr)
{
int i;
* Returns 1 on success
* 0 on failure
*/
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
+bool select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
{
CLIENT_DBR ocr;
char name[MAX_NAME_LENGTH];
}
memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
+ bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
if (!get_pool_dbr(ua, &pr)) {
return false;
}
*/
static bool update_job(UAContext *ua)
{
- bool done = false;
int i;
+ char ed1[50], ed2[50];
+ POOL_MEM cmd(PM_MESSAGE);
+ JOB_DBR jr;
+ CLIENT_DBR cr;
+ utime_t StartTime;
+ char *client_name = NULL;
+ char *start_time = NULL;
const char *kw[] = {
- NT_("StartTime"), /* 0 */
+ NT_("starttime"), /* 0 */
+ NT_("client"), /* 1 */
NULL };
+ Dmsg1(200, "cmd=%s\n", ua->cmd);
+ i = find_arg_with_value(ua, NT_("jobid"));
+ if (i < 0) {
+ ua->error_msg(_("Expect JobId keyword, not found.\n"));
+ return false;
+ }
+ memset(&jr, 0, sizeof(jr));
+ memset(&cr, 0, sizeof(cr));
+ jr.JobId = str_to_int64(ua->argv[i]);
+ if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
+ ua->error_msg("%s", db_strerror(ua->db));
+ return false;
+ }
for (i=0; kw[i]; i++) {
int j;
- if ((j=find_arg_with_value(ua, kw[i])) > 0) {
+ if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
switch (i) {
- case 0:
+ case 0: /* start time */
+ start_time = ua->argv[j];
break;
- case 1:
+ case 1: /* Client name */
+ client_name = ua->argv[j];
break;
}
- done = true;
}
}
+ if (!client_name && !start_time) {
+ ua->error_msg(_("Neither Client nor StartTime specified.\n"));
+ return 0;
+ }
+ if (client_name) {
+ if (!get_client_dbr(ua, &cr)) {
+ return false;
+ }
+ jr.ClientId = cr.ClientId;
+ }
+ if (start_time) {
+ utime_t delta_start;
+ StartTime = str_to_utime(start_time);
+ if (StartTime == 0) {
+ ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
+ return false;
+ }
+ delta_start = StartTime - jr.StartTime;
+ Dmsg3(200, "ST=%d jr.ST=%d delta=%d\n", (time_t)StartTime,
+ (time_t)jr.StartTime, (time_t)delta_start);
+ jr.StartTime = (time_t)StartTime;
+ jr.SchedTime += (time_t)delta_start;
+ jr.EndTime += (time_t)delta_start;
+ jr.JobTDate += delta_start;
+ /* Convert to DB times */
+ bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
+ bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
+ bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
+ }
+ Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
+ "EndTime='%s',JobTDate=%s WHERE JobId=%s",
+ edit_int64(jr.ClientId, ed1),
+ jr.cStartTime,
+ jr.cSchedTime,
+ jr.cEndTime,
+ edit_uint64(jr.JobTDate, ed1),
+ edit_int64(jr.JobId, ed2));
+ if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
+ ua->error_msg("%s", db_strerror(ua->db));
+ return false;
+ }
return true;
}
-/*
- * Bacula floating point time and date routines -- John Walker
- *
- * Later double precision integer time/date routines -- Kern Sibbald
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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 floating point time and date routines -- John Walker
+ *
+ * Later double precision integer time/date routines -- Kern Sibbald
+ *
+ * Version $Id$
+ */
/* Concerning times. There are a number of differnt time standards
"Job %s waiting. Cannot find any appendable volumes.\n"
"Please use the \"label\" command to create a new Volume for:\n"
" Storage: %s\n"
-" Media type: %s\n"
-" Pool: %s\n"),
+" Pool: %s\n"
+" Media type: %s\n"),
jcr->Job,
dev->print_name(),
- dcr->media_type,
- dcr->pool_name);
+ dcr->pool_name,
+ dcr->media_type);
}
}
Jmsg(jcr, M_MOUNT, 0, _("Please mount Volume \"%s\" or label a new one for:\n"
" Job: %s\n"
" Storage: %s\n"
- " Media type: %s\n"
- " Pool: %s\n"),
+ " Pool: %s\n"
+ " Media type: %s\n"),
dcr->VolumeName,
jcr->Job,
dev->print_name(),
- dcr->media_type,
- dcr->pool_name);
+ dcr->pool_name,
+ dcr->media_type);
Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n",
dcr->VolumeName, dev->print_name(), jcr->Job);
}
exit(1);
}
in_here = true;
+ stop_watchdog();
if (sig == SIGTERM) { /* normal shutdown request? */
/*
}
term_reservations_lock();
term_msg();
- stop_watchdog();
cleanup_crypto();
free_volume_list();
close_memory_pool();
General:
13May07
+kes Fix restore before command.
+kes Convert old hdr.name to name() in a few places.
+kes Implement update jobid command.
+kes Return all time_t dates in db_get_job_record()
+kes Stop watchdog in SD earlier.
+kes Put Pool just after Storage in please mount message.
kes Fix pointer usage bugs in Verify InitCatalog pointed out by
Eric.
12May07