]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mac.c
- Add more jcr methods and make mutex and use_count private.
[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    if (!jcr->read_dcr || !jcr->dcr) {
66       Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n"));
67       goto bail_out;
68    }
69    Dmsg2(000, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);
70
71
72    create_restore_volume_list(jcr);
73    if (jcr->NumVolumes == 0) {
74       Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
75       goto bail_out;
76    }
77
78    Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumVolumes,
79       jcr->VolList->VolumeName, Type);
80
81    /* Ready devices for reading and writing */
82    if (!acquire_device_for_read(jcr->read_dcr) ||
83        !acquire_device_for_append(jcr->dcr)) {
84       set_jcr_job_status(jcr, JS_ErrorTerminated);
85       goto bail_out;
86    }
87
88    jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
89    jcr->run_time = time(NULL);
90
91    ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
92    goto ok_out;
93
94 bail_out:
95    ok = false;
96
97 ok_out:
98    if (jcr->dcr) {
99       dev = jcr->dcr->dev;
100       if (ok || dev->can_write()) {
101          /* Flush out final partial block of this session */
102          if (!write_block_to_device(jcr->dcr)) {
103             Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
104                   dev->print_name(), dev->bstrerror());
105             Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
106             ok = false;
107          }
108       }  
109
110
111       if (ok && dev->is_dvd()) {
112          ok = dvd_close_job(jcr->dcr);   /* do DVD cleanup if any */
113       }
114       /* Release the device -- and send final Vol info to DIR */
115       release_device(jcr->dcr);
116    }
117
118    if (jcr->read_dcr) {
119       if (!release_device(jcr->read_dcr)) {
120          ok = false;
121       }
122    }
123
124    free_restore_volume_list(jcr);
125
126
127    if (!ok || job_canceled(jcr)) {
128       discard_attribute_spool(jcr);
129    } else {
130       commit_attribute_spool(jcr);
131    }
132
133    dir_send_job_status(jcr);          /* update director */
134
135
136    Dmsg0(30, "Done reading.\n");
137    jcr->end_time = time(NULL);
138    dequeue_messages(jcr);             /* send any queued messages */
139    if (ok) {
140       set_jcr_job_status(jcr, JS_Terminated);
141    }
142    generate_daemon_event(jcr, "JobEnd");
143    bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
144       edit_uint64(jcr->JobBytes, ec1));
145    Dmsg4(400, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); 
146        
147    bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
148
149    return ok;
150 }
151
152 /*
153  * Called here for each record from read_records()
154  *  Returns: true if OK
155  *           false if error
156  */
157 static bool record_cb(DCR *dcr, DEV_RECORD *rec)
158 {
159    bool ok = true;
160    JCR *jcr = dcr->jcr;
161    char buf1[100], buf2[100];
162    int32_t stream;   
163    
164    switch (rec->FileIndex) {                        
165    case PRE_LABEL:
166    case VOL_LABEL:
167    case EOT_LABEL:
168       return true;                    /* don't write vol labels */
169    }
170    rec->VolSessionId = jcr->VolSessionId;
171    rec->VolSessionTime = jcr->VolSessionTime;
172    Dmsg4(850, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
173       rec->FileIndex, rec->VolSessionId, 
174       stream_to_ascii(buf1, rec->Stream,rec->FileIndex),
175       rec->data_len);
176
177    while (!write_record_to_block(jcr->dcr->block, rec)) {
178       Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
179                  rec->remainder);
180       if (!write_block_to_device(jcr->dcr)) {
181          DEVICE *dev = jcr->dcr->dev;
182          Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
183             dev->print_name(), dev->bstrerror());
184          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
185                dev->print_name(), dev->bstrerror());
186          return false;
187       }
188    }
189    jcr->JobBytes += rec->data_len;   /* increment bytes this job */
190    if (rec->FileIndex > 0) {
191       jcr->JobFiles = rec->FileIndex;
192    }
193    Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
194       FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
195       stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
196
197    /* Send attributes and digest to Director for Catalog */
198    stream = rec->Stream;
199    if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
200        crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
201       if (!jcr->no_attributes) {
202          if (are_attributes_spooled(jcr)) {
203             jcr->dir_bsock->spool = true;
204          }
205          Dmsg0(850, "Send attributes to dir.\n");
206          if (!dir_update_file_attributes(jcr->dcr, rec)) {
207             jcr->dir_bsock->spool = false;
208             Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
209                bnet_strerror(jcr->dir_bsock));
210             return false;
211          }
212          jcr->dir_bsock->spool = false;
213       }
214    }
215
216    return ok;
217 }