From: Kern Sibbald Date: Sun, 13 May 2007 16:11:13 +0000 (+0000) Subject: kes Fix restore before command. X-Git-Tag: Release-7.0.0~6360 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5fbd8982ddd21941c4be36222f71747d1b36488d;p=bacula%2Fbacula 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. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4771 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index d95512c804..1423e0c4bc 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -46,6 +46,9 @@ Professional Needs: - 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) diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index ee4c826812..f3dc9c7556 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -274,12 +274,14 @@ bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) 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)); } @@ -315,6 +317,12 @@ bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) 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); diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 5856a241ee..8e4335287f 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -357,7 +357,7 @@ void backup_cleanup(JCR *jcr, int TermCode) 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)); diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index cfacd1fbf5..0a29de1e0e 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -132,7 +132,7 @@ bool update_device_res(JCR *jcr, DEVICE *dev) 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); @@ -163,11 +163,11 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore) /* * 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)); @@ -238,7 +238,7 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore) 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); @@ -273,7 +273,7 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore) 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); @@ -443,9 +443,9 @@ extern "C" void *device_thread(void *arg) 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(); diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 71c4dd095b..586d376788 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -230,7 +230,7 @@ FILESET *select_fileset_resource(UAContext *ua); 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); @@ -241,7 +241,7 @@ int get_storage_drive(UAContext *ua, STORE *store); 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); diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 8d41289b8a..cbed06a1d0 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -125,6 +125,7 @@ int do_a_dot_command(UAContext *ua, const char *cmd) !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 */ diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 9915136b65..0aed6da0dc 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -480,7 +480,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) 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) { @@ -610,21 +610,27 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) 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; } @@ -643,8 +649,10 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) } 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; @@ -665,7 +673,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) 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; } @@ -673,8 +683,10 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) 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; @@ -695,7 +707,9 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) 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; } @@ -1106,7 +1120,6 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat 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); @@ -1187,6 +1200,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat 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. */ diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 6fa39efdf0..060bdd66ea 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -352,7 +352,7 @@ CLIENT *get_client_resource(UAContext *ua) * 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; @@ -389,7 +389,7 @@ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr) * 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]; diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index 4339735ab6..eaf10bc7d5 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -743,7 +743,7 @@ static bool update_pool(UAContext *ua) } 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; } @@ -771,25 +771,87 @@ static bool update_pool(UAContext *ua) */ 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; } diff --git a/bacula/src/lib/btime.c b/bacula/src/lib/btime.c index 0f730cf3bf..fbaacafdce 100644 --- a/bacula/src/lib/btime.c +++ b/bacula/src/lib/btime.c @@ -1,14 +1,7 @@ -/* - * 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. @@ -32,6 +25,13 @@ (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 diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 8a60555b36..b93b933716 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -487,12 +487,12 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) "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); } } @@ -574,13 +574,13 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) 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); } diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index e027ffd89d..04dc82620c 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -537,6 +537,7 @@ void terminate_stored(int sig) exit(1); } in_here = true; + stop_watchdog(); if (sig == SIGTERM) { /* normal shutdown request? */ /* @@ -601,7 +602,6 @@ void terminate_stored(int sig) } term_reservations_lock(); term_msg(); - stop_watchdog(); cleanup_crypto(); free_volume_list(); close_memory_pool(); diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 2a924a9670..edaa2e404f 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -2,6 +2,12 @@ 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