]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mac.c
dhb left console.cpp uncompileable. Modified a comment in mainwin.cpp
[bacula/bacula] / bacula / src / stored / mac.c
1 /*
2  * SD -- mac.c --  responsible for doing
3  *     migration, archive, and copy jobs.
4  *
5  *     Kern Sibbald, January MMVI
6  *
7  *   Version $Id$
8  */
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
13
14    The main author of Bacula is Kern Sibbald, with contributions from
15    many others, a complete list can be found in the file AUTHORS.
16    This program is Free Software; you can redistribute it and/or
17    modify it under the terms of version two of the GNU General Public
18    License as published by the Free Software Foundation plus additions
19    that are listed in the file LICENSE.
20
21    This program is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24    General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program; if not, write to the Free Software
28    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
32    The licensor of Bacula is the Free Software Foundation Europe
33    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34    Switzerland, email:ftf@fsfeurope.org.
35 */
36
37 #include "bacula.h"
38 #include "stored.h"
39
40 /* Import functions */
41 extern char Job_end[];   
42
43 /* Forward referenced subroutines */
44 static bool record_cb(DCR *dcr, DEV_RECORD *rec);
45
46
47 /*
48  *  Read Data and send to File Daemon
49  *   Returns: false on failure
50  *            true  on success
51  */
52 bool do_mac(JCR *jcr)
53 {
54    bool ok = true;
55    BSOCK *dir = jcr->dir_bsock;
56    const char *Type;
57    char ec1[50];
58    DEVICE *dev;
59
60    switch(jcr->JobType) {
61    case JT_MIGRATE:
62       Type = "Migration";
63       break;
64    case JT_ARCHIVE:
65       Type = "Archive";
66       break;
67    case JT_COPY:
68       Type = "Copy";
69       break;
70    default:
71       Type = "Unknown";
72       break;
73    }
74
75
76    Dmsg0(20, "Start read data.\n");
77
78    if (!jcr->read_dcr || !jcr->dcr) {
79       Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n"));
80       goto bail_out;
81    }
82    Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);
83
84
85    create_restore_volume_list(jcr);
86    if (jcr->NumReadVolumes == 0) {
87       Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
88       goto bail_out;
89    }
90
91    Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes,
92       jcr->VolList->VolumeName, Type);
93
94    /* Ready devices for reading and writing */
95    if (!acquire_device_for_read(jcr->read_dcr) ||
96        !acquire_device_for_append(jcr->dcr)) {
97       set_jcr_job_status(jcr, JS_ErrorTerminated);
98       goto bail_out;
99    }
100
101    Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num);
102      
103
104    set_jcr_job_status(jcr, JS_Running);
105    dir_send_job_status(jcr);
106
107    jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
108    jcr->run_time = time(NULL);
109
110    ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
111    goto ok_out;
112
113 bail_out:
114    ok = false;
115
116 ok_out:
117    if (jcr->dcr) {
118       dev = jcr->dcr->dev;
119       if (ok || dev->can_write()) {
120          /* Flush out final partial block of this session */
121          if (!write_block_to_device(jcr->dcr)) {
122             Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
123                   dev->print_name(), dev->bstrerror());
124             Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
125             ok = false;
126          }
127          Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num);
128       }  
129
130
131       if (ok && dev->is_dvd()) {
132          ok = dvd_close_job(jcr->dcr);   /* do DVD cleanup if any */
133       }
134       /* Release the device -- and send final Vol info to DIR */
135       release_device(jcr->dcr);
136    }
137
138    if (jcr->read_dcr) {
139       if (!release_device(jcr->read_dcr)) {
140          ok = false;
141       }
142    }
143
144    free_restore_volume_list(jcr);
145
146
147    if (!ok || job_canceled(jcr)) {
148       discard_attribute_spool(jcr);
149    } else {
150       commit_attribute_spool(jcr);
151    }
152
153    dir_send_job_status(jcr);          /* update director */
154
155
156    Dmsg0(30, "Done reading.\n");
157    jcr->end_time = time(NULL);
158    dequeue_messages(jcr);             /* send any queued messages */
159    if (ok) {
160       set_jcr_job_status(jcr, JS_Terminated);
161    }
162    generate_daemon_event(jcr, "JobEnd");
163    bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
164       edit_uint64(jcr->JobBytes, ec1));
165    Dmsg4(200, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); 
166        
167    bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
168
169    return ok;
170 }
171
172 /*
173  * Called here for each record from read_records()
174  *  Returns: true if OK
175  *           false if error
176  */
177 static bool record_cb(DCR *dcr, DEV_RECORD *rec)
178 {
179    JCR *jcr = dcr->jcr;
180    DEVICE *dev = jcr->dcr->dev;
181    char buf1[100], buf2[100];
182    int32_t stream;   
183    
184    /* If label and not for us, discard it */
185    if (rec->FileIndex < 0 && rec->match_stat <= 0) {
186       return true;
187    }
188    /* We want to write SOS_LABEL and EOS_LABEL discard all others */
189    switch (rec->FileIndex) {                        
190    case PRE_LABEL:
191    case VOL_LABEL:
192    case EOT_LABEL:
193    case EOM_LABEL:
194       return true;                    /* don't write vol labels */
195    }
196    /*
197     * Modify record SessionId and SessionTime to correspond to
198     * output.
199     */
200    rec->VolSessionId = jcr->VolSessionId;
201    rec->VolSessionTime = jcr->VolSessionTime;
202    Dmsg5(200, "before write_rec JobId=%d FI=%s SessId=%d Strm=%s len=%d\n",
203       jcr->JobId,
204       FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
205       stream_to_ascii(buf1, rec->Stream,rec->FileIndex), rec->data_len);
206
207    while (!write_record_to_block(jcr->dcr->block, rec)) {
208       Dmsg4(200, "!write_record_to_block blkpos=%u:%u len=%d rem=%d\n", 
209             dev->file, dev->block_num, rec->data_len, rec->remainder);
210       if (!write_block_to_device(jcr->dcr)) {
211          Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
212             dev->print_name(), dev->bstrerror());
213          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
214                dev->print_name(), dev->bstrerror());
215          return false;
216       }
217       Dmsg2(200, "===== Wrote block new pos %u:%u\n", dev->file, dev->block_num);
218    }
219    jcr->JobBytes += rec->data_len;   /* increment bytes this job */
220    if (rec->FileIndex > 0) {
221       jcr->JobFiles = rec->FileIndex;
222    } else {
223       return true;                    /* don't send LABELs to Dir */
224    }
225    Dmsg5(500, "wrote_record JobId=%d FI=%s SessId=%d Strm=%s len=%d\n",
226       jcr->JobId,
227       FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
228       stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
229
230    /* Send attributes and digest to Director for Catalog */
231    stream = rec->Stream;
232    if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
233        crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
234       if (!jcr->no_attributes) {
235          if (are_attributes_spooled(jcr)) {
236             jcr->dir_bsock->spool = true;
237          }
238          Dmsg0(850, "Send attributes to dir.\n");
239          if (!dir_update_file_attributes(jcr->dcr, rec)) {
240             jcr->dir_bsock->spool = false;
241             Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
242                bnet_strerror(jcr->dir_bsock));
243             return false;
244          }
245          jcr->dir_bsock->spool = false;
246       }
247    }
248
249    return true;
250 }