]> git.sur5r.net Git - bacula/bacula/commitdiff
Commit final code for 1.32b + Verify Job (name) + change Pool for a Volume
authorKern Sibbald <kern@sibbald.com>
Fri, 17 Oct 2003 08:07:07 +0000 (08:07 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 17 Oct 2003 08:07:07 +0000 (08:07 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@750 91ce42f0-d328-0410-95d8-f526ca767f89

23 files changed:
bacula/ChangeLog
bacula/ReleaseNotes
bacula/autoconf/acconfig.h
bacula/autoconf/aclocal.m4
bacula/autoconf/config.h.in
bacula/configure
bacula/kernstodo
bacula/src/cats/mysql.c
bacula/src/cats/protos.h
bacula/src/cats/sql_find.c
bacula/src/cats/sql_get.c
bacula/src/dird/authenticate.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_run.c
bacula/src/dird/ua_tree.c
bacula/src/dird/verify.c
bacula/src/filed/job.c
bacula/src/filed/verify.c
bacula/src/jcr.h
bacula/src/stored/bscan.c
bacula/src/version.h

index a3d34622784bc0467518c71a90d5c91866bc69d8..c06d96429aa5278af715a05f92dbb479e60a8e41 100644 (file)
@@ -1,5 +1,18 @@
 
-2003-10-10 Version 1.32b 10Oct03 Release
+2003-10-15 Version 1.32b 14Oct03 Release
+14Oct03
+- Modify configure so that if threaded MySQL client library
+  is not present, Bacula will link with the non-threaded 
+  version.
+- Updates to the Web pages and to the manual.
+- Remove trademark symbol from title. Phil pointed out that it
+  does not display correctly in a title.
+11Oct03
+- Implement restore by file before date. 
+- Change restore arguments a bit so that you can feed it
+  multiple jobid= specifications or multiple file= specifications.
+- Pass restore with run option on to run_cmd.
+- Make run-cmd not prompt if it has a "run" on the command line.
 10Oct03
 - When pruning, select only old orphanned jobs to delete so that
   the current job is not pruned too.
index 3220ac2652b2423540ff2716302a8b98461dc3e8..4831d591b5c6338fa12843cbfae7d2c2e98d7110 100644 (file)
@@ -1,14 +1,18 @@
 
           Release Notes for Bacula 1.32b
 
-  Bacula code: Total files = 259 Total lines = 77,984 (*.h *.c *.in)
+  Bacula code: Total files = 259 Total lines = 78,067 (*.h *.c *.in)
 
-Changes since 1.32a:
+Most Significant Changes since 1.32a:
 - Improve forward space file/block during restore, many
   optimizations.
 - Fix a bug that did not allow appending to a tape    
   on FreeBSD systems.
 - Fix pruning so that it will not prune the current job.
+- Modify configure to use non-threaded MySQL client lib if
+  the threaded version is not present.
+- Implement restore by file before date.
+- When pruning don't prune the current job.
 
 Major Changes 1.32a Release:
 - Implemented forward space file/block whenever possible 
index a6fe066c74eee2c788cc0f4c3769333869a116f6..e9cef42055dd2798dbf4493faded6c55962d72db 100644 (file)
@@ -23,6 +23,9 @@
 /* Define if you want to use MySQL */
 #undef HAVE_MYSQL
 
+/* Defined if MySQL thread safe library is present */
+#undef HAVE_THREAD_SAFE_MYSQL
+
 /* Define if you want to use embedded MySQL */
 #undef HAVE_EMBEDDED_MYSQL
 
 #undef HAVE_OLD_SOCKOPT
  
 #undef HAVE_BIGENDIAN
-
index 8f0aab87b2002f13c8cdc3382119cfe188028045..b5f4b4d889a971b454466810664d77744daf0106 100644 (file)
@@ -390,7 +390,12 @@ Which DBMS do you want to use (please select only one):
                 fi
         fi
     SQL_INCLUDE=-I$MYSQL_INCDIR
-    SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz"
+    if test -f $MYSQL_LIBDIR/libmysqlclient_r.a; then
+       SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz"
+       AC_DEFINE(HAVE_THREAD_SAFE_MYSQL)
+    else
+       SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient -lz"
+    fi
     SQL_BINDIR=$MYSQL_BINDIR
 
     AC_DEFINE(HAVE_MYSQL)
index 13c47a86365786bc9887511b6ad3ab516d1d3af7..db3f80dc3cca8d4d9711d3f9f8f1fc039dfb36a5 100644 (file)
@@ -24,6 +24,9 @@
 /* Define if you want to use MySQL */
 #undef HAVE_MYSQL
 
+/* Defined if MySQL thread safe library is present */
+#undef HAVE_THREAD_SAFE_MYSQL
+
 /* Define if you want to use embedded MySQL */
 #undef HAVE_EMBEDDED_MYSQL
 
  
 #undef HAVE_BIGENDIAN
 
-
 /* Define to 1 if the `closedir' function returns void instead of `int'. */
 #undef CLOSEDIR_VOID
 
index ee3fafe7e5b7ea7d0a3d6a5b88c5c7dbc0dab5ad..56b9244a7f42aeb701e51e4a4427127a526918ee 100755 (executable)
@@ -6734,7 +6734,15 @@ echo "$as_me: error: Invalid MySQL directory $withval - unable to find mysql.h u
                 fi
         fi
     SQL_INCLUDE=-I$MYSQL_INCDIR
-    SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz"
+    if test -f $MYSQL_LIBDIR/libmysqlclient_r.a; then
+       SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz"
+       cat >>confdefs.h <<\_ACEOF
+#define HAVE_THREAD_SAFE_MYSQL 1
+_ACEOF
+
+    else
+       SQL_LFLAGS="-L$MYSQL_LIBDIR -lmysqlclient -lz"
+    fi
     SQL_BINDIR=$MYSQL_BINDIR
 
     cat >>confdefs.h <<\_ACEOF
index 582aa56831acb5a0693463a96e9d759411a5c3be..0095e2ba2d6bfbe4139bde3ce4e8592d27c8eb8b 100644 (file)
@@ -36,13 +36,19 @@ For 1.33 Testing/Documentation:
   SuSE.
                 
 For 1.33
+- Add VerifyJob to "run" summary (yes/mod/no) prompt.
+- Add device name to "Current Volume not acceptable because ..."
+- Make sure that Bacula rechecks the tape after the 20 min wait.
+- Set IO_NOWAIT on Bacula packets
+- Try doing a raw partition backup and restore by mounting a
+  Windows partition.
+- Implement Verify=DiskToCatalog
+- Implement a RunAfterFailedJob
 - Report CVS problems to SourceForge.
 - Implement .consolerc for Console
-- I want to restore by file to some date.
 - Is it really important to make Job name the same to find the
   Full backup to avoid promoting an Incremental job?
 - Start label, then run job when tape labeled, it should broadcast.
-- Implement a RunAfterFailedJob
 - Zap illegal characters in job name for mail files (e.g. /).
 - From Lars Köllers:
     Yes, it would allow to highly automatic the request for new tapes. If a 
@@ -107,7 +113,6 @@ For 1.33
 - Make sure a rescheduled job is properly reported by status.
 - Walk through the Pool records rather than the Job records
   in dird.c to create/update pools.
-- Figure out a way to move Volumes from one pool to another.
 - What to do about "list files job=xxx".
 - Implement delete Job.
 - Document need to put LabelFormat in quotes.
@@ -1044,3 +1049,6 @@ Done: (see kernsdone for more)
 - Test connect timeouts.
 - Fix FreeBSD build with tcp_wrapper -- should not have -lnsl
 - Implement fast block rejection.
+- I want to restore by file to some date.
+---- 1.32b released
+- Figure out a way to move Volumes from one pool to another.
index 3b474819b01bbaa64d42cea38fb1b209c09855d1..719aab5cd8db50da25287b4ff8fc3d15c673d2ac 100644 (file)
@@ -176,7 +176,9 @@ It is probably not running or your password is incorrect.\n"),
       return 0;
    }
 
+#ifdef HAVE_TREAD_SAFE_MYSQL
    my_thread_init();
+#endif
 
    mdb->connected = TRUE;
    V(mutex);
@@ -188,7 +190,9 @@ db_close_database(JCR *jcr, B_DB *mdb)
 {
    P(mutex);
    mdb->ref_count--;
+#ifdef HAVE_TREAD_SAFE_MYSQL
    my_thread_end();
+#endif
    if (mdb->ref_count == 0) {
       qdchain(&mdb->bq);
       if (mdb->connected && mdb->db) {
index 6ce3efee0c588981be381fd0f4ca8390277e5466..ab233e474a7f4f8556af7ba2f65c71374635a086 100644 (file)
@@ -61,7 +61,7 @@ int db_delete_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
 
 /* find.c */
 int db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime);
-int db_find_last_jobid(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
+int db_find_last_jobid(JCR *jcr, B_DB *mdb, char *Name, JOB_DBR *jr);
 int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, MEDIA_DBR *mr);
 
 /* get.c */
@@ -69,7 +69,7 @@ int db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames);
-int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, FILE_DBR *fdbr);
+int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr);
 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr);
 int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
 int db_get_num_media_records(JCR *jcr, B_DB *mdb);
index c0379235f8473ebeeda85bb2391deaada203f49a..e29ea401105ba6edbbfc0ba07777bc3573af0c1b 100644 (file)
@@ -144,7 +144,7 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
  *         0 on failure
  */
 int
-db_find_last_jobid(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
+db_find_last_jobid(JCR *jcr, B_DB *mdb, char *Name, JOB_DBR *jr)
 {
    SQL_ROW row;
 
@@ -156,10 +156,15 @@ db_find_last_jobid(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 "ClientId=%u ORDER BY StartTime DESC LIMIT 1",
           L_VERIFY_INIT, jr->Name, jr->ClientId);
    } else if (jr->Level == L_VERIFY_VOLUME_TO_CATALOG) {
-      Mmsg(&mdb->cmd, 
+      if (Name) {
+        Mmsg(&mdb->cmd,
+"SELECT JobId FROM Job WHERE Type='B' AND JobStatus='T' AND "
+"Name='%s' ORDER BY StartTime DESC LIMIT 1", Name);
+      } else {
+        Mmsg(&mdb->cmd, 
 "SELECT JobId FROM Job WHERE Type='B' AND "
-"ClientId=%u ORDER BY StartTime DESC LIMIT 1", 
-          jr->ClientId);
+"ClientId=%u ORDER BY StartTime DESC LIMIT 1", jr->ClientId);
+      }
    } else {
       Mmsg1(&mdb->errmsg, _("Unknown Job level=%c\n"), jr->Level);
       db_unlock(mdb);
index 7ff3a44fe6bc409b9a0995c257e3a4f60e77ea2d..43d9a3a1182c3f1e9a69b2dd52c42669e85f7014 100644 (file)
@@ -48,7 +48,7 @@
  */
 
 /* Forward referenced functions */
-static int db_get_file_record(JCR *jcr, B_DB *mdb, FILE_DBR *fdbr);
+static int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr);
 static int db_get_filename_record(JCR *jcr, B_DB *mdb);
 static int db_get_path_record(JCR *jcr, B_DB *mdb);
 
@@ -67,7 +67,7 @@ extern void split_path_and_filename(JCR *jcr, B_DB *mdb, char *fname);
  *  Returns: 0 on failure
  *          1 on success with the File record in FILE_DBR
  */
-int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, FILE_DBR *fdbr)
+int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
 {
    int stat;
    Dmsg1(20, "Enter get_file_from_catalog fname=%s \n", fname);
@@ -79,7 +79,7 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, FILE_DBR *fd
 
    fdbr->PathId = db_get_path_record(jcr, mdb);
 
-   stat = db_get_file_record(jcr, mdb, fdbr);
+   stat = db_get_file_record(jcr, mdb, jr, fdbr);
 
    db_unlock(mdb);
 
@@ -99,15 +99,23 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, FILE_DBR *fd
  *    "normal" if a new file is found during Verify.
  */
 static
-int db_get_file_record(JCR *jcr, B_DB *mdb, FILE_DBR *fdbr)
+int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
 {
    SQL_ROW row;
    int stat = 0;
 
-   Mmsg(&mdb->cmd, 
-"SELECT FileId, LStat, MD5 from File where File.JobId=%u and File.PathId=%u and \
-File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
-
+   if (jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG) {
+      Mmsg(&mdb->cmd, 
+"SELECT FileId, LStat, MD5 FROM File,Job WHERE "
+"File.JobId=Job.JobId AND File.PathId=%u AND "
+"File.FilenameId=%u AND Job.Type='B' AND Job.JobSTATUS='T' AND "
+"ClientId=%u ORDER BY StartTime DESC LIMIT 1",
+      fdbr->PathId, fdbr->FilenameId, jr->ClientId);
+   } else {
+      Mmsg(&mdb->cmd, 
+"SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%u AND File.PathId=%u AND "
+"File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
+   }
    Dmsg3(050, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n",
       fdbr->JobId, fdbr->FilenameId, fdbr->PathId);
       
index b41ca667c683600eb13a84e54c28d5675eece5be..9ec6d81bf1b3e12a2ac4b6af2cd6f91335bddcb9 100644 (file)
@@ -69,7 +69,7 @@ int authenticate_storage_daemon(JCR *jcr)
    }
    if (!cram_md5_get_auth(sd, jcr->store->password, ssl_need) || 
        !cram_md5_auth(sd, jcr->store->password, ssl_need)) {
-      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords not the same.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n"));
       return 0;
    }
    Dmsg1(116, ">stored: %s", sd->msg);
@@ -106,7 +106,7 @@ int authenticate_file_daemon(JCR *jcr)
    }
    if (!cram_md5_get_auth(fd, jcr->client->password, ssl_need) || 
        !cram_md5_auth(fd, jcr->client->password, ssl_need)) {
-      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords not the same.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n"));
       return 0;
    }
    Dmsg1(116, ">filed: %s", fd->msg);
index 47c9f98581eafa706c18c68aeb837bfea747fa4c..a5b3ae2646e63cc6f86a2773c1df1705a229636d 100644 (file)
@@ -203,6 +203,7 @@ static struct res_items job_items[] = {
    {"pool",     store_res,     ITEM(res_job.pool),     R_POOL, 0, 0},
    {"client",   store_res,     ITEM(res_job.client),   R_CLIENT, 0, 0},
    {"fileset",  store_res,     ITEM(res_job.fileset),  R_FILESET, 0, 0},
+   {"verifyjob",  store_res,   ITEM(res_job.verify_job), R_JOB, 0, 0},
    {"where",    store_dir,     ITEM(res_job.RestoreWhere), 0, 0, 0},
    {"replace",  store_replace, ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS},
    {"bootstrap",store_dir,     ITEM(res_job.RestoreBootstrap), 0, 0, 0},
@@ -345,6 +346,7 @@ struct s_jl joblevels[] = {
    {"Catalog",       L_VERIFY_CATALOG,  JT_VERIFY},
    {"InitCatalog",   L_VERIFY_INIT,     JT_VERIFY},
    {"VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG,   JT_VERIFY},
+   {"DiskToCatalog", L_VERIFY_DISK_TO_CATALOG,   JT_VERIFY},
    {"Data",          L_VERIFY_DATA,     JT_VERIFY},
    {NULL,           0}
 };
@@ -410,7 +412,7 @@ char *level_to_str(int level)
 void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...), void *sock)
 {
    URES *res = (URES *)reshdr;
-   int recurse = 1;
+   bool recurse = true;
    char ed1[100], ed2[100];
 
    if (res == NULL) {
@@ -419,7 +421,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
    }
    if (type < 0) {                   /* no recursion */
       type = - type;
-      recurse = 0;
+      recurse = false;
    }
    switch (type) {
    case R_DIRECTOR:
@@ -527,6 +529,11 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       } else {
          sendit(sock, "!!! No Pool resource\n");
       }
+      if (res->res_job.verify_job) {
+         sendit(sock, "  --> ");
+        dump_resource(-R_JOB, (RES *)res->res_job.verify_job, sendit, sock);
+      }
+      break;
       if (res->res_job.messages) {
          sendit(sock, "  --> ");
         dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
@@ -919,12 +926,13 @@ void save_resource(int type, struct res_items *items, int pass)
         if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", res_all.res_dir.hdr.name);
         }
-        res->res_job.messages = res_all.res_job.messages;
-        res->res_job.schedule = res_all.res_job.schedule;
-        res->res_job.client   = res_all.res_job.client;
-        res->res_job.fileset  = res_all.res_job.fileset;
-        res->res_job.storage  = res_all.res_job.storage;
-        res->res_job.pool     = res_all.res_job.pool;
+        res->res_job.messages   = res_all.res_job.messages;
+        res->res_job.schedule   = res_all.res_job.schedule;
+        res->res_job.client     = res_all.res_job.client;
+        res->res_job.fileset    = res_all.res_job.fileset;
+        res->res_job.storage    = res_all.res_job.storage;
+        res->res_job.pool       = res_all.res_job.pool;
+        res->res_job.verify_job = res_all.res_job.verify_job;
         if (res->res_job.JobType == 0) {
             Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name);
         }
index 5c4aad6b66570ad8d41efdc3c7fd71fbccffdf5c..bf3ee962714593cc510cfa0c5baf06db4d8f5700 100644 (file)
@@ -207,6 +207,7 @@ struct JOB {
    FILESET   *fileset;                /* What to backup -- Fileset */
    STORE     *storage;                /* Where is device -- Storage daemon */
    POOL      *pool;                   /* Where is media -- Media Pool */
+   JOB       *verify_job;             /* Job name to verify */
    uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
 };
 
index c455d086b4c2069b68ab4a33b8b7d3b55ecb6226..48e1d49a82b1097916b07e82e8eacdfde87d3c32 100644 (file)
@@ -799,6 +799,26 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
    free_pool_memory(query);
 }
 
+/* Modify the Pool in which this Volume is located */
+static void update_volpool(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+   POOL_DBR pr;
+   POOLMEM *query;
+   memset(&pr, 0, sizeof(pr));
+   bstrncpy(pr.Name, val, sizeof(pr.Name));
+   if (!get_pool_dbr(ua, &pr)) {
+      return;
+   }
+   query = get_pool_memory(PM_MESSAGE);
+   Mmsg(&query, "UPDATE Media SET PoolId=%u WHERE MediaId=%u", pr.PoolId, mr->MediaId);
+   if (!db_sql_query(ua->db, query, NULL, NULL)) {  
+      bsendmsg(ua, "%s", db_strerror(ua->db));
+   } else {      
+      bsendmsg(ua, _("New Pool is: %s\n"), pr.Name);
+   }
+   free_pool_memory(query);
+}
+
 /*
  * Update a media record -- allows you to change the
  *  Volume status. E.g. if you want Bacula to stop
@@ -808,6 +828,7 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
 static int update_volume(UAContext *ua)
 {
    MEDIA_DBR mr;
+   POOL_DBR pr;
    POOLMEM *query;
    char ed1[30];
    bool done = false;
@@ -819,6 +840,7 @@ static int update_volume(UAContext *ua)
       N_("MaxVolFiles"),              /* 4 */
       N_("MaxVolBytes"),              /* 5 */
       N_("Recycle"),                  /* 6 */
+      N_("Pool"),                     /* 7 */
       NULL };
 
    for (int i=0; kw[i]; i++) {
@@ -849,6 +871,8 @@ static int update_volume(UAContext *ua)
         case 6:
            update_volrecycle(ua, ua->argv[j], &mr);
            break;
+        case 7:
+           update_volpool(ua, ua->argv[j], &mr);
         }
         done = true;
       }
@@ -869,6 +893,7 @@ static int update_volume(UAContext *ua)
       add_prompt(ua, _("Recycle Flag"));
       add_prompt(ua, _("Slot"));
       add_prompt(ua, _("Volume Files"));
+      add_prompt(ua, _("Pool"));
       add_prompt(ua, _("Done"));
       switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
       case 0:                        /* Volume Status */
@@ -944,7 +969,6 @@ static int update_volume(UAContext *ua)
 
       case 7:                        /* Slot */
         int slot;
-        POOL_DBR pr;
 
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
@@ -999,6 +1023,19 @@ static int update_volume(UAContext *ua)
         free_pool_memory(query);
         break;
 
+      case 9:                         /* Volume's Pool */
+        memset(&pr, 0, sizeof(POOL_DBR));
+        pr.PoolId = mr.PoolId;
+        if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
+            bsendmsg(ua, "%s", db_strerror(ua->db));
+           return 0;
+        }
+         bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
+         if (!get_cmd(ua, _("Enter new Pool name: "))) {
+           return 0;
+        }
+        update_volpool(ua, ua->cmd, &mr);
+        return 1;
       default:                       /* Done or error */
          bsendmsg(ua, "Selection done.\n");
         return 1;
index 829e1e9a927d962a1c20615ae9443991253fc9c6..f54eaf22a36bc4080879ce3327ce72adf691fac6 100644 (file)
@@ -557,6 +557,7 @@ Priority:   %d\n"),
             add_prompt(ua, _("Initialize Catalog"));
             add_prompt(ua, _("Verify Catalog"));
             add_prompt(ua, _("Verify Volume to Catalog"));
+            add_prompt(ua, _("Verify Disk to Catalog"));
             add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
             switch (do_prompt(ua, "",  _("Select level"), NULL, 0)) {
            case 0:
@@ -569,6 +570,9 @@ Priority:   %d\n"),
               jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
               break;
            case 3:
+              jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
+              break;
+           case 4:
               jcr->JobLevel = L_VERIFY_DATA;
               break;
            default:
index 29db4a832dd91ebddf45b2ea66909b2f23dbd3d5..f09b7d5147b674102e5708301ee8bf1b0f72a364 100644 (file)
@@ -195,7 +195,7 @@ static void set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, int valu
       tree_getpath(node, cwd, sizeof(cwd));
       fdbr.FileId = 0;
       fdbr.JobId = node->JobId;
-      if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, &fdbr)) {
+      if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) {
         int32_t LinkFI;
         decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */
         /*
@@ -338,7 +338,7 @@ static int dircmd(UAContext *ua, TREE_CTX *tree)
         tree_getpath(node, cwd, sizeof(cwd));
         fdbr.FileId = 0;
         fdbr.JobId = node->JobId;
-        if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, &fdbr)) {
+        if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) {
            int32_t LinkFI;
            decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */
            ls_output(buf, cwd, node->extract, &statp);
index 40faac1e41f1669c9af3e6688d8be073dc42ad7d..213d8ddc5f80efab334caf12ac76dc6eccb5dbc1 100644 (file)
@@ -64,9 +64,9 @@ static int missing_handler(void *ctx, int num_fields, char **row);
  */
 int do_verify(JCR *jcr) 
 {
-   char *level;
+   char *level, *Name;
    BSOCK   *fd;
-   JOB_DBR jr;
+   JOB_DBR jr, verify_jr;
    JobId_t JobId = 0;
    int stat;
 
@@ -76,14 +76,23 @@ int do_verify(JCR *jcr)
 
    Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
 
-   /* If we are doing a verify from the catalog,
-    * we must look up the time and date of the
-    * last full verify.
+   /*
+    * Find JobId of last job that ran. E.g. 
+    *  for VERIFY_CATALOG we want the JobId of the last INIT.
+    *  for VERIFY_VOLUME_TO_CATALOG, we want the JobId of the 
+    *      last backup Job.
     */
    if (jcr->JobLevel == L_VERIFY_CATALOG || 
        jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
       memcpy(&jr, &jcr->jr, sizeof(jr));
-      if (!db_find_last_jobid(jcr, jcr->db, &jr)) {
+      if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG &&
+         jcr->job->verify_job) {
+        Name = jcr->job->verify_job->hdr.name;
+      } else {
+        Name = NULL;
+      }
+      Dmsg1(100, "find last jobid for: %s\n", NPRT(Name));
+      if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) {
         if (jcr->JobLevel == L_VERIFY_CATALOG) {
            Jmsg(jcr, M_FATAL, 0, _(
                  "Unable to find JobId of previous InitCatalog Job.\n"
@@ -96,7 +105,7 @@ int do_verify(JCR *jcr)
         goto bail_out;
       }
       JobId = jr.JobId;
-      Dmsg1(20, "Last full id=%d\n", JobId);
+      Dmsg1(100, "Last full Jobid=%d\n", JobId);
    } 
 
    jcr->jr.JobId = jcr->JobId;
@@ -111,28 +120,31 @@ int do_verify(JCR *jcr)
       jcr->fname = get_pool_memory(PM_FNAME);
    }
 
-   jcr->jr.JobId = JobId;      /* save target JobId */
-
    /* Print Job Start message */
    Jmsg(jcr, M_INFO, 0, _("Start Verify JobId %d Job=%s\n"),
       jcr->JobId, jcr->Job);
 
+   /*
+    * Now get the job record for the previous backup that interests
+    *  us. We use the JobId that we found above.
+    */
    if (jcr->JobLevel == L_VERIFY_CATALOG || 
-       jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
-      memset(&jr, 0, sizeof(jr));
-      jr.JobId = JobId;
-      if (!db_get_job_record(jcr, jcr->db, &jr)) {
+       jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
+       jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG) {
+      memset(&verify_jr, 0, sizeof(verify_jr));
+      verify_jr.JobId = JobId;
+      if (!db_get_job_record(jcr, jcr->db, &verify_jr)) {
          Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"), 
              db_strerror(jcr->db));
         goto bail_out;
       }
-      if (jr.JobStatus != 'T') {
+      if (verify_jr.JobStatus != 'T') {
          Jmsg(jcr, M_FATAL, 0, _("Last Job %d did not terminate normally. JobStatus=%c\n"),
-           JobId, jr.JobStatus);
+           JobId, verify_jr.JobStatus);
         goto bail_out;
       }
       Jmsg(jcr, M_INFO, 0, _("Verifying against JobId=%d Job=%s\n"),
-        JobId, jr.Job); 
+        verify_jr.JobId, verify_jr.Job); 
    }
 
    /* 
@@ -144,12 +156,12 @@ int do_verify(JCR *jcr)
    if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
       RBSR *bsr = new_bsr();
       UAContext *ua;
-      bsr->JobId = jr.JobId;
+      bsr->JobId = verify_jr.JobId;
       ua = new_ua_context(jcr);
       complete_bsr(ua, bsr);
       bsr->fi = new_findex();
       bsr->fi->findex = 1;
-      bsr->fi->findex2 = jr.JobFiles;
+      bsr->fi->findex2 = verify_jr.JobFiles;
       if (!write_bsr_file(ua, bsr)) {
         free_ua_context(ua);
         free_bsr(bsr);
@@ -188,6 +200,13 @@ int do_verify(JCR *jcr)
    } else {
       jcr->sd_auth_key = bstrdup("dummy");    /* dummy Storage daemon key */
    }
+
+   if (jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG &&
+       jcr->job->verify_job) {
+       jcr->fileset = jcr->job->verify_job->fileset;
+   }
+   jcr->verify_jr = &verify_jr;
+
    /*
     * OK, now connect to the File daemon
     *  and ask him for the files.
@@ -200,6 +219,7 @@ int do_verify(JCR *jcr)
    set_jcr_job_status(jcr, JS_Running);
    fd = jcr->file_bsock;
 
+
    Dmsg0(30, ">filed: Send include list\n");
    if (!send_include_list(jcr)) {
       goto bail_out;
@@ -262,6 +282,9 @@ int do_verify(JCR *jcr)
    case L_VERIFY_DATA:
       level = "data";
       break;
+   case L_VERIFY_DISK_TO_CATALOG:
+      level="disk_to_catalog";
+      break;
    default:
       Jmsg1(jcr, M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->JobLevel);
       goto bail_out;
@@ -298,6 +321,11 @@ int do_verify(JCR *jcr)
       get_attributes_and_compare_to_catalog(jcr, JobId);
       break;
 
+   case L_VERIFY_DISK_TO_CATALOG:
+      Dmsg0(10, "Verify level=disk_to_catalog\n");
+      get_attributes_and_compare_to_catalog(jcr, JobId);
+      break;
+
    case L_VERIFY_INIT:
       /* Build catalog */
       Dmsg0(10, "Verify level=init\n");
@@ -510,7 +538,8 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
          * Find equivalent record in the database 
          */
         fdbr.FileId = 0;
-        if (!db_get_file_attributes_record(jcr, jcr->db, jcr->fname, &fdbr)) {
+        if (!db_get_file_attributes_record(jcr, jcr->db, jcr->fname, 
+             jcr->verify_jr, &fdbr)) {
             Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
             Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
            stat = JS_Differences;
index 1f9662d4bafb62b0d6325611784e86448bcc21d2..689ae4d4d61a1a2a7a03473ca5997c3b162922e4 100644 (file)
@@ -843,6 +843,8 @@ static int verify_cmd(JCR *jcr)
       jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
    } else if (strcasecmp(level, "data") == 0){
       jcr->JobLevel = L_VERIFY_DATA;
+   } else if (strcasecmp(level, "disk_to_catalog") == 0) {
+      jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
    } else {   
       bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
       return 0;   
@@ -875,6 +877,9 @@ static int verify_cmd(JCR *jcr)
       /* Inform Storage daemon that we are done */
       bnet_sig(sd, BNET_TERMINATE);
 
+      break;
+   case L_VERIFY_DISK_TO_CATALOG:
+      do_verify(jcr);
       break;
    default:
       bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
index bd5ac212e0b86536c1d753eb5fdecc4140e8260e..5bbb0db369578042ce2b68af5e80ffa5777eb5f8 100644 (file)
@@ -192,7 +192,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
       return 0;
    }
 
-   /* If file opened, compute MD5 */
+   /* If file opened, compute MD5 or SHA1 hash */
    if (is_bopen(&bfd)  && ff_pkt->flags & FO_MD5) {
       char MD5buf[40];               /* 24 should do */
       MD5Init(&md5c);
index e3e012b61cd80f8747cd63bf3cc9c45fde98b4d6..88217eeb260c6d854598ada4af9da2b188183683 100644 (file)
@@ -40,6 +40,7 @@
 #define L_VERIFY_CATALOG         'C'  /* verify from catalog */
 #define L_VERIFY_INIT            'V'  /* verify save (init DB) */
 #define L_VERIFY_VOLUME_TO_CATALOG 'O'  /* verify Volume to catalog entries */
+#define L_VERIFY_DISK_TO_CATALOG 'd'  /* verify Disk attributes to catalog */
 #define L_VERIFY_DATA            'A'  /* verify data on volume */
 #define L_BASE                   'B'  /* Base level job */
 
@@ -154,7 +155,8 @@ struct JCR {
    POOLMEM *fname;                    /* name to put into catalog */
    int fn_printed;                    /* printed filename */
    POOLMEM *stime;                    /* start time for incremental/differential */
-   JOB_DBR jr;                        /* Job record in Database */
+   JOB_DBR jr;                        /* Job DB record for current job */
+   JOB_DBR *verify_jr;                /* Pointer to target job */
    uint32_t RestoreJobId;             /* Id specified by UA */
    POOLMEM *client_uname;             /* client uname */ 
    int replace;                       /* Replace option */
index 1bf6a8836bd50bdc2cf477de65be599d9c0b5209..56f311f6bee713bfefcba76d454b049ef15bec5f 100644 (file)
@@ -575,7 +575,7 @@ static int record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       }
       fr.JobId = mjcr->JobId;
       fr.FileId = 0;
-      if (db_get_file_attributes_record(bjcr, db, attr->fname, &fr)) {
+      if (db_get_file_attributes_record(bjcr, db, attr->fname, NULL, &fr)) {
         if (verbose > 1) {
             Pmsg1(000, _("File record already exists for: %s\n"), attr->fname);
         }
index 225618e80875e3a7ef0325d0bf62e6db3268c359..9a35e2d15a915df91bd30722237a00370dff0611 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.32b"
 #define VSTRING "1"
-#define BDATE   "10 Oct 2003"
-#define LSMDATE "10Oct03"
+#define BDATE   "14 Oct 2003"
+#define LSMDATE "14Oct03"
 
 /* Debug flags */
 #undef  DEBUG