]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mac.c
5e51f453f642a91e8bfc42d06e61c4ab8ce1c629
[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    Copyright (C) 2006 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "stored.h"
26
27 /* Import functions */
28 extern char Job_end[];   
29
30 /* Forward referenced subroutines */
31 static bool record_cb(DCR *dcr, DEV_RECORD *rec);
32
33
34 /*
35  *  Read Data and send to File Daemon
36  *   Returns: false on failure
37  *            true  on success
38  */
39 bool do_mac(JCR *jcr)
40 {
41    bool ok = true;
42    BSOCK *dir = jcr->dir_bsock;
43    const char *Type;
44    char ec1[50];
45    DEVICE *dev;
46
47    switch(jcr->JobType) {
48    case JT_MIGRATE:
49       Type = "Migration";
50       break;
51    case JT_ARCHIVE:
52       Type = "Archive";
53       break;
54    case JT_COPY:
55       Type = "Copy";
56       break;
57    default:
58       Type = "Unknown";
59       break;
60    }
61
62
63    Dmsg0(20, "Start read data.\n");
64
65
66    create_restore_volume_list(jcr);
67    if (jcr->NumVolumes == 0) {
68       Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
69       free_restore_volume_list(jcr);
70       return false;
71    }
72
73    Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumVolumes,
74       jcr->VolList->VolumeName, Type);
75
76    /* Ready device for reading */
77    if (!acquire_device_for_read(jcr->read_dcr)) {
78       ok = false;
79       goto bail_out;
80    }
81
82    if (!acquire_device_for_append(jcr->dcr)) {
83       set_jcr_job_status(jcr, JS_ErrorTerminated);
84       ok = false;
85       goto bail_out;
86    }
87    jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
88    jcr->run_time = time(NULL);
89
90    ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
91
92 bail_out:
93
94    dev = jcr->dcr->dev;
95    if (ok || dev->can_write()) {
96       /* Flush out final partial block of this session */
97       if (!write_block_to_device(jcr->dcr)) {
98          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
99                dev->print_name(), strerror_dev(dev));
100          Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
101          ok = false;
102       }
103    }  
104
105
106    if (ok && dev->is_dvd()) {
107       ok = dvd_close_job(jcr->dcr);   /* do DVD cleanup if any */
108    }
109    /* Release the device -- and send final Vol info to DIR */
110    release_device(jcr->dcr);
111
112    if (!release_device(jcr->read_dcr)) {
113       ok = false;
114    }
115
116    free_restore_volume_list(jcr);
117
118
119    if (!ok || job_canceled(jcr)) {
120       discard_attribute_spool(jcr);
121    } else {
122       commit_attribute_spool(jcr);
123    }
124
125    dir_send_job_status(jcr);          /* update director */
126
127
128    Dmsg0(30, "Done reading.\n");
129    jcr->end_time = time(NULL);
130    dequeue_messages(jcr);             /* send any queued messages */
131    if (ok) {
132       set_jcr_job_status(jcr, JS_Terminated);
133    }
134    generate_daemon_event(jcr, "JobEnd");
135    bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
136       edit_uint64(jcr->JobBytes, ec1));
137    Dmsg4(400, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); 
138        
139    bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
140
141    return ok;
142 }
143
144 /*
145  * Called here for each record from read_records()
146  *  Returns: true if OK
147  *           false if error
148  */
149 static bool record_cb(DCR *dcr, DEV_RECORD *rec)
150 {
151    bool ok = true;
152    JCR *jcr = dcr->jcr;
153    char buf1[100], buf2[100];
154    int32_t stream;   
155    
156    switch (rec->FileIndex) {                        
157    case PRE_LABEL:
158    case VOL_LABEL:
159    case EOT_LABEL:
160       return true;                    /* don't write vol labels */
161    }
162    rec->VolSessionId = jcr->VolSessionId;
163    rec->VolSessionTime = jcr->VolSessionTime;
164    Dmsg4(850, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
165       rec->FileIndex, rec->VolSessionId, 
166       stream_to_ascii(buf1, rec->Stream,rec->FileIndex),
167       rec->data_len);
168
169    while (!write_record_to_block(jcr->dcr->block, rec)) {
170       Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
171                  rec->remainder);
172       if (!write_block_to_device(jcr->dcr)) {
173          DEVICE *dev = jcr->dcr->dev;
174          Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
175             dev->print_name(), strerror_dev(dev));
176          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
177                dev->print_name(), strerror_dev(dev));
178          return false;
179       }
180    }
181    jcr->JobBytes += rec->data_len;   /* increment bytes this job */
182    if (rec->FileIndex > 0) {
183       jcr->JobFiles = rec->FileIndex;
184    }
185    Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
186       FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
187       stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
188
189    /* Send attributes and digest to Director for Catalog */
190    stream = rec->Stream;
191    if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
192        crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
193       if (!jcr->no_attributes) {
194          if (are_attributes_spooled(jcr)) {
195             jcr->dir_bsock->spool = true;
196          }
197          Dmsg0(850, "Send attributes to dir.\n");
198          if (!dir_update_file_attributes(jcr->dcr, rec)) {
199             jcr->dir_bsock->spool = false;
200             Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
201                bnet_strerror(jcr->dir_bsock));
202             return false;
203          }
204          jcr->dir_bsock->spool = false;
205       }
206    }
207
208    return ok;
209 }