From 86f12efb612e538558a4e56eea4353bd2885c0a7 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 7 Oct 2002 16:45:49 +0000 Subject: [PATCH] Minor bscan fixes + documentation git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@167 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 79 +++--------------------------- bacula/src/cats/sql_get.c | 5 +- bacula/src/stored/bscan.c | 100 +++++++++++++++++++++++++------------- 3 files changed, 75 insertions(+), 109 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 99774626bf..602bb7201a 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 6 October 2002 + 7 October 2002 Irix conversion notes: - no uuencode @@ -83,10 +83,12 @@ From Chuck: Projects: - Bacula Projects Roadmap + Bacula Projects Roadmap 17 August 2002 + last update 7 October 2002 Item 1: Multiple simultaneous Jobs. (done) +Done What: Permit multiple simultaneous jobs in Bacula. @@ -106,7 +108,7 @@ Item 1: Multiple simultaneous Jobs. (done) Item 2: Make the Storage daemon use intermediate file storage to buffer data. - (not necessary) +Deferred -- not necessary yet. What: If data is coming into the SD too fast, buffer it to disk if the user has configured this option. @@ -125,6 +127,7 @@ Item 2: Make the Storage daemon use intermediate file storage to buffer data. Item 3: Write the bscan program. +Done What: Write a program that reads a Bacula tape and puts all the appropriate data into the catalog. This allows recovery @@ -175,6 +178,7 @@ Item 5: Implement Label templates Item 6: Write a regression script. +Started What: This is an automatic script that runs and tests as many features of Bacula as possible. The output is compared to previous @@ -229,6 +233,7 @@ Item 9: Add SSL to daemon communications. Item 10: Define definitive tape format. +Mostly done (version 1.27) What: Define that definitive tape format that will not change for the next millennium. @@ -271,17 +276,11 @@ Small projects: - Restore options (overwrite, overwrite if older, overwrite if newer, never overwrite, ...) - Restore to a particular time -- e.g. before date, after date. -- On command write out a bootstrap file (at end of job). - Make all database Ids 64 bit. -- Pass JCR to database routines permitting better error printing. -- Make bls accept bootstrap record. - Write an applet for Linux. - Make SD reject writing on tape where Catalog and tape # files don't agree (possibly OK if tape > catalog). - Implement new daemon communications protocol. -- Add DIR config directive to spool attributes. -- Pass DIR config variable to SD for no attributes. -- Create JobMedia record for all running Jobs when Media changes. - Send Volumes needed during restore to Console (just after create_volume_list) -- also in restore command? - Add estimate to Console commands @@ -555,65 +554,3 @@ Longer term to do: Done: (see kernsdone for more) ---the console script is broken as installed and has to be hand-massaged with - paths, config files etc. -- Termination status in FD for Verify = C -- incorrect. -- Implement alter_sqlite_tables -- Fix scheduler -- see "Hourly cycle". It doesn't do both each - hour, rather it alternates between 0:05 and 0:35. -- Create Counter DB records. -- Fix db_get_job_volume_names() to return array of strings (now works - with pool memory. -- Eliminate MySQL shared libraries from smtp and daemons not using MySQL. -- Compare tape File attributes to Catalog. - (File attributes are size, dates, MD5, but not - data). -- Report bad status from smtp or mail program. -- Ensure that Start/End File/Block are correct. -- If MySQL database is not running, job terminates with - wierd type and wierd error code. -- Probably create a jcr with JobId=0 as a master - catchall if jcr not found or if operation involves - global operation. -- The daemons should know when one is already - running and refuse to run a second copy. -- Figure out how to do a "full" restore from catalog -- Make SD send attribute stream to DR but first - buffering to file, then sending only when the - files are written to tape. -- Restore file xx or files xx, yy to their most recent values. -- Get correct block/file information in Catalog, pay attention to change of media. -- Write better dump of Messages resource. -- Authentication between SD and FD -- In restore job, print some summary information at end, such - as rate, ... job status, ... -- Problem with len at 362 in tree.c -- Report volume write rate. -- Pass "Catalog Files = no" to storage daemon to eliminate network traffic. -- When we are at EOM, we must ask each job to write JobMedia - record (update_volume_info). -- Create all pools when Director starts -- Correct Warning: Volume name mismatch. Wanted test2 got test1 - when reading a tape and want the next one. -- Implement autochanger for restore. ARRRGGG! I forgot! -- sd.conf password does not match dir.conf storage password -- Apparently Description records are not freed. Storage daemon - Device reported orphaned buffer 45 bytes probably for a Description. -- Take another stab at 64 bit file addresses -- Had to label second tape using the autochanger two times. The - first time the second tape was apparently loaded but not labeled. - 3903 Failed to label Volume: ERR=dev.c:285 Bad call to rewind_dev. Device /dev/nst0 not open -- Attempt to label autochanger tape which is unloaded. - rufus-dir: Start Backup JobId 1, Job=kernsave.2002-09-21.21:07:34 - rufus-sd: Job kernsave.2002-09-21.21:07:34 waiting. Cannot find any appendable volumes. - Please use the "label" command to create a new Volume for: - Storage: FileStorage - Media type: File - Pool: Default - rufus-dir: Error in getmsg.c:129 Job not found: Jmsg Job= type=6 level=0 rufus-sd: Issuing autochanger "load slot 2" command. - - Another try with tape mounted and Job hung in Director. -- Write updated bootstrap after every Job. -- Document driver testing with btape. -- Document autochanger. - diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 66e63aea3a..eb021b4000 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -548,13 +548,12 @@ int db_get_fileset_record(B_DB *mdb, FILESET_DBR *fsr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { char ed1[30]; - Mmsg1(&mdb->errmsg, _("Got %s FileSets expected only one!\n"), + Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"), edit_uint64(mdb->num_rows, ed1)); sql_data_seek(mdb, mdb->num_rows-1); } if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("Error fetching row get_fileset: %s\n"), sql_strerror(mdb)); - Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); + Mmsg1(&mdb->errmsg, _("Error: FileSet record \"%s\" not found\n"), fsr->FileSet); } else { fsr->FileSetId = atoi(row[0]); strcpy(fsr->FileSet, row[1]); diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 678718ae74..7f674276cd 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -74,6 +74,8 @@ static FILE_DBR fr; static SESSION_LABEL label; static SESSION_LABEL elabel; +static time_t lasttime = 0; + static char *db_name = "bacula"; static char *db_user = "bacula"; static char *db_password = ""; @@ -232,7 +234,6 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, rec->data_len); } -Dmsg1(000, "record_cb block=%u\n", rec->Block); /* * Check for Start or End of Session Record * @@ -258,8 +259,10 @@ Dmsg1(000, "record_cb block=%u\n", rec->Block); Pmsg1(000, "Pool record for %s found in DB.\n", pr.Name); } } else { - Pmsg1(000, "VOL_LABEL: Pool record not found for Pool: %s\n", - pr.Name); + if (!update_db) { + Pmsg1(000, "VOL_LABEL: Pool record not found for Pool: %s\n", + pr.Name); + } create_pool_record(db, &pr); } if (strcmp(pr.PoolType, dev->VolHdr.PoolType) != 0) { @@ -282,8 +285,10 @@ Dmsg1(000, "record_cb block=%u\n", rec->Block); mr.VolJobs = mr.VolFiles = mr.VolBlocks = 0; mr.VolBytes = rec->data_len + 20; } else { - Pmsg1(000, "VOL_LABEL: Media record not found for Volume: %s\n", - mr.VolumeName); + if (!update_db) { + Pmsg1(000, "VOL_LABEL: Media record not found for Volume: %s\n", + mr.VolumeName); + } strcpy(mr.MediaType, dev->VolHdr.MediaType); create_media_record(db, &mr, &dev->VolHdr); } @@ -317,8 +322,10 @@ Dmsg1(000, "record_cb block=%u\n", rec->Block); } } else { /* Must create a Job record in DB */ - Pmsg1(000, "SOS_LABEL: Job record not found for JobId: %d\n", - jr.JobId); + if (!update_db) { + Pmsg1(000, "SOS_LABEL: Job record not found for JobId: %d\n", + jr.JobId); + } } /* Create Client record if not already there */ strcpy(cr.Name, label.ClientName); @@ -602,14 +609,20 @@ static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl) strcpy(mr->VolStatus, "Full"); mr->VolRetention = 355 * 3600 * 24; /* 1 year */ - dt.julian_day_number = vl->write_date; - dt.julian_day_fraction = vl->write_time; - tm_decode(&dt, &tm); - mr->FirstWritten = mktime(&tm); - dt.julian_day_number = vl->label_date; - dt.julian_day_fraction = vl->label_time; - tm_decode(&dt, &tm); - mr->LabelDate = mktime(&tm); + if (vl->VerNum >= 11) { + mr->FirstWritten = (time_t)vl->write_btime; + mr->LabelDate = (time_t)vl->label_btime; + } else { + dt.julian_day_number = vl->write_date; + dt.julian_day_fraction = vl->write_time; + tm_decode(&dt, &tm); + mr->FirstWritten = mktime(&tm); + dt.julian_day_number = vl->label_date; + dt.julian_day_fraction = vl->label_time; + tm_decode(&dt, &tm); + mr->LabelDate = mktime(&tm); + } + lasttime = mr->LabelDate; if (!update_db) { return 1; @@ -639,6 +652,7 @@ static int update_media_record(B_DB *db, MEDIA_DBR *mr) return 1; } + mr->LastWritten = lasttime; if (!db_update_media_record(db, mr)) { Pmsg1(0, _("Could not update media record. ERR=%s\n"), db_strerror(db)); return 0; @@ -696,16 +710,19 @@ static int create_fileset_record(B_DB *db, FILESET_DBR *fsr) return 1; } fsr->FileSetId = 0; + fsr->MD5[0] = ' '; /* ***FIXME*** */ + fsr->MD5[1] = 0; if (db_get_fileset_record(db, fsr)) { if (verbose) { Pmsg1(000, _("Fileset \"%s\" already exists.\n"), fsr->FileSet); } } else { - if (!db_create_fileset_record(db, fsr)) { - Pmsg1(0, _("Could not create FileSet record. ERR=%s\n"), db_strerror(db)); - return 0; - } - if (verbose) { + if (!db_create_fileset_record(db, fsr)) { + Pmsg2(0, _("Could not create FileSet record \"%s\". ERR=%s\n"), + fsr->FileSet, db_strerror(db)); + return 0; + } + if (verbose) { Pmsg1(000, _("Created FileSet record \"%s\"\n"), fsr->FileSet); } } @@ -730,10 +747,15 @@ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label, jr->JobStatus = JS_Created; strcpy(jr->Name, label->JobName); strcpy(jr->Job, label->Job); - dt.julian_day_number = label->write_date; - dt.julian_day_fraction = label->write_time; - tm_decode(&dt, &tm); - jr->SchedTime = mktime(&tm); + if (label->VerNum >= 11) { + jr->SchedTime = (time_t)label->write_btime; + } else { + dt.julian_day_number = label->write_date; + dt.julian_day_fraction = label->write_time; + tm_decode(&dt, &tm); + jr->SchedTime = mktime(&tm); + } + jr->StartTime = jr->SchedTime; jr->JobTDate = (btime_t)jr->SchedTime; jr->VolSessionId = rec->VolSessionId; @@ -748,7 +770,7 @@ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label, /* This creates the bare essentials */ if (!db_create_job_record(db, jr)) { - Pmsg1(0, _("Could not create job record. ERR=%s\n"), db_strerror(db)); + Pmsg1(0, _("Could not create JobId record. ERR=%s\n"), db_strerror(db)); return mjcr; } @@ -758,8 +780,10 @@ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label, return mjcr; } if (verbose) { - Pmsg1(000, _("Created Job record for JobId: %d\n"), jr->JobId); + Pmsg2(000, _("Created new JobId=%u record for original JobId=%u\n"), jr->JobId, + label->JobId); } + mjcr->JobId = jr->JobId; /* set new JobId */ return mjcr; } @@ -780,14 +804,20 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, rec->VolSessionId, rec->VolSessionTime); return 0; } - dt.julian_day_number = elabel->write_date; - dt.julian_day_fraction = elabel->write_time; - tm_decode(&dt, &tm); - jr->JobId = mjcr->JobId; - jr->JobStatus = JS_Terminated; /* ***FIXME*** need to add to EOS label */ - mjcr->JobStatus = JS_Terminated; - jr->EndTime = mktime(&tm); + if (elabel->VerNum >= 11) { + jr->EndTime = (time_t)elabel->write_btime; + } else { + dt.julian_day_number = elabel->write_date; + dt.julian_day_fraction = elabel->write_time; + tm_decode(&dt, &tm); + jr->EndTime = mktime(&tm); + } + lasttime = jr->EndTime; mjcr->end_time = jr->EndTime; + + jr->JobId = mjcr->JobId; + jr->JobStatus = elabel->JobStatus; + mjcr->JobStatus = elabel->JobStatus; jr->JobFiles = elabel->JobFiles; jr->JobBytes = elabel->JobBytes; jr->VolSessionId = rec->VolSessionId; @@ -801,12 +831,12 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, } if (!db_update_job_end_record(db, jr)) { - Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db)); + Pmsg2(0, _("Could not update JobId=%u record. ERR=%s\n"), jr->JobId, db_strerror(db)); free_jcr(mjcr); return 0; } if (verbose) { - Pmsg1(000, _("Updated Job termination record for JobId: %u\n"), jr->JobId); + Pmsg1(000, _("Updated Job termination record for new JobId=%u\n"), jr->JobId); } if (verbose > 1) { char *term_msg; -- 2.39.5