]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Make bscan ignore ACL streams.
authorKern Sibbald <kern@sibbald.com>
Sun, 30 Jul 2006 16:00:35 +0000 (16:00 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 30 Jul 2006 16:00:35 +0000 (16:00 +0000)
kes  Update projects files with new Feature Requests.
kes  Generate current English and French manuals and upload
     them to the site.
kes  Update the home page to include the new British/French flags to
     switch between translations. Work done by Alexandre Baron.
kes  Make disk-changer script print an error message if the changer
     directory is not defined.
kes  Create a generic DB routine for getting an int (32/64 bit) from
     the DB.
kes  Add more migration code.
kes  Add a few more files to .cvsignore here and there.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3201 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/kernstodo
bacula/kes-1.39
bacula/projects
bacula/scripts/disk-changer.in
bacula/src/cats/bdb.c
bacula/src/cats/cats.h
bacula/src/cats/protos.h
bacula/src/cats/sql.c
bacula/src/dird/catreq.c
bacula/src/dird/dird_conf.h
bacula/src/dird/migrate.c
bacula/src/filed/job.c
bacula/src/jcr.h
bacula/src/stored/bscan.c
bacula/src/version.h

index a61bfa79aa1e2c8156fb35f9b58e9db8ab21af28..4926a8fdb72baa0966b78b6323141481ada3ca60 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                     16 July 2006
+                     30 July 2006
 
 Major development:      
 Project                     Developer
@@ -28,6 +28,9 @@ Document:
 Priority:
 
 For 1.39:
+- Fix bextract to restore ACLs, or better yet, use common
+  routines.
+- Do we migrate appendable Volumes?
 - Remove queue.c code.
 - Add bconsole option to use stdin/out instead of conio.
 - Fix ClientRunBefore/AfterJob compatibility.
index ab161b5e514168c5b283cb15500b5dcd19ed7ca1..995e59bf288b593ccfbffb08e632b58c471058c0 100644 (file)
@@ -2,6 +2,32 @@
                         Kern Sibbald
 
 General:
+30Jul06
+kes  Make bscan ignore ACL streams.
+kes  Update projects files with new Feature Requests.
+kes  Generate current English and French manuals and upload
+     them to the site.
+kes  Update the home page to include the new British/French flags to
+     switch between translations. Work done by Alexandre Baron.
+kes  Make disk-changer script print an error message if the changer
+     directory is not defined.
+kes  Create a generic DB routine for getting an int (32/64 bit) from
+     the DB.
+kes  Add more migration code.
+kes  Add a few more files to .cvsignore here and there.
+
+Version 1.39.18
+29Jul06
+- Incremented the version number to signify that all of Robert's code
+  for Win32 that was in the branch is now integrated into the HEAD,
+  and that Eric has submitted code that we hope will provide limited
+  backward compatibility with 1.38 file daemons (more testing to be
+  done).
+- I rationalized a few of the names of the variables (mainly jcr names)
+  that are used during migration as keeping three different jcrs at the
+  same time clear in one's head is not easy.
+
+Version 1.39.17
 28Jul06
 - Tweak new runscript feature to work with 1.38.x FDs. 
 - Correct crypto.c to fix segfault when restoring an encrypted stream 
index 3bc11156a6d3b8c986d946f10dbc6e900055388a..6e126ec18697a8bf19f311767da1be92944fe595 100644 (file)
@@ -1,8 +1,8 @@
                 
 Projects:
                      Bacula Projects Roadmap 
-                       07 December 2005
-                    (prioritized by user vote)
+                Prioritized by user vote 07 December 2005
+                    Status updated 30 July 2006
 
 Summary:
 Item  1:  Implement data encryption (as opposed to comm encryption)
@@ -37,7 +37,7 @@ Below, you will find more information on future projects:
 Item  1:  Implement data encryption (as opposed to comm encryption)
   Date:   28 October 2005
   Origin: Sponsored by Landon and 13 contributors to EFF.
-  Status: Landon Fuller has implemented this in 1.39.x.
+  Status: Done: Landon Fuller has implemented this in 1.39.x.
                   
   What:   Currently the data that is stored on the Volume is not
           encrypted. For confidentiality, encryption of data at
@@ -51,7 +51,7 @@ Item 2:   Implement Migration that moves Jobs from one Pool to another.
   Origin: Sponsored by Riege Software International GmbH. Contact:
           Daniel Holtkamp <holtkamp at riege dot com>
   Date:   28 October 2005
-  Status: Partially working in 1.39, more to do. Assigned to
+  Status: 90% complete: Working in 1.39, more to do. Assigned to
           Kern.
 
   What:   The ability to copy, move, or archive data that is on a
@@ -389,7 +389,8 @@ Item  9:  Implement new {Client}Run{Before|After}Job feature.
 Item 10:  Merge multiple backups (Synthetic Backup or Consolidation).
   Origin: Marc Cousin and Eric Bollengier 
   Date:   15 November 2005
-  Status: Depends on first implementing project Item 1 (Migration).
+  Status: Waiting implementation. Depends on first implementing 
+          project Item 2 (Migration).
 
   What:   A merged backup is a backup made without connecting to the Client.
           It would be a Merge of existing backups into a single backup.
@@ -446,7 +447,7 @@ Item 12:  Directive/mode to backup only file changes, not entire file
   Date:   11 November 2005
   Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
           Marek Bajon <mbajon at bimsplus dot com dot pl>
-  Status: RFC
+  Status: 
 
   What:   Currently when a file changes, the entire file will be backed up in
           the next incremental or full backup.  To save space on the tapes
@@ -755,6 +756,7 @@ Item n:   One line summary ...
 
 ===============================================
 Feature requests submitted after cutoff for December 2005 vote
+  and not yet discussed.
 ===============================================
 Item n:   Allow skipping execution of Jobs
   Date:   29 November 2005
@@ -798,4 +800,106 @@ Item n: archive data
           could do this bit ability to save data uncompresed so
           it can be read in any other system (future proof data)
           save the catalog with the disk as some kind of menu
-          system
+          system 
+
+Item :  Tray monitor window cleanups
+  Origin: Alan Brown ajb2 at mssl dot ucl dot ac dot uk
+  Date:   24 July 2006
+  Status:
+  What:   Resizeable and scrollable windows in the tray monitor.
+
+  Why:    With multiple clients, or with many jobs running, the displayed
+          window often ends up larger than the available screen, making
+          the trailing items difficult to read.
+
+   Notes:
+
+  Item :  Clustered file-daemons
+  Origin: Alan Brown ajb2 at mssl dot ucl dot ac dot uk
+  Date:   24 July 2006
+  Status:
+  What:   A "virtual" filedaemon, which is actually a cluster of real ones.
+
+  Why:    In the case of clustered filesystems (SAN setups, GFS, or OCFS2, etc)
+          multiple machines may have access to the same set of filesystems
+
+          For performance reasons, one may wish to initate backups from
+          several of these machines simultaneously, instead of just using
+          one backup source for the common clustered filesystem.
+
+          For obvious reasons, normally backups of $A-FD/$PATH and
+          B-FD/$PATH are treated as different backup sets. In this case
+          they are the same communal set.
+
+          Likewise when restoring, it would be easier to just specify
+          one of the cluster machines and let bacula decide which to use.
+
+          This can be faked to some extent using DNS round robin entries
+          and a virtual IP address, however it means "status client" will
+          always give bogus answers. Additionally there is no way of
+          spreading the load evenly among the servers.
+
+          What is required is something similar to the storage daemon
+          autochanger directives, so that Bacula can keep track of
+          operating backups/restores and direct new jobs to a "free"
+          client.
+
+   Notes:
+
+Item :  Tray monitor window cleanups
+  Origin: Alan Brown ajb2 at mssl dot ucl dot ac dot uk
+  Date:   24 July 2006
+  Status:
+  What:   Resizeable and scrollable windows in the tray monitor.
+
+  Why:    With multiple clients, or with many jobs running, the displayed
+          window often ends up larger than the available screen, making
+          the trailing items difficult to read.
+
+  Notes:
+
+Item:    Commercial database support
+  Origin: Russell Howe <russell_howe dot wreckage dot org>
+  Date:   26 July 2006
+  Status:
+
+  What:   It would be nice for the database backend to support more 
+          databases. I'm thinking of SQL Server at the moment, but I guess Oracle, 
+          DB2, MaxDB, etc are all candidates. SQL Server would presumably be 
+          implemented using FreeTDS or maybe an ODBC library?
+
+  Why:    We only really have one database server, which is MS SQL Server 
+          2000. Maintaining a second one for the backup software (we grew out of 
+          SQLite, which I liked, but which didn't work so well with our database 
+          size). We don't really have a machine with the resources to run 
+          postgres, and would rather only maintain a single DBMS. We're stuck with 
+          SQL Server because pretty much all the company's custom applications 
+          (written by consultants) are locked into SQL Server 2000. I can imagine 
+          this scenario is fairly common, and it would be nice to use the existing 
+          properly specced database server for storing Bacula's catalog, rather 
+          than having to run a second DBMS.
+
+
+Item n:   Split documentation
+  Origin: Maxx <maxxatworkat gmail dot com>
+  Date:   27th July 2006
+  Status:
+
+  What:   Split documentation in several books
+
+  Why:    Bacula manual has now more than 600 pages, and looking for
+          implementation details is getting complicated.  I think
+          it would be good to split the single volume in two or
+          maybe three parts:
+
+          1) Introduction, requirements and tutorial, typically
+             are useful only until first installation time
+
+          2) Basic installation and configuration, with all the
+             gory details about the directives supported 3)
+             Advanced Bacula: testing, troubleshooting, GUI and
+             ancillary programs, security managements, scripting,
+             etc.
+
+  Notes:
+
index c66799b50e0e8b13e8aeaee71b5a4ee1c1936c8c..7cba06acf431f7c3131a362928ead92a77aaa58f 100644 (file)
@@ -108,6 +108,11 @@ check_parm_count() {
 get_dir() {
    bn=`basename $device`
    dir=`echo "$device" | sed -e s%/$bn%%g -`
+   if [ ! -d $dir ]; then
+      echo "ERROR: Autochanger directory \"$dir\" does not exist.\n"
+      echo "      You must create it.\n"
+      exit 1
+   fi
 }
 
 
index 43cc175e2bc81d4c8ac44c05ad5fd15e04471538..3aa57c220da3fcc3ef086cd47e68641d0450d04c 100644 (file)
@@ -462,4 +462,8 @@ db_list_pool_records(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr,
                      DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
 { }
 
+int db_int64_handler(void *ctx, int num_fields, char **row)
+{ return 0; }
+
+
 #endif /* HAVE_BACULA_DB */
index a196701e30119defe06c9d2a6fc60f1c6d176042..1d47ae6d060b2047f8cfd5568240565df544492c 100644 (file)
@@ -786,19 +786,24 @@ struct FILESET_DBR {
    bool created;                      /* set when record newly created */
 };
 
+/* Call back context for getting a 32/64 bit value from the database */
+struct db_int64_ctx {
+   int64_t value;                     /* value returned */
+   int count;                         /* number of values seen */
+};
 
 
 #include "protos.h"
 #include "jcr.h"
 
 /*
- * Some functions exported by sql.c for use withing the
+ * Some functions exported by sql.c for use within the
  *   cats directory.
  */
 void list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
 void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx);
 int get_sql_record_max(JCR *jcr, B_DB *mdb);
-int check_tables_version(JCR *jcr, B_DB *mdb);
+bool check_tables_version(JCR *jcr, B_DB *mdb);
 void _db_unlock(const char *file, int line, B_DB *mdb);
 void _db_lock(const char *file, int line, B_DB *mdb);
 
index dcc84f7cb8fdbff493db16091a346193a18091c4..646c44715731f037cdd46f018721b0d138b1a34d 100644 (file)
@@ -39,6 +39,7 @@ int  db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index);
 int  db_sql_query(B_DB *mdb, const char *cmd, DB_RESULT_HANDLER *result_handler, void *ctx);
 void db_start_transaction(JCR *jcr, B_DB *mdb);
 void db_end_transaction(JCR *jcr, B_DB *mdb);
+int db_int64_handler(void *ctx, int num_fields, char **row);
 
 
 /* create.c */
index d1ab64267224107e1a57563219ca73e0075d8420..0ee91f8847305c9ff6ea7963245931f937615ef0 100644 (file)
@@ -60,6 +60,21 @@ static int int_handler(void *ctx, int num_fields, char **row)
    return 0;
 }
 
+/*
+ * Called here to retrieve a 32/64 bit integer from the database.
+ *   The returned integer will be extended to 64 bit.
+ */
+int db_int64_handler(void *ctx, int num_fields, char **row)
+{
+   db_int64_ctx *lctx = (db_int64_ctx *)ctx;
+
+   if (row[0]) {
+      lctx->value = str_to_int64(row[0]);
+      lctx->count++;
+   }
+   return 0;
+}
+
 
 
 /* NOTE!!! The following routines expect that the
@@ -67,7 +82,7 @@ static int int_handler(void *ctx, int num_fields, char **row)
  */
 
 /* Check that the tables correspond to the version we want */
-int check_tables_version(JCR *jcr, B_DB *mdb)
+bool check_tables_version(JCR *jcr, B_DB *mdb)
 {
    const char *query = "SELECT VersionId FROM Version";
 
@@ -75,14 +90,15 @@ int check_tables_version(JCR *jcr, B_DB *mdb)
    if (!db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version)) {
       Mmsg(mdb->errmsg, "Database not created or server not running.\n");
       Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+      return false;
    }
    if (bacula_db_version != BDB_VERSION) {
       Mmsg(mdb->errmsg, "Version error for database \"%s\". Wanted %d, got %d\n",
           mdb->db_name, BDB_VERSION, bacula_db_version);
       Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
-      return 0;
+      return false;
    }
-   return 1;
+   return true;
 }
 
 /* Utility routine for queries. The database MUST be locked before calling here. */
index 75b1c8b1635035c08a809b4afd126afac904210b..3dd8a582124f1b3a1bf3c12c77585f8585b837e1 100644 (file)
@@ -282,8 +282,8 @@ void catalog_request(JCR *jcr, BSOCK *bs)
       &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile,
       &jm.StartBlock, &jm.EndBlock, &jm.Copy, &Stripe) == 9) {
 
-      if (jcr->previous_jcr) {
-         jm.JobId = jcr->previous_jcr->JobId;
+      if (jcr->mig_jcr) {
+         jm.JobId = jcr->mig_jcr->JobId;
          jm.MediaId = jcr->MediaId;
       } else {
          jm.JobId = jcr->JobId;
@@ -397,8 +397,8 @@ void catalog_update(JCR *jcr, BSOCK *bs)
       ar->FileIndex = FileIndex;
       ar->Stream = Stream;
       ar->link = NULL;
-      if (jcr->previous_jcr) {
-         ar->JobId = jcr->previous_jcr->JobId;
+      if (jcr->mig_jcr) {
+         ar->JobId = jcr->mig_jcr->JobId;
       } else {
          ar->JobId = jcr->JobId;
       }
index 6695df9085a96444f4df08454f38f1c3abb0cc83..e77ccdeaae06a1ca83092ae150b8113f41d8971b 100644 (file)
@@ -463,8 +463,8 @@ public:
    uint32_t MaxVolFiles;              /* Maximum files on the Volume */
    uint64_t MaxVolBytes;              /* Maximum bytes on the Volume */
    utime_t MigrationTime;             /* Time to migrate to next pool */
-   uint32_t MigrationHighBytes;       /* When migration starts */
-   uint32_t MigrationLowBytes;        /* When migration stops */
+   uint64_t MigrationHighBytes;       /* When migration starts */
+   uint64_t MigrationLowBytes;        /* When migration stops */
    POOL  *NextPool;                   /* Next pool for migration */
    alist *storage;                    /* Where is device -- list of Storage to be used */
    bool  use_catalog;                 /* maintain catalog for media */
index e30fb296500ac96563c7649db67defb940ff1a22..20e6078235dc0ed6a07c3e0931cf9e5b0233bf2a 100644 (file)
@@ -45,6 +45,9 @@ static bool get_job_to_migrate(JCR *jcr);
 struct idpkt;
 static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1,
                  const char *query2, const char *type);
+static bool find_mediaid_then_jobids(JCR *jcr, idpkt *ids, const char *query1,
+                 const char *type);
+static bool find_jobids_from_mediaid_list(JCR *jcr, idpkt *ids, const char *type);
 static void start_migration_job(JCR *jcr);
 
 /* 
@@ -98,8 +101,22 @@ bool do_migration(JCR *jcr)
    char ed1[100];
    BSOCK *sd;
    JOB *job, *prev_job;
-   JCR *prev_jcr;                     /* newly migrated job */
+   JCR *mig_jcr;                   /* newly migrated job */
 
+   /* 
+    *  previous_jr refers to the job DB record of the Job that is
+    *    being migrated.
+    *  prev_job refers to the job resource of the Job that is
+    *    being migrated.
+    *  jcr is the jcr for the current "migration" job.  It is a
+    *    control job that is put in the DB as a migration job, which
+    *    means that this job migrated a previous job to a new job.
+    *  mig_jcr refers to the newly migrated job that is run by
+    *    the current jcr.  It is a backup job that moves (migrates) the
+    *    data written for the previous_jr into the new pool.  This
+    *    job (mig_jcr) becomes the new backup job that replaces
+    *    the original backup job.
+    */
    if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) {
       set_jcr_job_status(jcr, JS_Terminated);
       migration_cleanup(jcr, jcr->JobStatus);
@@ -122,39 +139,34 @@ bool do_migration(JCR *jcr)
       return false;
    }
 
-   /* 
-    *  prev_jcr is the new Job that corresponds to the original
-    *  job. It "runs" at the same time as the current 
-    *  migration job and becomes a new backup job that replaces
-    *  the original backup job.  Most operations on the current
-    *  migration jcr are also done on the prev_jcr.
-    */
-   prev_jcr = jcr->previous_jcr = new_jcr(sizeof(JCR), dird_free_jcr);
-   memcpy(&prev_jcr->previous_jr, &jcr->previous_jr, sizeof(prev_jcr->previous_jr));
+   mig_jcr = jcr->mig_jcr = new_jcr(sizeof(JCR), dird_free_jcr);
+   memcpy(&mig_jcr->previous_jr, &jcr->previous_jr, sizeof(mig_jcr->previous_jr));
 
-   /* Turn the prev_jcr into a "real" job */
-   set_jcr_defaults(prev_jcr, prev_job);
-   if (!setup_job(prev_jcr)) {
+   /* Turn the mig_jcr into a "real" job that takes on the aspects of
+    *   the previous backup job "prev_job".
+    */
+   set_jcr_defaults(mig_jcr, prev_job);
+   if (!setup_job(mig_jcr)) {
       return false;
    }
 
    /* Now reset the job record from the previous job */
-   memcpy(&prev_jcr->jr, &jcr->previous_jr, sizeof(prev_jcr->jr));
+   memcpy(&mig_jcr->jr, &jcr->previous_jr, sizeof(mig_jcr->jr));
    /* Update the jr to reflect the new values of PoolId, FileSetId, and JobId. */
-   prev_jcr->jr.PoolId = jcr->jr.PoolId;
-   prev_jcr->jr.FileSetId = jcr->jr.FileSetId;
-   prev_jcr->jr.JobId = prev_jcr->JobId;
+   mig_jcr->jr.PoolId = jcr->jr.PoolId;
+   mig_jcr->jr.FileSetId = jcr->jr.FileSetId;
+   mig_jcr->jr.JobId = mig_jcr->JobId;
 
-   Dmsg4(dbglevel, "Prev_jcr: Name=%s JobId=%d Type=%c Level=%c\n",
-      prev_jcr->jr.Name, prev_jcr->jr.JobId, 
-      prev_jcr->jr.JobType, prev_jcr->jr.JobLevel);
+   Dmsg4(dbglevel, "mig_jcr: Name=%s JobId=%d Type=%c Level=%c\n",
+      mig_jcr->jr.Name, mig_jcr->jr.JobId, 
+      mig_jcr->jr.JobType, mig_jcr->jr.JobLevel);
 
    /*
     * Get the PoolId used with the original job. Then
     *  find the pool name from the database record.
     */
    memset(&pr, 0, sizeof(pr));
-   pr.PoolId = prev_jcr->previous_jr.PoolId;
+   pr.PoolId = mig_jcr->previous_jr.PoolId;
    if (!db_get_pool_record(jcr, jcr->db, &pr)) {
       Jmsg(jcr, M_FATAL, 0, _("Pool for JobId %s not in database. ERR=%s\n"),
             edit_int64(pr.PoolId, ed1), db_strerror(jcr->db));
@@ -167,11 +179,8 @@ bool do_migration(JCR *jcr)
       return false;
    }
 
-   /* Check Migration time and High/Low water marks */
-   /* ***FIXME*** */
-
    /* If pool storage specified, use it for restore */
-   copy_rstorage(prev_jcr, pool->storage, _("Pool resource"));
+   copy_rstorage(mig_jcr, pool->storage, _("Pool resource"));
    copy_rstorage(jcr, pool->storage, _("Pool resource"));
 
    /* If the original backup pool has a NextPool, make sure a 
@@ -186,8 +195,8 @@ bool do_migration(JCR *jcr)
        * put the "NextPool" resource pointer in our jcr so that we
        * can pull the Storage reference from it.
        */
-      prev_jcr->pool = jcr->pool = pool->NextPool;
-      prev_jcr->jr.PoolId = jcr->jr.PoolId;
+      mig_jcr->pool = jcr->pool = pool->NextPool;
+      mig_jcr->jr.PoolId = jcr->jr.PoolId;
       pm_strcpy(jcr->pool_source, _("NextPool in Pool resource"));
    }
 
@@ -199,7 +208,7 @@ bool do_migration(JCR *jcr)
         edit_uint64(jcr->JobId, ed1), jcr->Job);
 
    set_jcr_job_status(jcr, JS_Running);
-   set_jcr_job_status(prev_jcr, JS_Running);
+   set_jcr_job_status(mig_jcr, JS_Running);
    Dmsg2(dbglevel, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel);
 
    /* Update job start record for this migration job */
@@ -208,13 +217,13 @@ bool do_migration(JCR *jcr)
       return false;
    }
 
-   Dmsg4(dbglevel, "Prev_jcr: Name=%s JobId=%d Type=%c Level=%c\n",
-      prev_jcr->jr.Name, prev_jcr->jr.JobId, 
-      prev_jcr->jr.JobType, prev_jcr->jr.JobLevel);
+   Dmsg4(dbglevel, "mig_jcr: Name=%s JobId=%d Type=%c Level=%c\n",
+      mig_jcr->jr.Name, mig_jcr->jr.JobId, 
+      mig_jcr->jr.JobType, mig_jcr->jr.JobLevel);
 
    /* Update job start record for migrated job */
-   if (!db_update_job_start_record(prev_jcr, prev_jcr->db, &prev_jcr->jr)) {
-      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(prev_jcr->db));
+   if (!db_update_job_start_record(mig_jcr, mig_jcr->db, &mig_jcr->jr)) {
+      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(mig_jcr->db));
       return false;
    }
 
@@ -227,7 +236,7 @@ bool do_migration(JCR *jcr)
     */
    Dmsg0(110, "Open connection with storage daemon\n");
    set_jcr_job_status(jcr, JS_WaitSD);
-   set_jcr_job_status(prev_jcr, JS_WaitSD);
+   set_jcr_job_status(mig_jcr, JS_WaitSD);
    /*
     * Start conversation with Storage daemon
     */
@@ -264,7 +273,7 @@ bool do_migration(JCR *jcr)
 
 
    set_jcr_job_status(jcr, JS_Running);
-   set_jcr_job_status(prev_jcr, JS_Running);
+   set_jcr_job_status(mig_jcr, JS_Running);
 
    /* Pickup Job termination data */
    /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */
@@ -275,7 +284,7 @@ bool do_migration(JCR *jcr)
       return false;
    }
    migration_cleanup(jcr, jcr->JobStatus);
-   if (prev_jcr) {
+   if (mig_jcr) {
       UAContext *ua = new_ua_context(jcr);
       purge_files_from_job(ua, jcr->previous_jr.JobId);
       free_ua_context(ua);
@@ -365,7 +374,7 @@ const char *sql_jobids_from_client =
 /* Get Volume names in Pool */
 const char *sql_vol = 
    "SELECT DISTINCT VolumeName FROM Media,Pool WHERE"
-   " VolStatus in ('Full','Used','Error') AND"
+   " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s'";
 
 /* Get JobIds from regex'ed Volume names */
@@ -374,23 +383,21 @@ const char *sql_jobids_from_vol =
    " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId"
    " AND JobMedia.JobId=Job.JobId" 
    " ORDER by Job.StartTime";
-   
-
-
 
 
 const char *sql_smallest_vol = 
    "SELECT MediaId FROM Media,Pool WHERE"
-   " VolStatus in ('Full','Used','Error') AND"
+   " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s'"
    " ORDER BY VolBytes ASC LIMIT 1";
 
 const char *sql_oldest_vol = 
    "SELECT MediaId FROM Media,Pool WHERE"
-   " VolStatus in ('Full','Used','Error') AND"
+   " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s'"
    " ORDER BY LastWritten ASC LIMIT 1";
 
+/* Get JobIds when we have selected MediaId */
 const char *sql_jobids_from_mediaid =
    "SELECT DISTINCT Job.JobId,Job.StartTime FROM JobMedia,Job"
    " WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId=%s"
@@ -398,12 +405,12 @@ const char *sql_jobids_from_mediaid =
 
 const char *sql_pool_bytes =
    "SELECT SUM(VolBytes) FROM Media,Pool WHERE"
-   " VolStatus in ('Full','Used','Error','Append') AND"
+   " VolStatus in ('Full','Used','Error','Append') AND Media.Enabled=1 AND"
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s'";
 
 const char *sql_vol_bytes =
    "SELECT MediaId FROM Media,Pool WHERE"
-   " VolStatus in ('Full','Used','Error') AND"
+   " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s' AND"
    " VolBytes<%s ORDER BY LastWritten ASC LIMIT 1";
 
@@ -467,22 +474,36 @@ static bool get_job_to_migrate(JCR *jcr)
             goto bail_out;
          }
          break;
-
-
-/***** Below not implemented yet *********/
       case MT_SMALLEST_VOL:
-         Mmsg(query, sql_smallest_vol, jcr->pool->hdr.name);
-//       Mmsg(query2, sql_jobids_from_mediaid, JobIds);
-//       Dmsg1(000, "Smallest Vol Jobids=%s\n", JobIds);
+         if (!find_mediaid_then_jobids(jcr, &ids, sql_smallest_vol, "Smallest Volume")) {
+            goto bail_out;
+         }
          break;
       case MT_OLDEST_VOL:
-         Mmsg(query, sql_oldest_vol, jcr->pool->hdr.name);
-//       Mmsg(query2, sql_jobids_from_mediaid, JobIds);
-//       Dmsg1(000, "Oldest Vol Jobids=%s\n", JobIds);
+         if (!find_mediaid_then_jobids(jcr, &ids, sql_oldest_vol, "Oldest Volume")) {
+            goto bail_out;
+         }
          break;
+
+/***** Below not implemented yet *********/
       case MT_POOL_OCCUPANCY:
+         db_int64_ctx ctx;
+
+         ctx.count = 0;
          Mmsg(query, sql_pool_bytes, jcr->pool->hdr.name);
-//       Dmsg1(000, "Pool Occupancy Jobids=%s\n", JobIds);
+         if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) {
+            Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+            goto bail_out;
+         }
+         if (ctx.count == 0) {
+            Jmsg(jcr, M_INFO, 0, _("No Volumes found to migrate.\n"));
+            goto bail_out;
+         }
+         if (ctx.value > (int64_t)jcr->pool->MigrationHighBytes) {
+            Dmsg2(000, "highbytes=%d pool=%d\n", (int)jcr->pool->MigrationHighBytes,
+               (int)ctx.value);
+         }
+         goto bail_out;
          break;
       case MT_POOL_TIME:
          Dmsg0(000, "Pool time not implemented\n");
@@ -566,9 +587,57 @@ static void start_migration_job(JCR *jcr)
    free_ua_context(ua);
 }
 
+static bool find_mediaid_then_jobids(JCR *jcr, idpkt *ids, const char *query1,
+                 const char *type) 
+{
+   bool ok = false;
+   POOL_MEM query(PM_MESSAGE);
+
+   ids->count = 0;
+   /* Basic query for MediaId */
+   Mmsg(query, query1, jcr->pool->hdr.name);
+   if (!db_sql_query(jcr->db, query.c_str(), dbid_handler, (void *)ids)) {
+      Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+      goto bail_out;
+   }
+   if (ids->count == 0) {
+      Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+   }
+   if (ids->count != 1) {
+      Jmsg(jcr, M_FATAL, 0, _("SQL logic error. Count should be 1 but is %d\n"), 
+         ids->count);
+      goto bail_out;
+   }
+   Dmsg1(000, "Smallest Vol Jobids=%s\n", ids->list);
+
+   ok = find_jobids_from_mediaid_list(jcr, ids, type);
+
+bail_out:
+   return ok;
+}
+
+static bool find_jobids_from_mediaid_list(JCR *jcr, idpkt *ids, const char *type) 
+{
+   bool ok = false;
+   POOL_MEM query(PM_MESSAGE);
+
+   Mmsg(query, sql_jobids_from_mediaid, ids->list);
+   ids->count = 0;
+   if (!db_sql_query(jcr->db, query.c_str(), dbid_handler, (void *)ids)) {
+      Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+      goto bail_out;
+   }
+   if (ids->count == 0) {
+      Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+   }
+   ok = true;
+bail_out:
+   return ok;
+}
 
 static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1,
-                 const char *query2, const char *type) {
+                 const char *query2, const char *type) 
+{
    dlist *item_chain;
    uitem *item = NULL;
    uitem *last_item = NULL;
@@ -667,7 +736,7 @@ void migration_cleanup(JCR *jcr, int TermCode)
    MEDIA_DBR mr;
    double kbps;
    utime_t RunTime;
-   JCR *prev_jcr = jcr->previous_jcr;
+   JCR *mig_jcr = jcr->mig_jcr;
    POOL_MEM query(PM_MESSAGE);
 
    Dmsg2(100, "Enter migrate_cleanup %d %c\n", TermCode, TermCode);
@@ -678,33 +747,33 @@ void migration_cleanup(JCR *jcr, int TermCode)
 
    /* 
     * Check if we actually did something.  
-    *  prev_jcr is jcr of the newly migrated job.
+    *  mig_jcr is jcr of the newly migrated job.
     */
-   if (prev_jcr) {
-      prev_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles;
-      prev_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes;
-      prev_jcr->VolSessionId = jcr->VolSessionId;
-      prev_jcr->VolSessionTime = jcr->VolSessionTime;
-      prev_jcr->jr.RealEndTime = 0; 
-      prev_jcr->jr.PriorJobId = jcr->previous_jr.JobId;
+   if (mig_jcr) {
+      mig_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles;
+      mig_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes;
+      mig_jcr->VolSessionId = jcr->VolSessionId;
+      mig_jcr->VolSessionTime = jcr->VolSessionTime;
+      mig_jcr->jr.RealEndTime = 0; 
+      mig_jcr->jr.PriorJobId = jcr->previous_jr.JobId;
 
-      set_jcr_job_status(prev_jcr, TermCode);
+      set_jcr_job_status(mig_jcr, TermCode);
 
   
-      update_job_end_record(prev_jcr);
+      update_job_end_record(mig_jcr);
      
       /* Update final items to set them to the previous job's values */
       Mmsg(query, "UPDATE Job SET StartTime='%s',EndTime='%s',"
                   "JobTDate=%s WHERE JobId=%s", 
          jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, 
          edit_uint64(jcr->previous_jr.JobTDate, ec1),
-         edit_uint64(prev_jcr->jr.JobId, ec2));
-      db_sql_query(prev_jcr->db, query.c_str(), NULL, NULL);
+         edit_uint64(mig_jcr->jr.JobId, ec2));
+      db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
 
       /* Now marke the previous job as migrated */
       Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
            (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1));
-      db_sql_query(prev_jcr->db, query.c_str(), NULL, NULL);
+      db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
 
       if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
          Jmsg(jcr, M_WARNING, 0, _("Error getting job record for stats: %s"),
@@ -719,9 +788,9 @@ void migration_cleanup(JCR *jcr, int TermCode)
          set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
 
-      update_bootstrap_file(prev_jcr);
+      update_bootstrap_file(mig_jcr);
 
-      if (!db_get_job_volume_names(prev_jcr, prev_jcr->db, prev_jcr->jr.JobId, &prev_jcr->VolumeName)) {
+      if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) {
          /*
           * Note, if the job has erred, most likely it did not write any
           *  tape, so suppress this "error" message since in that case
@@ -729,9 +798,9 @@ void migration_cleanup(JCR *jcr, int TermCode)
           *  normal exit should we complain about this error.
           */
          if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) {
-            Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(prev_jcr->db));
+            Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(mig_jcr->db));
          }
-         prev_jcr->VolumeName[0] = 0;         /* none */
+         mig_jcr->VolumeName[0] = 0;         /* none */
       }
   }
 
@@ -808,8 +877,8 @@ void migration_cleanup(JCR *jcr, int TermCode)
    VERSION,
    LSMDATE,
         edt, 
-        prev_jcr ? edit_uint64(jcr->previous_jr.JobId, ec6) : "0", 
-        prev_jcr ? edit_uint64(prev_jcr->jr.JobId, ec7) : "0",
+        mig_jcr ? edit_uint64(jcr->previous_jr.JobId, ec6) : "0", 
+        mig_jcr ? edit_uint64(mig_jcr->jr.JobId, ec7) : "0",
         edit_uint64(jcr->jr.JobId, ec8),
         jcr->jr.Job,
         level_to_str(jcr->JobLevel), jcr->since,
@@ -825,7 +894,7 @@ void migration_cleanup(JCR *jcr, int TermCode)
         edit_uint64_with_commas(jcr->SDJobBytes, ec2),
         edit_uint64_with_suffix(jcr->SDJobBytes, ec3),
         (float)kbps,
-        prev_jcr ? prev_jcr->VolumeName : "",
+        mig_jcr ? mig_jcr->VolumeName : "",
         jcr->VolSessionId,
         jcr->VolSessionTime,
         edit_uint64_with_commas(mr.VolBytes, ec4),
@@ -834,10 +903,10 @@ void migration_cleanup(JCR *jcr, int TermCode)
         sd_term_msg,
         term_code);
 
-   Dmsg1(100, "migrate_cleanup() previous_jcr=0x%x\n", jcr->previous_jcr);
-   if (jcr->previous_jcr) {
-      free_jcr(jcr->previous_jcr);
-      jcr->previous_jcr = NULL;
+   Dmsg1(100, "migrate_cleanup() mig_jcr=0x%x\n", jcr->mig_jcr);
+   if (jcr->mig_jcr) {
+      free_jcr(jcr->mig_jcr);
+      jcr->mig_jcr = NULL;
    }
    Dmsg0(100, "Leave migrate_cleanup()\n");
 }
index c8100a12bfcc97cde983133b5d87c785c2cae87c..a7f3fd88a9f3df09f133cd54cfc8b14b8abe913c 100644 (file)
@@ -1328,14 +1328,14 @@ static int backup_cmd(JCR *jcr)
             } else {
                /* tell user if snapshot creation of a specific drive failed */
                int i;
-               for (i=0; i < strlen(szWinDriveLetters); i++) {
+               for (i=0; i < (int)strlen(szWinDriveLetters); i++) {
                   if (islower(szWinDriveLetters[i])) {
                      Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled on this drive.\n"), szWinDriveLetters[i]);
                      jcr->Errors++;
                   }
                }
                /* inform user about writer states */
-               for (i=0; i<g_pVSSClient->GetWriterCount(); i++)                
+               for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++)                
                   if (g_pVSSClient->GetWriterState(i) < 1) {
                      Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));                    
                      jcr->Errors++;
index 20630005f0e8c75067ec8c25ca59ac2af208bfea..f37b6f68650fa35f728feb48dd4feef0b7366b42 100644 (file)
@@ -214,7 +214,7 @@ public:
    JOB_DBR jr;                        /* Job DB record for current job */
    JOB_DBR previous_jr;               /* previous job database record */
    JOB *previous_job;                 /* Job resource of migration previous job */
-   JCR *previous_jcr;                 /* previous job control record */
+   JCR *mig_jcr;                      /* JCR for migration/copy job */
    char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */
    char since[MAX_TIME_LENGTH];       /* since time */
    union {
index 0500692c01b73e9d8cfbf837830d38ba560d38cb..fd5e49236f79aea9248fc4fd5065d3f5b2d6c02f 100644 (file)
@@ -751,6 +751,12 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
          Pmsg0(000, _("Got Prog Data Stream record.\n"));
       }
       break;
+
+   case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:   /* Standard ACL attributes on UNIX */
+   case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:  /* Default ACL attributes on UNIX */
+      /* Ignore Unix attributes */
+      break;
+
    default:
       Pmsg2(0, _("Unknown stream type!!! stream=%d data=%s\n"), rec->Stream, rec->data);
       break;
index 81709076ae2bd592e28274d24eb1b52f091e2a41..9c9d33c45903733a3b5a67e5fbaa09e6a69bd993 100644 (file)
@@ -3,9 +3,9 @@
  */
 
 #undef  VERSION
-#define VERSION "1.39.17"
-#define BDATE   "27 July 2006"
-#define LSMDATE "27Jul06"
+#define VERSION "1.39.18"
+#define BDATE   "30 July 2006"
+#define LSMDATE "30Jul06"
 
 /* Debug flags */
 #undef  DEBUG