2 This patch can be applied to version 3.0.0. It ensures that the list
3 of volumes to be read is created very early when starting the Job in
4 the SD (before the drive reservation) so that any Volume to be read
5 cannot also be chosen to append.
7 Apply it to version 3.0.0 with:
10 patch -p0 <3.0.0-read-vol-list.patch
11 ./configure <your-options>
18 Index: src/dird/msgchan.c
19 ===================================================================
20 --- src/dird/msgchan.c (revision 8699)
21 +++ src/dird/msgchan.c (working copy)
26 +static char OKbootstrap[] = "3000 OK bootstrap\n";
29 * Start a job with the Storage daemon
31 -bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
32 +bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore, bool send_bsr)
37 &jcr->VolSessionTime, &auth_key) != 3) {
38 Dmsg1(100, "BadJob=%s\n", sd->msg);
39 Jmsg(jcr, M_FATAL, 0, _("Storage daemon rejected Job command: %s\n"), sd->msg);
43 jcr->sd_auth_key = bstrdup(auth_key);
44 Dmsg1(150, "sd_auth_key=%s\n", jcr->sd_auth_key);
47 Jmsg(jcr, M_FATAL, 0, _("<stored: bad response to Job command: %s\n"),
53 + if (send_bsr && (!send_bootstrap_file(jcr, sd) ||
54 + !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR))) {
59 * We have two loops here. The first comes from the
60 * Storage = associated with the Job, and we need
61 Index: src/dird/migrate.c
62 ===================================================================
63 --- src/dird/migrate.c (revision 8699)
64 +++ src/dird/migrate.c (working copy)
67 static const int dbglevel = 10;
69 -static char OKbootstrap[] = "3000 OK bootstrap\n";
70 static int get_job_to_migrate(JCR *jcr);
72 static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1,
74 ((STORE *)jcr->rstorage->first())->name());
77 - if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
78 + if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
81 Dmsg0(150, "Storage daemon connection OK\n");
83 - if (!send_bootstrap_file(jcr, sd) ||
84 - !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
89 * We re-update the job start record so that the start
90 Index: src/dird/protos.h
91 ===================================================================
92 --- src/dird/protos.h (revision 8699)
93 +++ src/dird/protos.h (working copy)
96 extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
97 int max_retry_time, int verbose);
98 -extern bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore);
99 +extern bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore,
100 + bool send_bsr=false);
101 extern bool start_storage_daemon_message_thread(JCR *jcr);
102 extern int bget_dirmsg(BSOCK *bs);
103 extern void wait_for_storage_daemon_termination(JCR *jcr);
104 Index: src/dird/vbackup.c
105 ===================================================================
106 --- src/dird/vbackup.c (revision 8699)
107 +++ src/dird/vbackup.c (working copy)
110 static const int dbglevel = 10;
112 -static char OKbootstrap[] = "3000 OK bootstrap\n";
114 static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
115 void vbackup_cleanup(JCR *jcr, int TermCode);
117 @@ -217,16 +215,11 @@
119 * Now start a job with the Storage daemon
121 - if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
122 + if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
125 Dmsg0(100, "Storage daemon connection OK\n");
127 - if (!send_bootstrap_file(jcr, sd) ||
128 - !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
133 * We re-update the job start record so that the start
134 * time is set after the run before job. This avoids
135 Index: src/stored/fd_cmds.c
136 ===================================================================
137 --- src/stored/fd_cmds.c (revision 8699)
138 +++ src/stored/fd_cmds.c (working copy)
140 if (debug_level >= 10) {
141 dump_bsr(jcr->bsr, true);
143 + /* If we got a bootstrap, we are reading, so create read volume list */
144 + create_restore_volume_list(jcr);
148 Index: src/stored/read.c
149 ===================================================================
150 --- src/stored/read.c (revision 8699)
151 +++ src/stored/read.c (working copy)
154 Bacula® - The Network Backup Solution
156 - Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
157 + Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
159 The main author of Bacula is Kern Sibbald, with contributions from
160 many others, a complete list can be found in the file AUTHORS.
166 - create_restore_volume_list(jcr);
167 if (jcr->NumReadVolumes == 0) {
168 Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n"));
169 - free_restore_volume_list(jcr);
175 /* Ready device for reading */
176 if (!acquire_device_for_read(dcr)) {
177 - free_restore_volume_list(jcr);
185 - free_restore_volume_list(jcr);
186 Dmsg0(30, "Done reading.\n");
189 Index: src/stored/parse_bsr.c
190 ===================================================================
191 --- src/stored/parse_bsr.c (revision 8699)
192 +++ src/stored/parse_bsr.c (working copy)
195 Bacula® - The Network Backup Solution
197 - Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
198 + Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
200 The main author of Bacula is Kern Sibbald, with contributions from
201 many others, a complete list can be found in the file AUTHORS.
202 Index: src/stored/mac.c
203 ===================================================================
204 --- src/stored/mac.c (revision 8699)
205 +++ src/stored/mac.c (working copy)
208 Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);
211 - create_restore_volume_list(jcr);
212 if (jcr->NumReadVolumes == 0) {
213 Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
219 - free_restore_volume_list(jcr);
221 dir_send_job_status(jcr); /* update director */
224 Dmsg0(30, "Done reading.\n");
225 jcr->end_time = time(NULL);
226 dequeue_messages(jcr); /* send any queued messages */
227 Index: src/stored/vol_mgr.c
228 ===================================================================
229 --- src/stored/vol_mgr.c (revision 8699)
230 +++ src/stored/vol_mgr.c (working copy)
234 if (read_vol_list->empty()) {
235 + Dmsg0(dbglvl, "find_read_vol: read_vol_list empty.\n");
238 /* Do not lock reservations here */
239 Index: src/stored/job.c
240 ===================================================================
241 --- src/stored/job.c (revision 8699)
242 +++ src/stored/job.c (working copy)
247 + /* Free any restore volume list created */
248 + free_restore_volume_list(jcr);
249 if (jcr->RestoreBootstrap) {
250 unlink(jcr->RestoreBootstrap);
251 free_pool_memory(jcr->RestoreBootstrap);
252 Index: src/stored/acquire.c
253 ===================================================================
254 --- src/stored/acquire.c (revision 8699)
255 +++ src/stored/acquire.c (working copy)
257 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
258 Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n",
259 dcr->VolumeName, jcr->errmsg);
260 - Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
261 + Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
263 dev->set_load(); /* set to load volume */
266 * error messages when nothing is mounted.
268 if (tape_previously_mounted) {
269 - Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
270 + Jmsg(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
278 - Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
279 + Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
281 Dmsg0(50, "default path\n");
282 tape_previously_mounted = true;