]> git.sur5r.net Git - bacula/bacula/commitdiff
15Feb07
authorKern Sibbald <kern@sibbald.com>
Thu, 15 Feb 2007 18:57:55 +0000 (18:57 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 15 Feb 2007 18:57:55 +0000 (18:57 +0000)
kes  Add quick disconnect FD code from 2.1.4 to 2.0.3.  This code
     causes the SD to release the FD as soon as the FD has sent
     all the data to the SD. After that the SD will do any final
     despooling (data and attributes) that are necessary. This
     allows laptops to disconnect much quicker from the network
     after a backup.
13Feb07
kes  Apply Eric's ClientRunScriptAfter patch to 2.0 and 2.1.
11Feb07
kes  Optimize the use of the database a bit in the Status dir command.
     Only open it when needed, ensure that if any previous database
     was opened, it is closed.
10Feb07
kes  Modify dbcheck to handle orphaned JobMedia, Path, Filename,
     and File records in 300K chunks to be more efficient. This
     idea came from Juan Luis Frances (if I remember right).
09Feb07
kes  Update projects list.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.0@4183 91ce42f0-d328-0410-95d8-f526ca767f89

20 files changed:
bacula/projects
bacula/src/dird/catreq.c
bacula/src/dird/job.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_status.c
bacula/src/dird/ua_update.c
bacula/src/dird/verify.c
bacula/src/filed/job.c
bacula/src/filed/verify.c
bacula/src/jcr.h
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/fd_cmds.c
bacula/src/stored/protos.h
bacula/src/tools/dbcheck.c
bacula/src/version.h
bacula/technotes-2.0

index e9fc208ea57d231bbb76c07d7ebf435790ee1c03..24c6573c0854110c3fb3830a880102dcb32f374c 100644 (file)
@@ -4,6 +4,11 @@ Projects:
                     Status updated 26 January 2007
                    After re-ordering in vote priority
 
+Items Completed:
+Item:  18   Quick release of FD-SD connection after backup.
+Item:  40   Include JobID in spool file name
+Item:  25   Implement huge exclude list support using dlist   
+
 Summary:
 Item:   1   Accurate restoration of renamed/deleted files
 Item:   2   Implement a Bacula GUI/management tool.
@@ -22,14 +27,14 @@ Item:  14   Cause daemons to use a specific IP address to source communications
 Item:  15   Multiple threads in file daemon for the same job
 Item:  16   Add Plug-ins to the FileSet Include statements.
 Item:  17   Restore only file attributes (permissions, ACL, owner, group...)
-Item:  18   Quick release of FD-SD connection after backup.
+Item:  18*  Quick release of FD-SD connection after backup.
 Item:  19   Implement a Python interface to the Bacula catalog.
 Item:  20   Archive data
 Item:  21   Split documentation
 Item:  22   Implement support for stacking arbitrary stream filters, sinks.
 Item:  23   Implement from-client and to-client on restore command line.
 Item:  24   Add an override in Schedule for Pools based on backup types.
-Item:  25   Implement huge exclude list support using hashing.
+Item:  25*  Implement huge exclude list support using hashing.
 Item:  26   Implement more Python events in Bacula.
 Item:  27   Incorporation of XACML2/SAML2 parsing
 Item:  28   Filesystem watch triggered backup.
@@ -44,7 +49,7 @@ Item:  36   An option to operate on all pools with update vol parameters
 Item:  37   Add an item to the restore option where you can select a pool
 Item:  38   Include timestamp of job launch in "stat clients" output
 Item:  39   Message mailing based on backup types
-Item:  40   Include JobID in spool file name
+Item:  40*  Include JobID in spool file name
 
 
 Item  1:  Accurate restoration of renamed/deleted files
@@ -82,7 +87,7 @@ Item  1:  Accurate restoration of renamed/deleted files
 Item  2:  Implement a Bacula GUI/management tool.
   Origin: Kern
   Date:   28 October 2005
-  Status:         
+  Status: In progress
 
   What:   Implement a Bacula console, and management tools
           probably using Qt3 and C++.
@@ -569,6 +574,7 @@ Item 17:  Restore only file attributes (permissions, ACL, owner, group...)
   Notes:  If the file is here, we skip restore and we change rights.
           If the file isn't here, we can create an empty one and apply
           rights or do nothing.
+
 Item 18:  Quick release of FD-SD connection after backup.
   Origin: Frank Volf (frank at deze dot org)
   Date:   17 November 2005
@@ -746,10 +752,12 @@ Status:
           backups, then the Full job would use the proper Storage device, which
           has more capacity (i.e. a 8TB tape library.
 
-Item 25:  Implement huge exclude list support using hashing.
+Item 25:  Implement huge exclude list support using hashing (dlists).
   Date:   28 October 2005
   Origin: Kern
-  Status: 
+  Status: Done in 2.1.2 but was done with dlists (doubly linked lists
+          since hashing will not help. The huge list also supports
+          large include lists).
 
   What:   Allow users to specify very large exclude list (currently
           more than about 1000 files is too many).
index eeae8ed4e5faf4385ead28c4c893a65b1b167479..87e4293277a7dc7b028db1a34dfac77f94422b49 100644 (file)
@@ -280,7 +280,7 @@ void catalog_request(JCR *jcr, BSOCK *bs)
       mr.VolWriteTime = sdmr.VolWriteTime;
       mr.VolParts     = sdmr.VolParts;
       bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
-      if (jcr->wstore->StorageId) {
+      if (jcr->wstore && jcr->wstore->StorageId) {
          mr.StorageId = jcr->wstore->StorageId;
       }
 
index 83d06fcaed41b4158ebf921ec2cda69a31febd32..b158ce2d1fd7eaeb74b64947bc03f465381d898f 100644 (file)
@@ -156,6 +156,10 @@ bool setup_job(JCR *jcr)
     * Create Job record
     */
    init_jcr_job_record(jcr);
+   if (!get_or_create_client_record(jcr)) {
+      goto bail_out;
+   }
+
    if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
       goto bail_out;
@@ -164,10 +168,6 @@ bool setup_job(JCR *jcr)
    Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
        jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
 
-   if (!get_or_create_client_record(jcr)) {
-      goto bail_out;
-   }
-
    generate_daemon_event(jcr, "JobStart");
 
    if (job_canceled(jcr)) {
@@ -554,7 +554,7 @@ static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
             jcr->JobStatus);
    }
    Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
-         cancel ? "" : "do not ", jcr, jcr->job);
+         cancel ? "" : "do not ", jcr, jcr->Job);
 #endif
    return cancel;
 }
@@ -602,7 +602,7 @@ static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
    }
 
    Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
-         cancel ? "" : "do not ", jcr, jcr->job);
+         cancel ? "" : "do not ", jcr, jcr->Job);
 #endif
    return true;
 }
@@ -886,6 +886,10 @@ void dird_free_jcr(JCR *jcr)
       db_close_database(jcr, jcr->db);
       jcr->db = NULL;
    }
+   if (jcr->db_batch) {
+      db_close_database(jcr, jcr->db_batch);
+      jcr->db_batch = NULL;
+   }
    if (jcr->stime) {
       Dmsg0(200, "Free JCR stime\n");
       free_pool_memory(jcr->stime);
index 84a25f4537c7d92eaea5334d5f5f2382a7181c7b..31d47dab9fcc072cbea02a61252da779c9827567 100644 (file)
@@ -302,7 +302,7 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
  * Start a thread to handle Storage daemon messages and
  *  Catalog requests.
  */
-int start_storage_daemon_message_thread(JCR *jcr)
+bool start_storage_daemon_message_thread(JCR *jcr)
 {
    int status;
    pthread_t thid;
@@ -318,9 +318,12 @@ int start_storage_daemon_message_thread(JCR *jcr)
    /* Wait for thread to start */
    while (jcr->SD_msg_chan == 0) {
       bmicrosleep(0, 50);
+      if (job_canceled(jcr) || jcr->sd_msg_thread_done) {
+         return false;
+      }
    }
    Dmsg1(100, "SD msg_thread started. use=%d\n", jcr->use_count());
-   return 1;
+   return true;
 }
 
 extern "C" void msg_thread_cleanup(void *arg)
index fcdaa11d4c8a1b8b52a05433d50c331e31fef497..fa0b88d737a4d9ed50252844c9f6f411d4294026 100644 (file)
@@ -141,7 +141,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
 extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
                               int max_retry_time, int verbose);
 extern bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore);
-extern int start_storage_daemon_message_thread(JCR *jcr);
+extern bool start_storage_daemon_message_thread(JCR *jcr);
 extern int bget_dirmsg(BSOCK *bs);
 extern void wait_for_storage_daemon_termination(JCR *jcr);
 
@@ -195,9 +195,12 @@ bool is_volume_name_legal(UAContext *ua, const char *name);
 int get_num_drives_from_SD(UAContext *ua);
 void update_slots(UAContext *ua);
 
+/* ua_update.c */
+void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr);
+
 /* ua_output.c */
 void prtit(void *ctx, const char *msg);
-int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool);
+bool complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool);
 RUN *find_next_run(RUN *run, JOB *job, time_t &runtime, int ndays);
 
 /* ua_restore.c */
index 268e5158b27f7d02544dcb77bcea7216d6dc6e92..93b3357d33b8bcd40f304e7587cb539769205e9c 100644 (file)
@@ -384,10 +384,6 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
    JCR *jcr = NULL;
    char JobName[MAX_NAME_LENGTH];
 
-   if (!open_client_db(ua)) {
-      return 1;
-   }
-
    for (i=1; i<ua->argc; i++) {
       if (strcasecmp(ua->argk[i], NT_("jobid")) == 0) {
          uint32_t JobId;
@@ -434,28 +430,38 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       *   throw up a list and ask the user to select one.
       */
       char buf[1000];
+      int tjobs = 0;                  /* total # number jobs */
       /* Count Jobs running */
       foreach_jcr(jcr) {
          if (jcr->JobId == 0) {      /* this is us */
             continue;
          }
+         tjobs++;                    /* count of all jobs */
          if (!acl_access_ok(ua, Job_ACL, jcr->job->name())) {
             continue;               /* skip not authorized */
          }
-         njobs++;
+         njobs++;                   /* count of authorized jobs */
       }
       endeach_jcr(jcr);
 
-      if (njobs == 0) {
-         bsendmsg(ua, _("No Jobs running.\n"));
+      if (njobs == 0) {            /* no authorized */
+         if (tjobs == 0) {
+            bsendmsg(ua, _("No Jobs running.\n"));
+         } else {
+            bsendmsg(ua, _("None of your jobs are running.\n"));
+         }
          return 1;
       }
+
       start_prompt(ua, _("Select Job:\n"));
       foreach_jcr(jcr) {
          char ed1[50];
          if (jcr->JobId == 0) {      /* this is us */
             continue;
          }
+         if (!acl_access_ok(ua, Job_ACL, jcr->job->name())) {
+            continue;               /* skip not authorized */
+         }
          bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job);
          add_prompt(ua, buf);
       }
@@ -472,7 +478,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
       jcr = get_jcr_by_full_name(JobName);
       if (!jcr) {
-         bsendmsg(ua, _("Job %s not found.\n"), JobName);
+         bsendmsg(ua, _("Job \"%s\" not found.\n"), JobName);
          return 1;
       }
    }
index 5f050468700e56177a8b0bc209b3336e8fbe406c..3d03199f12437164706f76732cf634acb14cef33 100644 (file)
@@ -1,16 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Output Commands
- *     I.e. messages, listing database, showing resources, ...
- *
- *     Kern Sibbald, September MM
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- User Agent Output Commands
+ *     I.e. messages, listing database, showing resources, ...
+ *
+ *     Kern Sibbald, September MM
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 #include "dird.h"
@@ -602,7 +602,7 @@ RUN *find_next_run(RUN *run, JOB *job, time_t &runtime, int ndays)
  * Fill in the remaining fields of the jcr as if it
  *  is going to run the job.
  */
-int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
+bool complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
 {
    POOL_DBR pr;
 
@@ -611,6 +611,10 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
    if (pool) {
       jcr->pool = pool;               /* override */
    }
+   if (jcr->db) {
+      db_close_database(jcr, jcr->db);
+      jcr->db = NULL;
+   }
    jcr->db = jcr->db=db_init_database(jcr, jcr->catalog->db_name, jcr->catalog->db_user,
                       jcr->catalog->db_password, jcr->catalog->db_address,
                       jcr->catalog->db_port, jcr->catalog->db_socket,
@@ -620,8 +624,10 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
                  jcr->catalog->db_name);
       if (jcr->db) {
          Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+         db_close_database(jcr, jcr->db);
+         jcr->db = NULL;
       }
-      return 0;
+      return false;
    }
    bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name));
    while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
@@ -633,13 +639,13 @@ int complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool)
             db_close_database(jcr, jcr->db);
             jcr->db = NULL;
          }
-         return 0;
+         return false;
       } else {
          Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
       }
    }
    jcr->jr.PoolId = pr.PoolId;
-   return 1;
+   return true;
 }
 
 
index 2da4d56a2edc8992e97c8b1646b561eaa0e60e6b..b5fa59f5375030781b8d6d086a928f73ba9be697 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Status Command
- *
- *     Kern Sibbald, August MMI
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   Bacula Director -- User Agent Status Command
+ *
+ *     Kern Sibbald, August MMI
+ *
+ *   Version $Id$
+ */
 
 
 #include "bacula.h"
@@ -100,9 +100,6 @@ int status_cmd(UAContext *ua, const char *cmd)
    CLIENT *client;
    int item, i;
 
-   if (!open_client_db(ua)) {
-      return 1;
-   }
    Dmsg1(20, "status:%s:\n", cmd);
 
    for (i=1; i<ua->argc; i++) {
index 5e2688c38dd5d20cec84775d199c452e08ad5ed7..e81d67bfea869d4ffc5aba10e31ef1f0ef6e0a38 100644 (file)
@@ -290,7 +290,7 @@ static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
 }
 
 /* Modify the Pool in which this Volume is located */
-static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
+void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
 {
    POOL_DBR pr;
    POOLMEM *query;
index 0997fb6fb42183f1122139a066267f46b2ecf577..674cdd8c58bc2214c5e3019916e2aac68b511577 100644 (file)
@@ -756,7 +756,7 @@ static int missing_handler(void *ctx, int num_fields, char **row)
    }
    if (!jcr->fn_printed) {
       Jmsg(jcr, M_INFO, 0, "\n");
-      Jmsg(jcr, M_INFO, 0, _("The following files are missing:\n"));
+      Jmsg(jcr, M_INFO, 0, _("The following files are in the Catalog but not on disk:\n"));
       jcr->fn_printed = true;
    }
    Jmsg(jcr, M_INFO, 0, "      %s%s\n", row[0]?row[0]:"", row[1]?row[1]:"");
index 51f8afcedce64bc32f294a4a7799a7fbbdc4b42c..d1b4ea607ba41552d92c34bbd47cd3d190ba43fb 100644 (file)
@@ -244,16 +244,14 @@ void *handle_client_request(void *dirp)
       }
    }
 
-   if (!jcr->runscript_after) {
-      jcr->runscript_after=1;
-      run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
-   }
-
    /* Inform Storage daemon that we are done */
    if (jcr->store_bsock) {
       bnet_sig(jcr->store_bsock, BNET_TERMINATE);
    }
 
+   /* Run the after job */
+   run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
+
    generate_daemon_event(jcr, "JobEnd");
 
    dequeue_messages(jcr);             /* send any queued messages */
@@ -1387,17 +1385,9 @@ static int backup_cmd(JCR *jcr)
       bnet_suppress_error_messages(sd, 1);
       bget_msg(sd);                   /* Read final response from append_data */
       Dmsg0(110, "Error in blast_data.\n");
-      /* run shortly after end of data transmission */ 
-      run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
-      jcr->runscript_after=1;
-
    } else {
       set_jcr_job_status(jcr, JS_Terminated);
 
-      /* run shortly after end of data transmission */   
-      run_scripts(jcr, jcr->RunScripts, "ClientAfterJob");
-      jcr->runscript_after=1;
-
       if (jcr->JobStatus != JS_Terminated) {
          bnet_suppress_error_messages(sd, 1);
          goto cleanup;                /* bail out now */
index 14a667106db7d4c38de28f1b46615912b05b8dd8..86403d533f7c2294a59fb952b162d7092bbd4b36 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *  Bacula File Daemon  verify.c  Verify files.
- *
- *    Kern Sibbald, October MM
- *
- *   Version $Id$
- *
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *  Bacula File Daemon  verify.c  Verify files.
+ *
+ *    Kern Sibbald, October MM
+ *
+ *   Version $Id$
+ *
+ */
 
 #include "bacula.h"
 #include "filed.h"
@@ -102,6 +102,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level)
       Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
       break;
    case FT_DIRBEGIN:
+      jcr->num_files_examined--;      /* correct file count */
       return 1;                       /* ignored */
    case FT_DIREND:
       Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname);
@@ -145,7 +146,8 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level)
       return 1;
    case FT_NORECURSE:
       Jmsg(jcr, M_SKIPPED, 1, _("     Recursion turned off. Directory skipped: %s\n"), ff_pkt->fname);
-      return 1;
+      ff_pkt->type = FT_DIREND;     /* directory entry was backed up */
+      break;
    case FT_NOFSCHG:
       Jmsg(jcr, M_SKIPPED, 1, _("     File system change prohibited. Directory skipped: %s\n"), ff_pkt->fname);
       return 1;
index cb3cb885f0c07ec093df9415b77f1f2a83794e23..ff06afc9b2c6e567704ef8652a175e57973c751f 100644 (file)
@@ -184,6 +184,7 @@ public:
    bool cached_attribute;             /* set if attribute is cached */
    POOLMEM *attr;                     /* Attribute string from SD */
    B_DB *db;                          /* database pointer */
+   B_DB *db_batch;                    /* database pointer for batch insert */
    ATTR_DBR *ar;                      /* DB attribute record */
 
    /* Daemon specific part of JCR */
@@ -294,7 +295,6 @@ public:
    int32_t pki_session_encoded_size;  /* Size of DER-encoded pki_session */
    POOLMEM *crypto_buf;               /* Encryption/Decryption buffer */
    DIRRES* director;                  /* Director resource */
-   bool runscript_after;              /* Don't run After Script twice */
 #endif /* FILE_DAEMON */
 
 
index 69c8fa204974dcca0a62544272b6460269abbe2d..e59bea24e6fb0c289c522e20e71d7d66424cca6e 100644 (file)
@@ -463,8 +463,8 @@ bool release_device(DCR *dcr)
 
    if (dev->can_read()) {
       dev->clear_read();              /* clear read bit */
-
-      /******FIXME**** send read volume usage statistics to director */
+      Dmsg0(100, "dir_update_vol_info. Release0\n");
+//    dir_update_volume_info(dcr, false); /* send Volume info to Director */
 
    } else if (dev->num_writers > 0) {
       /* 
index 6a57c14b47cf0ddf5a8dc8d1533f629e0ef20af6..402324fa4da84a091367f77c2d09deef69ead8fd 100644 (file)
@@ -7,7 +7,7 @@
 /*
    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.
@@ -38,6 +38,7 @@
 
 /* Responses sent to the File daemon */
 static char OK_data[]    = "3000 OK data\n";
+static char OK_append[]  = "3000 OK append data\n";
 
 /* Forward referenced functions */
 
@@ -261,6 +262,14 @@ bool do_append_data(JCR *jcr)
       }
    }
 
+   /* Create Job status for end of session label */
+   set_jcr_job_status(jcr, ok?JS_Terminated:JS_ErrorTerminated);
+
+   /* Terminate connection with FD */
+   bnet_fsend(ds, OK_append);
+   do_fd_commands(jcr);               /* finish dialog with FD */
+
+
    time_t job_elapsed = time(NULL) - jcr->run_time;
 
    if (job_elapsed <= 0) {
@@ -271,8 +280,6 @@ bool do_append_data(JCR *jcr)
          job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
          edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec));
 
-   /* Create Job status for end of session label */
-   set_jcr_job_status(jcr, ok?JS_Terminated:JS_ErrorTerminated);
 
    Dmsg1(200, "Write EOS label JobStatus=%c\n", jcr->JobStatus);
 
@@ -303,6 +310,8 @@ bool do_append_data(JCR *jcr)
       Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
    }
 
+
+
    if (!ok) {
       discard_data_spool(dcr);
    } else {
index 47306f20b59e393351ea2d099435276a5e7ca1fa..63c163ff0073af537aba9493f9f933275eece4fe 100644 (file)
@@ -15,7 +15,7 @@
 /*
    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.
@@ -95,7 +95,6 @@ static char NOT_opened[]      = "3902 Error session not opened\n";
 static char OK_end[]          = "3000 OK end\n";
 static char OK_close[]        = "3000 OK close Status = %d\n";
 static char OK_open[]         = "3000 OK open ticket = %d\n";
-static char OK_append[]       = "3000 OK append data\n";
 static char ERROR_append[]    = "3903 Error append data\n";
 static char OK_bootstrap[]    = "3000 OK bootstrap\n";
 static char ERROR_bootstrap[] = "3904 Error bootstrap\n";
@@ -107,6 +106,7 @@ char Job_end[]   =
 
 /*
  * Run a File daemon Job -- File daemon already authorized
+ *  Director sends us this command.
  *
  * Basic task here is:
  * - Read a command from the File daemon
@@ -115,14 +115,9 @@ char Job_end[]   =
  */
 void run_job(JCR *jcr)
 {
-   int i;
-   bool found, quit;
-   BSOCK *fd = jcr->file_bsock;
    BSOCK *dir = jcr->dir_bsock;
    char ec1[30];
 
-
-   fd->jcr = jcr;
    dir->jcr = jcr;
    Dmsg1(120, "Start run Job=%s\n", jcr->Job);
    bnet_fsend(dir, Job_start, jcr->Job);
@@ -130,6 +125,27 @@ void run_job(JCR *jcr)
    jcr->run_time = jcr->start_time;
    set_jcr_job_status(jcr, JS_Running);
    dir_send_job_status(jcr);          /* update director */
+   do_fd_commands(jcr);
+   jcr->end_time = time(NULL);
+   dequeue_messages(jcr);             /* send any queued messages */
+   set_jcr_job_status(jcr, JS_Terminated);
+   generate_daemon_event(jcr, "JobEnd");
+   bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
+      edit_uint64(jcr->JobBytes, ec1));
+   bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
+   return;
+}
+
+/*
+ * Now talk to the FD and do what he says
+ */
+void do_fd_commands(JCR *jcr)
+{
+   int i;
+   bool found, quit;
+   BSOCK *fd = jcr->file_bsock;
+
+   fd->jcr = jcr;
    for (quit=false; !quit;) {
       int stat;
 
@@ -160,17 +176,8 @@ void run_job(JCR *jcr)
       }
    }
    bnet_sig(fd, BNET_TERMINATE);      /* signal to FD job is done */
-   jcr->end_time = time(NULL);
-   dequeue_messages(jcr);             /* send any queued messages */
-   set_jcr_job_status(jcr, JS_Terminated);
-   generate_daemon_event(jcr, "JobEnd");
-   bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
-      edit_uint64(jcr->JobBytes, ec1));
-   bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
-   return;
 }
 
-
 /*
  *   Append Data command
  *     Open Data Channel and receive Data for archiving
@@ -185,7 +192,7 @@ static bool append_data_cmd(JCR *jcr)
       Dmsg1(110, "<bfiled: %s", fd->msg);
       jcr->JobType = JT_BACKUP;
       if (do_append_data(jcr)) {
-         return bnet_fsend(fd, OK_append);
+         return true;
       } else {
          bnet_suppress_error_messages(fd, 1); /* ignore errors at this point */
          bnet_fsend(fd, ERROR_append);
index 2e3bbdf3a84ede3ba5b3f3adb9398c6ec207f15b..3b8388e7a58e76afb419130f0e72bd00051ae16b 100644 (file)
@@ -6,7 +6,7 @@
 /*
    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.
@@ -144,7 +144,8 @@ void     *handle_connection_request(void *arg);
 
 /* From fd_cmds.c */
 void     run_job(JCR *jcr);
-bool get_bootstrap_file(JCR *jcr, BSOCK *bsock);
+bool     get_bootstrap_file(JCR *jcr, BSOCK *bsock);
+void     do_fd_commands(JCR *jcr);
 
 /* From job.c */
 void     stored_free_jcr(JCR *jcr);
index e51c72c40364592295036dfce0f6d955fe7e7ad8..4e5eee8aabbf7133e8bbe443f480aea9fd551992 100644 (file)
@@ -702,135 +702,155 @@ static void eliminate_duplicate_paths()
 
 static void eliminate_orphaned_jobmedia_records()
 {
-   const char *query;
+   const char *query = "SELECT JobMedia.JobMediaId,Job.JobId FROM JobMedia "
+                "LEFT OUTER JOIN Job ON (JobMedia.JobId=Job.JobId) "
+                "WHERE Job.JobId IS NULL LIMIT 300000";
 
    printf(_("Checking for orphaned JobMedia entries.\n"));
-   query = "SELECT JobMedia.JobMediaId,Job.JobId FROM JobMedia "
-           "LEFT OUTER JOIN Job ON (JobMedia.JobId=Job.JobId) "
-           "WHERE Job.JobId IS NULL";
    if (!make_id_list(query, &id_list)) {
       exit(1);
    }
-   printf(_("Found %d orphaned JobMedia records.\n"), id_list.num_ids);
-   if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-      for (int i=0; i < id_list.num_ids; i++) {
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf),
+   /* Loop doing 300000 at a time */
+   while (id_list.num_ids != 0) {
+      printf(_("Found %d orphaned JobMedia records.\n"), id_list.num_ids);
+      if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
+         for (int i=0; i < id_list.num_ids; i++) {
+            char ed1[50];
+            bsnprintf(buf, sizeof(buf),
 "SELECT JobMedia.JobMediaId,JobMedia.JobId,Media.VolumeName FROM JobMedia,Media "
 "WHERE JobMedia.JobMediaId=%s AND Media.MediaId=JobMedia.MediaId", 
-            edit_int64(id_list.Id[i], ed1));
-         if (!db_sql_query(db, buf, print_jobmedia_handler, NULL)) {
-            printf("%s\n", db_strerror(db));
+               edit_int64(id_list.Id[i], ed1));
+            if (!db_sql_query(db, buf, print_jobmedia_handler, NULL)) {
+               printf("%s\n", db_strerror(db));
+            }
          }
       }
-   }
-   if (quit) {
-      return;
-   }
+      if (quit) {
+         return;
+      }
 
-   if (fix && id_list.num_ids > 0) {
-      printf(_("Deleting %d orphaned JobMedia records.\n"), id_list.num_ids);
-      delete_id_list("DELETE FROM JobMedia WHERE JobMediaId=%s", &id_list);
+      if (fix && id_list.num_ids > 0) {
+         printf(_("Deleting %d orphaned JobMedia records.\n"), id_list.num_ids);
+         delete_id_list("DELETE FROM JobMedia WHERE JobMediaId=%s", &id_list);
+      }
+      if (!make_id_list(query, &id_list)) {
+         exit(1);
+      }
    }
 }
 
 static void eliminate_orphaned_file_records()
 {
-   const char *query;
+   const char *query = "SELECT File.FileId,Job.JobId FROM File "
+                "LEFT OUTER JOIN Job ON (File.JobId=Job.JobId) "
+               "WHERE Job.JobId IS NULL LIMIT 300000";
 
    printf(_("Checking for orphaned File entries. This may take some time!\n"));
-   query = "SELECT File.FileId,Job.JobId FROM File "
-           "LEFT OUTER JOIN Job ON (File.JobId=Job.JobId) "
-           "WHERE Job.JobId IS NULL";
    if (verbose > 1) {
       printf("%s\n", query);
    }
    if (!make_id_list(query, &id_list)) {
       exit(1);
    }
-   printf(_("Found %d orphaned File records.\n"), id_list.num_ids);
-   if (name_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-      for (int i=0; i < id_list.num_ids; i++) {
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf),
+   /* Loop doing 300000 at a time */
+   while (id_list.num_ids != 0) {
+      printf(_("Found %d orphaned File records.\n"), id_list.num_ids);
+      if (name_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
+         for (int i=0; i < id_list.num_ids; i++) {
+            char ed1[50];
+            bsnprintf(buf, sizeof(buf),
 "SELECT File.FileId,File.JobId,Filename.Name FROM File,Filename "
 "WHERE File.FileId=%s AND File.FilenameId=Filename.FilenameId", 
-            edit_int64(id_list.Id[i], ed1));
-         if (!db_sql_query(db, buf, print_file_handler, NULL)) {
-            printf("%s\n", db_strerror(db));
+               edit_int64(id_list.Id[i], ed1));
+            if (!db_sql_query(db, buf, print_file_handler, NULL)) {
+               printf("%s\n", db_strerror(db));
+            }
          }
       }
-   }
-   if (quit) {
-      return;
-   }
-   if (fix && id_list.num_ids > 0) {
-      printf(_("Deleting %d orphaned File records.\n"), id_list.num_ids);
-      delete_id_list("DELETE FROM File WHERE FileId=%s", &id_list);
+      if (quit) {
+         return;
+      }
+      if (fix && id_list.num_ids > 0) {
+         printf(_("Deleting %d orphaned File records.\n"), id_list.num_ids);
+         delete_id_list("DELETE FROM File WHERE FileId=%s", &id_list);
+      }
+      if (!make_id_list(query, &id_list)) {
+         exit(1);
+      }
    }
 }
 
 static void eliminate_orphaned_path_records()
 {
-   const char *query;
+   const char *query = "SELECT DISTINCT Path.PathId,File.PathId FROM Path "
+               "LEFT OUTER JOIN File ON (Path.PathId=File.PathId) "
+               "WHERE File.PathId IS NULL LIMIT 300000";
 
    printf(_("Checking for orphaned Path entries. This may take some time!\n"));
-   query = "SELECT DISTINCT Path.PathId,File.PathId FROM Path "
-           "LEFT OUTER JOIN File ON (Path.PathId=File.PathId) "
-           "WHERE File.PathId IS NULL";
    if (verbose > 1) {
       printf("%s\n", query);
    }
    if (!make_id_list(query, &id_list)) {
       exit(1);
    }
-   printf(_("Found %d orphaned Path records.\n"), id_list.num_ids);
-   if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-      for (int i=0; i < id_list.num_ids; i++) {
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf), "SELECT Path FROM Path WHERE PathId=%s", 
-            edit_int64(id_list.Id[i], ed1));
-         db_sql_query(db, buf, print_name_handler, NULL);
+   /* Loop doing 300000 at a time */
+   while (id_list.num_ids != 0) {
+      printf(_("Found %d orphaned Path records.\n"), id_list.num_ids);
+      if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
+         for (int i=0; i < id_list.num_ids; i++) {
+            char ed1[50];
+            bsnprintf(buf, sizeof(buf), "SELECT Path FROM Path WHERE PathId=%s", 
+               edit_int64(id_list.Id[i], ed1));
+            db_sql_query(db, buf, print_name_handler, NULL);
+         }
+      }
+      if (quit) {
+         return;
+      }
+      if (fix && id_list.num_ids > 0) {
+         printf(_("Deleting %d orphaned Path records.\n"), id_list.num_ids);
+         delete_id_list("DELETE FROM Path WHERE PathId=%s", &id_list);
+      }
+      if (!make_id_list(query, &id_list)) {
+         exit(1);
       }
-   }
-   if (quit) {
-      return;
-   }
-   if (fix && id_list.num_ids > 0) {
-      printf(_("Deleting %d orphaned Path records.\n"), id_list.num_ids);
-      delete_id_list("DELETE FROM Path WHERE PathId=%s", &id_list);
    }
 }
 
 static void eliminate_orphaned_filename_records()
 {
-   const char *query;
+   const char *query = "SELECT Filename.FilenameId,File.FilenameId FROM Filename "
+                "LEFT OUTER JOIN File ON (Filename.FilenameId=File.FilenameId) "
+                "WHERE File.FilenameId IS NULL LIMIT 300000";
 
    printf(_("Checking for orphaned Filename entries. This may take some time!\n"));
-   query = "SELECT Filename.FilenameId,File.FilenameId FROM Filename "
-           "LEFT OUTER JOIN File ON (Filename.FilenameId=File.FilenameId) "
-           "WHERE File.FilenameId IS NULL";
    if (verbose > 1) {
       printf("%s\n", query);
    }
    if (!make_id_list(query, &id_list)) {
       exit(1);
    }
-   printf(_("Found %d orphaned Filename records.\n"), id_list.num_ids);
-   if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-      for (int i=0; i < id_list.num_ids; i++) {
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", 
-            edit_int64(id_list.Id[i], ed1));
-         db_sql_query(db, buf, print_name_handler, NULL);
+   /* Loop doing 300000 at a time */
+   while (id_list.num_ids != 0) {
+      printf(_("Found %d orphaned Filename records.\n"), id_list.num_ids);
+      if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
+         for (int i=0; i < id_list.num_ids; i++) {
+            char ed1[50];
+            bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", 
+               edit_int64(id_list.Id[i], ed1));
+            db_sql_query(db, buf, print_name_handler, NULL);
+         }
+      }
+      if (quit) {
+         return;
+      }
+      if (fix && id_list.num_ids > 0) {
+         printf(_("Deleting %d orphaned Filename records.\n"), id_list.num_ids);
+         delete_id_list("DELETE FROM Filename WHERE FilenameId=%s", &id_list);
+      }
+      if (!make_id_list(query, &id_list)) {
+         exit(1);
       }
-   }
-   if (quit) {
-      return;
-   }
-   if (fix && id_list.num_ids > 0) {
-      printf(_("Deleting %d orphaned Filename records.\n"), id_list.num_ids);
-      delete_id_list("DELETE FROM Filename WHERE FilenameId=%s", &id_list);
    }
 }
 
index b6db5b3f36b911d3e58d81abd44b3e7882966208..12815331444fbd358c564562e66f1ad142670b7a 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.0.3"
-#define BDATE   "06 February 2007"
-#define LSMDATE "06Feb07"
+#define BDATE   "15 February 2007"
+#define LSMDATE "15Feb07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
 
 #define USE_BSNPRINTF 1
 
-/* Disk file seeking is now controled by CAP_POSITIONBLOCKS */
+/* Turn on the following flag to enable batch attribute inserts
+ *  in the catalog.  This gives a large speedup.
+ */
+/* #define HAVE_BATCH_FILE_INSERT 1 */
+
 
 /* Debug flags not normally turned on */
 
index afaca2d1c8d31e67b9bdb143274d36fe07f709ee..54260b80d6b7a87f25429ab34ed4973b50a56da8 100644 (file)
@@ -1,6 +1,25 @@
               Technical notes on version 2.0
 
 General:
+15Feb07
+kes  Add quick disconnect FD code from 2.1.4 to 2.0.3.  This code
+     causes the SD to release the FD as soon as the FD has sent
+     all the data to the SD. After that the SD will do any final
+     despooling (data and attributes) that are necessary. This
+     allows laptops to disconnect much quicker from the network 
+     after a backup.
+13Feb07
+kes  Apply Eric's ClientRunScriptAfter patch to 2.0 and 2.1.
+11Feb07
+kes  Optimize the use of the database a bit in the Status dir command.
+     Only open it when needed, ensure that if any previous database
+     was opened, it is closed.
+10Feb07
+kes  Modify dbcheck to handle orphaned JobMedia, Path, Filename,
+     and File records in 300K chunks to be more efficient. This
+     idea came from Juan Luis Frances (if I remember right).
+09Feb07
+kes  Update projects list.
 08Feb07
 kes  Fix dird/ua_cmds.c so that a cancel command checks if the
      console is authorized to cancel the job.  This fixes bug 
@@ -46,6 +65,9 @@ kes  Fix a bug in the btree.c and btree.h routines, then rename them
      rblist and add them to be built in src/lib.  Include some new
      methods written by Rudolf Cejka that make the code more readable
      (hides some of the ugly casting).
+26Jan07 (back port)
+kes  Implement item #12 on project list -- quick release of FD by
+     the SD. This is noted in more detail above.
 
 Version 2.0.2 released: 30 January 2007
 28Jan08