4 * Kern Sibbald, March 2004
9 Copyright (C) 2000-2004 Kern Sibbald and John Walker
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of
14 the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public
22 License along with this program; if not, write to the Free
23 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
31 /* Forward referenced subroutines */
32 static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name);
33 static int open_data_spool_file(JCR *jcr);
34 static int close_data_spool_file(JCR *jcr);
35 static bool despool_data(DCR *dcr);
38 int begin_data_spool(JCR *jcr)
40 if (jcr->dcr->spool_data) {
41 return open_data_spool_file(jcr);
46 int discard_data_spool(JCR *jcr)
48 if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
49 return close_data_spool_file(jcr);
54 int commit_data_spool(JCR *jcr)
57 if (jcr->dcr->spool_data && jcr->dcr->spool_fd >= 0) {
58 lock_device(jcr->dcr->dev);
59 stat = despool_data(jcr->dcr);
60 unlock_device(jcr->dcr->dev);
62 close_data_spool_file(jcr);
65 return close_data_spool_file(jcr);
70 static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
72 Mmsg(name, "%s/%s.data.spool.%s.%s", working_directory, my_name,
73 jcr->Job, jcr->device->hdr.name);
77 static int open_data_spool_file(JCR *jcr)
79 POOLMEM *name = get_pool_memory(PM_MESSAGE);
82 make_unique_data_spool_filename(jcr, &name);
83 if ((spool_fd = open(name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0640)) >= 0) {
84 jcr->dcr->spool_fd = spool_fd;
85 jcr->spool_attributes = true;
87 Jmsg(jcr, M_ERROR, 0, "open data spool file %s failed: ERR=%s\n", name, strerror(errno));
88 free_pool_memory(name);
91 free_pool_memory(name);
95 static int close_data_spool_file(JCR *jcr)
97 POOLMEM *name = get_pool_memory(PM_MESSAGE);
99 make_unique_data_spool_filename(jcr, &name);
100 close(jcr->dcr->spool_fd);
101 jcr->dcr->spool_fd = -1;
103 free_pool_memory(name);
107 static bool despool_data(DCR *dcr)
111 dcr->spooling = false;
113 DEV_BLOCK *block = dcr->block;
116 /* Set up a dev structure to read */
117 sdev = (DEVICE *)malloc(sizeof(DEVICE));
118 memset(sdev, 0, sizeof(DEVICE));
119 sdev->fd = dcr->spool_fd;
120 lseek(sdev->fd, 0, SEEK_SET); /* rewind */
121 sdcr = new_dcr(jcr, sdev);
123 if (job_canceled(jcr)) {
127 if (!read_block_from_dev(jcr, sdev, block, CHECK_BLOCK_NUMBERS)) {
128 if (dev_state(sdev, ST_EOT)) {
134 if (!write_block_to_dev(dcr, block)) {
139 lseek(sdev->fd, 0, SEEK_SET); /* rewind */
140 if (ftruncate(sdev->fd, 0) != 0) {
147 * Write a block to the spool file
149 * Returns: true on success or EOT
150 * false on hard error
152 bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
155 uint32_t wlen; /* length to write */
156 DEVICE *dev = dcr->dev;
159 ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
161 wlen = block->binbuf;
162 if (wlen <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
163 Dmsg0(100, "return write_block_to_dev no data to write\n");
167 * Clear to the end of the buffer if it is not full,
168 * and on tape devices, apply min and fixed blocking.
170 if (wlen != block->buf_len) {
171 uint32_t blen; /* current buffer length */
173 Dmsg2(200, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
176 /* Adjust write size to min/max for tapes only */
177 if (dev->state & ST_TAPE) {
178 if (wlen < dev->min_block_size) {
179 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
181 /* check for fixed block size */
182 if (dev->min_block_size == dev->max_block_size) {
183 wlen = block->buf_len; /* fixed block size already rounded */
187 memset(block->bufp, 0, wlen-blen); /* clear garbage */
191 ser_block_header(block);
193 Dmsg1(300, "Write block of %u bytes\n", wlen);
195 stat = write(dcr->spool_fd, block->buf, (size_t)wlen);
196 if (stat != (ssize_t)wlen) {
197 if (!despool_data(dcr)) {
212 bool are_attributes_spooled(JCR *jcr)
214 return jcr->spool_attributes && jcr->dir_bsock->spool_fd;
217 int begin_attribute_spool(JCR *jcr)
219 if (!jcr->no_attributes && jcr->spool_attributes) {
220 return open_spool_file(jcr, jcr->dir_bsock);
225 int discard_attribute_spool(JCR *jcr)
227 if (are_attributes_spooled(jcr)) {
228 return close_spool_file(jcr, jcr->dir_bsock);
233 int commit_attribute_spool(JCR *jcr)
235 if (are_attributes_spooled(jcr)) {
236 bnet_despool_to_bsock(jcr->dir_bsock);
237 return close_spool_file(jcr, jcr->dir_bsock);