]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/2.4.3-cancel-after-network-outage.patch
ebl Add patch
[bacula/bacula] / bacula / patches / 2.4.3-cancel-after-network-outage.patch
1
2   This patch fixes a problem when canceling job if client looses 
3   connection while being backed up 
4   Apply the patch to version 2.4.3 (and previous versions) with:
5
6   cd <bacula-source>
7   patch -p0 <2.4.3-cancel-after-network-outage.patch
8   ./configure <your-options>
9   make
10   ...
11   make install
12
13
14 Index: src/dird/backup.c
15 ===================================================================
16 --- src/dird/backup.c   (rĂ©vision 7772)
17 +++ src/dird/backup.c   (copie de travail)
18 @@ -240,14 +240,16 @@
19     }     
20     return false;
21  
22 -/* Come here only after starting SD thread */
23 +/* Come here only after starting SD thread 
24 + * and we don't expect any EndJob message because the
25 + * the client don't have recieve the "backup" command.
26 + */
27  bail_out:
28     set_jcr_job_status(jcr, JS_ErrorTerminated);
29 -   Dmsg1(400, "wait for sd. use=%d\n", jcr->use_count());
30 -   /* Cancel SD */
31 -   cancel_storage_daemon_job(jcr);
32 -   wait_for_storage_daemon_termination(jcr);
33 -   Dmsg1(400, "after wait for sd. use=%d\n", jcr->use_count());
34 +   Dmsg1(400, "wait for sd and fd. use=%d\n", jcr->use_count());
35 +   /* Get status from SD and FD */
36 +   wait_for_job_termination(jcr, false /* don't expect EndJob message*/);
37 +   Dmsg1(400, "after wait for sd and fd. use=%d\n", jcr->use_count());
38     return false;
39  }
40  
41 @@ -258,7 +260,7 @@
42   *   are done, we return the job status.
43   * Also used by restore.c
44   */
45 -int wait_for_job_termination(JCR *jcr)
46 +int wait_for_job_termination(JCR *jcr, bool expect_EndJob)
47  {
48     int32_t n = 0;
49     BSOCK *fd = jcr->file_bsock;
50 @@ -270,30 +272,51 @@
51     int Encrypt = 0;
52  
53     set_jcr_job_status(jcr, JS_Running);
54 -   /* Wait for Client to terminate */
55 -   while ((n = bget_dirmsg(fd)) >= 0) {
56 -      if (!fd_ok && 
57 -          (sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
58 -              &ReadBytes, &JobBytes, &Errors, &VSS, &Encrypt) == 7 ||
59 -           sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
60 -                 &ReadBytes, &JobBytes, &Errors) == 5)) {
61 -         fd_ok = true;
62 -         set_jcr_job_status(jcr, jcr->FDJobStatus);
63 -         Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
64 -      } else {
65 -         Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
66 -            fd->msg);
67 +
68 +
69 +   if (fd) {
70 +      /* Wait for Client to terminate 
71 +       * In some conditions, the client isn't able to send
72 +       * any messages and we should not wait for ages
73 +       */
74 +      int OK=true;
75 +      int ret;
76 +      while (OK && expect_EndJob) {
77 +
78 +         /* Even if the job is canceled, we let a chance to FD to 
79 +          * send EndJob message 
80 +          */
81 +         if (job_canceled(jcr)) { 
82 +            OK=false;
83 +         }
84 +         
85 +         /* wait for data few minutes */
86 +         ret = fd->wait_data_intr(3*60, 0); 
87 +         if (ret == 1) {       /* get data */
88 +            n = bget_dirmsg(fd);
89 +            if (n >= 0 && 
90 +                (sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
91 +                        &ReadBytes, &JobBytes, &Errors, &VSS, &Encrypt) == 7 ||
92 +                 sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
93 +                        &ReadBytes, &JobBytes, &Errors) == 5)) {
94 +               fd_ok = true;
95 +               set_jcr_job_status(jcr, jcr->FDJobStatus);
96 +               OK=false;        /* end of loop */
97 +            } else {
98 +               Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
99 +                    fd->msg);
100 +            }
101 +         } /* else get timeout or network error */
102 +
103 +         if (is_bnet_error(fd)) {
104 +            Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
105 +                 job_type_to_str(jcr->JobType), fd->bstrerror());
106 +            OK=false;
107 +         }
108        }
109 -      if (job_canceled(jcr)) {
110 -         break;
111 -      }
112 -   }
113  
114 -   if (is_bnet_error(fd)) {
115 -      Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
116 -          job_type_to_str(jcr->JobType), fd->bstrerror());
117 +      fd->signal(BNET_TERMINATE);   /* tell Client we are terminating */
118     }
119 -   fd->signal(BNET_TERMINATE);   /* tell Client we are terminating */
120  
121     /* Force cancel in SD if failing */
122     if (job_canceled(jcr) || !fd_ok) {
123 Index: src/dird/protos.h
124 ===================================================================
125 --- src/dird/protos.h   (rĂ©vision 7772)
126 +++ src/dird/protos.h   (copie de travail)
127 @@ -52,7 +52,7 @@
128  extern bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
129  
130  /* backup.c */
131 -extern int wait_for_job_termination(JCR *jcr);
132 +extern int wait_for_job_termination(JCR *jcr, bool expect_EndJob=true);
133  extern bool do_backup_init(JCR *jcr);
134  extern bool do_backup(JCR *jcr);
135  extern void backup_cleanup(JCR *jcr, int TermCode);