[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bacula-devel] Patch: kernstodo line 921 :-)


Summary/reminder: a patch to update the state file whenever a job terminates,
rather than when the dir/sd/fd exits.

Kern Sibbald wrote:
On Wednesday 22 August 2007 22:07, Allan Black wrote:
Kern Sibbald wrote:
As it stands, the current patch that you have submitted will not work
correctly since two threads can be terminating at the same time, and the
write_state_file() code is not thread safe.   You can probably correct it
by moving the jcr chain lock.
OK.

That is exactly what I have done.

In addition, as you note, you need to do
something so that the state file is not updated more frequently than
really necessary.

Done. As you suggested, I had to check that jcr->JobId was non-zero.

By the way, the best way to provide a patch is to send a single patch file that is generated by:

  svn checkout ... (see developers guide for exact syntax)
  (make your changes ...)
  (test ...)
   svn update
   (correct any eventual conflicts ...)
   svn diff >state-file.patch
   (look at state-file.patch to ensure it is correct, complete and
    doesn't have any extra "garbage", but don't change it)
   (send state-file.patch ...)

I have been running 2.2.5 since October with this code in place. The attached
patch was generated (and tested) against the SVN trunk, though.

Allan
Index: src/dird/job.c
===================================================================
--- src/dird/job.c	(revision 6353)
+++ src/dird/job.c	(working copy)
@@ -891,6 +891,10 @@
    free_rwstorage(jcr);
 
    jcr->job_end_push.destroy();
+
+   if (jcr->JobId != 0)
+      write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
+
    Dmsg0(200, "End dird free_jcr\n");
 }
 
Index: src/filed/job.c
===================================================================
--- src/filed/job.c	(revision 6353)
+++ src/filed/job.c	(working copy)
@@ -1774,6 +1774,9 @@
    free_runscripts(jcr->RunScripts);
    delete jcr->RunScripts;
 
+   if (jcr->JobId != 0)
+      write_state_file(me->working_directory, "bacula-fd", get_first_port_host_order(me->FDaddrs));
+
    return;
 }
 
Index: src/stored/job.c
===================================================================
--- src/stored/job.c	(revision 6353)
+++ src/stored/job.c	(working copy)
@@ -406,5 +406,9 @@
       jcr->write_store = NULL;
    }
    Dsm_check(1);
+
+   if (jcr->JobId != 0)
+      write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
+
    return;
 }
Index: src/lib/jcr.c
===================================================================
--- src/lib/jcr.c	(revision 6353)
+++ src/lib/jcr.c	(working copy)
@@ -336,47 +336,6 @@
  */
 static void free_common_jcr(JCR *jcr)
 {
-   struct s_last_job *je, last_job;
-
-   /* Keep some statistics */
-   switch (jcr->JobType) {
-   case JT_BACKUP:
-   case JT_VERIFY:
-   case JT_RESTORE:
-   case JT_MIGRATE:
-   case JT_COPY:
-   case JT_ADMIN:
-      num_jobs_run++;
-      last_job.Errors = jcr->Errors;
-      last_job.JobType = jcr->JobType;
-      last_job.JobId = jcr->JobId;
-      last_job.VolSessionId = jcr->VolSessionId;
-      last_job.VolSessionTime = jcr->VolSessionTime;
-      bstrncpy(last_job.Job, jcr->Job, sizeof(last_job.Job));
-      last_job.JobFiles = jcr->JobFiles;
-      last_job.JobBytes = jcr->JobBytes;
-      last_job.JobStatus = jcr->JobStatus;
-      last_job.JobLevel = jcr->JobLevel;
-      last_job.start_time = jcr->start_time;
-      last_job.end_time = time(NULL);
-      /* Keep list of last jobs, but not Console where JobId==0 */
-      if (last_job.JobId > 0) {
-         je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
-         memcpy((char *)je, (char *)&last_job, sizeof(last_job));
-         if (!last_jobs) {
-            init_last_jobs_list();
-         }
-         last_jobs->append(je);
-         if (last_jobs->size() > max_last_jobs) {
-            je = (struct s_last_job *)last_jobs->first();
-            last_jobs->remove(je);
-            free(je);
-         }
-      }
-      break;
-   default:
-      break;
-   }
    jcr->destroy_mutex();
 
    if (jcr->msg_queue) {
@@ -446,12 +405,15 @@
 #ifdef DEBUG
 void b_free_jcr(const char *file, int line, JCR *jcr)
 {
+   struct s_last_job *je, last_job;
+
    Dmsg3(dbglvl, "Enter free_jcr jid=%u from %s:%d\n", jcr->JobId, file, line);
 
 #else
 
 void free_jcr(JCR *jcr)
 {
+   struct s_last_job *je, last_job;
 
    Dmsg3(dbglvl, "Enter free_jcr jid=%u use_count=%d Job=%s\n", 
          jcr->JobId, jcr->use_count(), jcr->Job);
@@ -478,14 +440,56 @@
             jcr->JobId, jcr->use_count(), jcr->Job);
    }
    remove_jcr(jcr);                   /* remove Jcr from chain */
-   unlock_jcr_chain();
 
    job_end_pop(jcr);                  /* pop and call hooked routines */
 
    Dmsg1(dbglvl, "End job=%d\n", jcr->JobId);
+
+   /* Keep some statistics */
+   switch (jcr->JobType) {
+   case JT_BACKUP:
+   case JT_VERIFY:
+   case JT_RESTORE:
+   case JT_MIGRATE:
+   case JT_COPY:
+   case JT_ADMIN:
+      num_jobs_run++;
+      last_job.Errors = jcr->Errors;
+      last_job.JobType = jcr->JobType;
+      last_job.JobId = jcr->JobId;
+      last_job.VolSessionId = jcr->VolSessionId;
+      last_job.VolSessionTime = jcr->VolSessionTime;
+      bstrncpy(last_job.Job, jcr->Job, sizeof(last_job.Job));
+      last_job.JobFiles = jcr->JobFiles;
+      last_job.JobBytes = jcr->JobBytes;
+      last_job.JobStatus = jcr->JobStatus;
+      last_job.JobLevel = jcr->JobLevel;
+      last_job.start_time = jcr->start_time;
+      last_job.end_time = time(NULL);
+      /* Keep list of last jobs, but not Console where JobId==0 */
+      if (last_job.JobId > 0) {
+         je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
+         memcpy((char *)je, (char *)&last_job, sizeof(last_job));
+         if (!last_jobs) {
+            init_last_jobs_list();
+         }
+         last_jobs->append(je);
+         if (last_jobs->size() > max_last_jobs) {
+            je = (struct s_last_job *)last_jobs->first();
+            last_jobs->remove(je);
+            free(je);
+         }
+      }
+      break;
+   default:
+      break;
+
+   }
    if (jcr->daemon_free_jcr) {
       jcr->daemon_free_jcr(jcr);      /* call daemon free routine */
    }
+
+   unlock_jcr_chain();
    free_common_jcr(jcr);
    close_msg(NULL);                   /* flush any daemon messages */
    garbage_collect_memory_pool();
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-devel mailing list
Bacula-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/bacula-devel


This mailing list archive is a service of Copilotco.