2 * SD -- mac.c -- responsible for doing
3 * migration, archive, and copy jobs.
5 * Kern Sibbald, January MMVI
10 Copyright (C) 2006 Kern Sibbald
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.
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.
27 /* Import functions */
28 extern char Job_end[];
30 /* Forward referenced subroutines */
31 static bool record_cb(DCR *dcr, DEV_RECORD *rec);
35 * Read Data and send to File Daemon
36 * Returns: false on failure
42 BSOCK *dir = jcr->dir_bsock;
47 switch(jcr->JobType) {
63 Dmsg0(20, "Start read data.\n");
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);
73 Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumVolumes,
74 jcr->VolList->VolumeName, Type);
76 /* Ready device for reading */
77 if (!acquire_device_for_read(jcr->read_dcr)) {
82 if (!acquire_device_for_append(jcr->dcr)) {
83 set_jcr_job_status(jcr, JS_ErrorTerminated);
87 jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
88 jcr->run_time = time(NULL);
90 ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
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"));
106 if (ok && dev->is_dvd()) {
107 ok = dvd_close_job(jcr->dcr); /* do DVD cleanup if any */
109 /* Release the device -- and send final Vol info to DIR */
110 release_device(jcr->dcr);
112 if (!release_device(jcr->read_dcr)) {
116 free_restore_volume_list(jcr);
119 if (!ok || job_canceled(jcr)) {
120 discard_attribute_spool(jcr);
122 commit_attribute_spool(jcr);
125 dir_send_job_status(jcr); /* update director */
128 Dmsg0(30, "Done reading.\n");
129 jcr->end_time = time(NULL);
130 dequeue_messages(jcr); /* send any queued messages */
132 set_jcr_job_status(jcr, JS_Terminated);
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);
139 bnet_sig(dir, BNET_EOD); /* send EOD to Director daemon */
145 * Called here for each record from read_records()
146 * Returns: true if OK
149 static bool record_cb(DCR *dcr, DEV_RECORD *rec)
153 char buf1[100], buf2[100];
156 switch (rec->FileIndex) {
160 return true; /* don't write vol labels */
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),
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,
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));
181 jcr->JobBytes += rec->data_len; /* increment bytes this job */
182 if (rec->FileIndex > 0) {
183 jcr->JobFiles = rec->FileIndex;
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);
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;
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));
204 jcr->dir_bsock->spool = false;