2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
17 * Bacula File Daemon backup.c send file attributes and data
18 * to the Storage daemon.
20 * Kern Sibbald, March MM
29 const bool have_darwin_os = true;
31 const bool have_darwin_os = false;
35 const bool have_acl = true;
37 const bool have_acl = false;
40 #if defined(HAVE_XATTR)
41 const bool have_xattr = true;
43 const bool have_xattr = false;
46 /* Forward referenced functions */
47 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
48 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
49 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
50 static bool crypto_session_start(JCR *jcr);
51 static void crypto_session_end(JCR *jcr);
52 static bool crypto_session_send(JCR *jcr, BSOCK *sd);
53 static void close_vss_backup_session(JCR *jcr);
56 * Find all the requested files and send them
57 * to the Storage daemon.
59 * Note, we normally carry on a one-way
60 * conversation from this point on with the SD, simply blasting
61 * data to him. To properly know what is going on, we
62 * also run a "heartbeat" monitor which reads the socket and
63 * reacts accordingly (at the moment it has nothing to do
64 * except echo the heartbeat to the Director).
67 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
71 // TODO landonf: Allow user to specify encryption algorithm
73 sd = jcr->store_bsock;
75 jcr->setJobStatus(JS_Running);
77 Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->m_fd);
80 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
84 buf_size = client->max_network_buffer_size;
86 buf_size = 0; /* use default */
88 if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) {
89 jcr->setJobStatus(JS_ErrorTerminated);
90 Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
94 jcr->buf_size = sd->msglen;
96 * Adjust for compression so that output buffer is
97 * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
98 * This gives a bit extra plus room for the sparse addr if any.
99 * Note, we adjust the read size to be smaller so that the
100 * same output buffer can be used without growing it.
102 * For LZO1X compression the recommended value is :
103 * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + sizeof(comp_stream_header)
105 * The zlib compression workset is initialized here to minimize
106 * the "per file" load. The jcr member is only set, if the init
109 * For the same reason, lzo compression is initialized here.
112 jcr->compress_buf_size = MAX(jcr->buf_size + (jcr->buf_size / 16) + 67 + (int)sizeof(comp_stream_header), jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30);
113 jcr->compress_buf = get_memory(jcr->compress_buf_size);
115 jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
116 jcr->compress_buf = get_memory(jcr->compress_buf_size);
120 z_stream *pZlibStream = (z_stream*)malloc(sizeof(z_stream));
122 pZlibStream->zalloc = Z_NULL;
123 pZlibStream->zfree = Z_NULL;
124 pZlibStream->opaque = Z_NULL;
125 pZlibStream->state = Z_NULL;
127 if (deflateInit(pZlibStream, Z_DEFAULT_COMPRESSION) == Z_OK) {
128 jcr->pZLIB_compress_workset = pZlibStream;
136 lzo_voidp pLzoMem = (lzo_voidp) malloc(LZO1X_1_MEM_COMPRESS);
138 if (lzo_init() == LZO_E_OK) {
139 jcr->LZO_compress_workset = pLzoMem;
146 if (!crypto_session_start(jcr)) {
150 set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
152 /** in accurate mode, we overload the find_one check function */
154 set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file);
157 start_heartbeat_monitor(jcr);
160 jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
161 memset(jcr->acl_data, 0, sizeof(acl_data_t));
162 jcr->acl_data->u.build = (acl_build_data_t *)malloc(sizeof(acl_build_data_t));
163 memset(jcr->acl_data->u.build, 0, sizeof(acl_build_data_t));
164 jcr->acl_data->u.build->content = get_pool_memory(PM_MESSAGE);
168 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
169 memset(jcr->xattr_data, 0, sizeof(xattr_data_t));
170 jcr->xattr_data->u.build = (xattr_build_data_t *)malloc(sizeof(xattr_build_data_t));
171 memset(jcr->xattr_data->u.build, 0, sizeof(xattr_build_data_t));
172 jcr->xattr_data->u.build->content = get_pool_memory(PM_MESSAGE);
175 /** Subroutine save_file() is called for each file */
176 if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
177 ok = false; /* error */
178 jcr->setJobStatus(JS_ErrorTerminated);
181 if (have_acl && jcr->acl_data->u.build->nr_errors > 0) {
182 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing backup\n"),
183 jcr->acl_data->u.build->nr_errors);
185 if (have_xattr && jcr->xattr_data->u.build->nr_errors > 0) {
186 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing backup\n"),
187 jcr->xattr_data->u.build->nr_errors);
190 close_vss_backup_session(jcr);
192 accurate_finish(jcr); /* send deleted or base file list to SD */
194 stop_heartbeat_monitor(jcr);
196 sd->signal(BNET_EOD); /* end of sending data */
198 if (have_acl && jcr->acl_data) {
199 free_pool_memory(jcr->acl_data->u.build->content);
200 free(jcr->acl_data->u.build);
202 jcr->acl_data = NULL;
204 if (have_xattr && jcr->xattr_data) {
205 free_pool_memory(jcr->xattr_data->u.build->content);
206 free(jcr->xattr_data->u.build);
207 free(jcr->xattr_data);
208 jcr->xattr_data = NULL;
214 if (jcr->compress_buf) {
215 free_pool_memory(jcr->compress_buf);
216 jcr->compress_buf = NULL;
218 if (jcr->pZLIB_compress_workset) {
219 /* Free the zlib stream */
221 deflateEnd((z_stream *)jcr->pZLIB_compress_workset);
223 free (jcr->pZLIB_compress_workset);
224 jcr->pZLIB_compress_workset = NULL;
226 if (jcr->LZO_compress_workset) {
227 free (jcr->LZO_compress_workset);
228 jcr->LZO_compress_workset = NULL;
231 crypto_session_end(jcr);
234 Dmsg1(100, "end blast_data ok=%d\n", ok);
238 static bool crypto_session_start(JCR *jcr)
240 crypto_cipher_t cipher = (crypto_cipher_t) me->pki_cipher;
243 * Create encryption session data and a cached, DER-encoded session data
244 * structure. We use a single session key for each backup, so we'll encode
245 * the session data only once.
247 if (jcr->crypto.pki_encrypt) {
250 /** Create per-job session encryption context */
251 jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients);
252 if (!jcr->crypto.pki_session) {
253 Jmsg(jcr, M_FATAL, 0, _("Unsupported cipher on this system.\n"));
257 /** Get the session data size */
258 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)0, &size)) {
259 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
263 /** Allocate buffer */
264 jcr->crypto.pki_session_encoded = get_memory(size);
266 /** Encode session data */
267 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) {
268 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
272 /** ... and store the encoded size */
273 jcr->crypto.pki_session_encoded_size = size;
275 /** Allocate the encryption/decryption buffer */
276 jcr->crypto.crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
281 static void crypto_session_end(JCR *jcr)
283 if (jcr->crypto.crypto_buf) {
284 free_pool_memory(jcr->crypto.crypto_buf);
285 jcr->crypto.crypto_buf = NULL;
287 if (jcr->crypto.pki_session) {
288 crypto_session_free(jcr->crypto.pki_session);
290 if (jcr->crypto.pki_session_encoded) {
291 free_pool_memory(jcr->crypto.pki_session_encoded);
292 jcr->crypto.pki_session_encoded = NULL;
296 static bool crypto_session_send(JCR *jcr, BSOCK *sd)
300 /** Send our header */
301 Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
302 sd->fsend("%ld %d %lld", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA,
303 (int64_t)jcr->ff->statp.st_size);
305 sd->msg = jcr->crypto.pki_session_encoded;
306 sd->msglen = jcr->crypto.pki_session_encoded_size;
307 jcr->JobBytes += sd->msglen;
309 Dmsg1(100, "Send data len=%d\n", sd->msglen);
312 sd->signal(BNET_EOD);
318 * Called here by find() for each file included.
319 * This is a callback. The original is find_files() above.
321 * Send the file and its data to the Storage daemon.
325 * -1 to ignore file/directory (not used here)
327 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
329 bool do_read = false;
330 bool plugin_started = false;
331 bool do_plugin_set = false;
332 int stat, data_stream;
334 DIGEST *digest = NULL;
335 DIGEST *signing_digest = NULL;
336 int digest_stream = STREAM_NONE;
337 SIGNATURE *sig = NULL;
338 bool has_file_data = false;
339 struct save_pkt sp; /* use by option plugin */
341 crypto_digest_t signing_algorithm = (crypto_digest_t) me->pki_digest;
343 BSOCK *sd = jcr->store_bsock;
344 time_t now = time(NULL);
345 if (jcr->last_stat_time == 0) {
346 jcr->last_stat_time = now;
347 jcr->stat_interval = 30; /* Default 30 seconds */
348 } else if (now >= jcr->last_stat_time + jcr->stat_interval) {
349 jcr->dir_bsock->fsend("Progress Job=x files=%ld bytes=%lld bps=%ld\n",
350 jcr->JobFiles, jcr->JobBytes, jcr->LastRate);
351 jcr->last_stat_time = now;
354 if (jcr->is_canceled()) {
355 Dmsg0(100, "Job canceled by user.\n");
359 jcr->num_files_examined++; /* bump total file count */
361 switch (ff_pkt->type) {
362 case FT_LNKSAVED: /* Hard linked, file already saved */
363 Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
366 Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
367 has_file_data = true;
370 Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
371 has_file_data = true;
374 Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
376 case FT_RESTORE_FIRST:
377 Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname);
379 case FT_PLUGIN_CONFIG:
380 Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname);
383 jcr->num_files_examined--; /* correct file count */
384 return 1; /* not used */
386 Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"),
387 ff_pkt->top_fname, ff_pkt->fname);
388 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
391 /* Suppress message for /dev filesystems */
392 if (!is_in_fileset(ff_pkt)) {
393 Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"),
394 ff_pkt->fname, ff_pkt->top_fname);
396 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
399 Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"),
400 ff_pkt->top_fname, ff_pkt->fname);
401 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
404 Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"),
410 Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
413 Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
414 if (S_ISSOCK(ff_pkt->statp.st_mode)) {
415 Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname);
420 Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
421 has_file_data = true;
424 Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
428 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
429 be.bstrerror(ff_pkt->ff_errno));
435 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"),
436 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
442 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
443 be.bstrerror(ff_pkt->ff_errno));
449 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
452 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
456 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"),
457 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
462 Dmsg1(130, "FT_DELETED: %s\n", ff_pkt->fname);
465 Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"),
466 ff_pkt->type, ff_pkt->fname);
471 Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
473 /** Digests and encryption are only useful if there's file data */
476 * Setup for digest handling. If this fails, the digest will be set to NULL
477 * and not used. Note, the digest (file hash) can be any one of the four
480 * The signing digest is a single algorithm depending on
481 * whether or not we have SHA2.
482 * ****FIXME**** the signing algoritm should really be
483 * determined a different way!!!!!! What happens if
484 * sha2 was available during backup but not restore?
486 if (ff_pkt->flags & FO_MD5) {
487 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
488 digest_stream = STREAM_MD5_DIGEST;
490 } else if (ff_pkt->flags & FO_SHA1) {
491 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
492 digest_stream = STREAM_SHA1_DIGEST;
494 } else if (ff_pkt->flags & FO_SHA256) {
495 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
496 digest_stream = STREAM_SHA256_DIGEST;
498 } else if (ff_pkt->flags & FO_SHA512) {
499 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
500 digest_stream = STREAM_SHA512_DIGEST;
503 /** Did digest initialization fail? */
504 if (digest_stream != STREAM_NONE && digest == NULL) {
505 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
506 stream_to_ascii(digest_stream));
510 * Set up signature digest handling. If this fails, the signature digest
511 * will be set to NULL and not used.
513 /* TODO landonf: We should really only calculate the digest once, for
514 * both verification and signing.
516 if (jcr->crypto.pki_sign) {
517 signing_digest = crypto_digest_new(jcr, signing_algorithm);
519 /** Full-stop if a failure occurred initializing the signature digest */
520 if (signing_digest == NULL) {
521 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
522 stream_to_ascii(signing_algorithm));
528 /** Enable encryption */
529 if (jcr->crypto.pki_encrypt) {
530 ff_pkt->flags |= FO_ENCRYPT;
534 /** Initialize the file descriptor we use for data and other streams. */
536 if (ff_pkt->flags & FO_PORTABLE) {
537 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
540 if (ff_pkt->cmd_plugin) {
541 do_plugin_set = true;
543 /* option and cmd plugin are not compatible together */
544 } else if (ff_pkt->opt_plugin) {
546 /* ask the option plugin what to do with this file */
547 switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) {
549 Dmsg2(10, "Option plugin %s will be used to backup %s\n",
550 ff_pkt->plugin, ff_pkt->fname);
551 do_plugin_set = true;
554 Dmsg2(10, "Option plugin %s decided to skip %s\n",
555 ff_pkt->plugin, ff_pkt->fname);
558 Dmsg2(10, "Option plugin %s decided to let bacula handle %s\n",
559 ff_pkt->plugin, ff_pkt->fname);
565 /* Tell bfile that it needs to call plugin */
566 if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
569 send_plugin_name(jcr, sd, true); /* signal start of plugin data */
570 plugin_started = true;
573 /** Send attributes -- must be done after binit() */
574 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
577 /** Meta data only for restore object */
578 if (IS_FT_OBJECT(ff_pkt->type)) {
581 /** Meta data only for deleted files */
582 if (ff_pkt->type == FT_DELETED) {
585 /** Set up the encryption context and send the session data to the SD */
586 if (has_file_data && jcr->crypto.pki_encrypt) {
587 if (!crypto_session_send(jcr, sd)) {
593 * Open any file with data that we intend to save, then save it.
595 * Note, if is_win32_backup, we must open the Directory so that
596 * the BackupRead will save its permissions and ownership streams.
598 if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
600 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
602 do_read = ff_pkt->statp.st_size > 0;
604 } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
605 ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION ||
606 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
610 if (ff_pkt->cmd_plugin && !ff_pkt->no_read) {
614 Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read);
618 if (ff_pkt->type == FT_FIFO) {
619 tid = start_thread_timer(jcr, pthread_self(), 60);
623 int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
624 ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE ||
625 ff_pkt->type == FT_JUNCTION);
626 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
627 ff_pkt->ff_errno = errno;
629 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
633 stop_thread_timer(tid);
639 stop_thread_timer(tid);
643 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
645 if (ff_pkt->flags & FO_CHKCHANGES) {
646 has_file_changed(jcr, ff_pkt);
649 bclose(&ff_pkt->bfd);
656 if (have_darwin_os) {
657 /** Regular files can have resource forks and Finder Info */
658 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
659 ff_pkt->flags & FO_HFSPLUS)) {
660 if (ff_pkt->hfsinfo.rsrclength > 0) {
663 if (bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
664 ff_pkt->ff_errno = errno;
666 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"),
667 ff_pkt->fname, be.bstrerror());
669 if (is_bopen(&ff_pkt->bfd)) {
670 bclose(&ff_pkt->bfd);
674 flags = ff_pkt->flags;
675 ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
676 if (flags & FO_ENCRYPT) {
677 rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
679 rsrc_stream = STREAM_MACOS_FORK_DATA;
681 stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
682 ff_pkt->flags = flags;
683 bclose(&ff_pkt->bfd);
689 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
690 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
691 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
692 pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
695 crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
697 if (signing_digest) {
698 crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
701 sd->signal(BNET_EOD);
706 * Save ACLs when requested and available for anything not being a symlink
707 * and not being a plugin.
710 if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
711 switch (build_acl_streams(jcr, ff_pkt)) {
712 case bacl_exit_fatal:
714 case bacl_exit_error:
716 * Non-fatal errors, count them and when the number is under
717 * ACL_REPORT_ERR_MAX_PER_JOB print the error message set by the
718 * lower level routine in jcr->errmsg.
720 if (jcr->acl_data->u.build->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
721 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
723 jcr->acl_data->u.build->nr_errors++;
732 * Save Extended Attributes when requested and available for all files not
736 if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
737 switch (build_xattr_streams(jcr, ff_pkt)) {
738 case bxattr_exit_fatal:
740 case bxattr_exit_error:
742 * Non-fatal errors, count them and when the number is under
743 * XATTR_REPORT_ERR_MAX_PER_JOB print the error message set by the
744 * lower level routine in jcr->errmsg.
746 if (jcr->xattr_data->u.build->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
747 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
749 jcr->xattr_data->u.build->nr_errors++;
757 /** Terminate the signing digest and send it to the Storage daemon */
758 if (signing_digest) {
761 if ((sig = crypto_sign_new(jcr)) == NULL) {
762 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
766 if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
767 Jmsg(jcr, M_FATAL, 0, _("An error occurred while adding signer the stream.\n"));
771 /** Get signature size */
772 if (!crypto_sign_encode(sig, NULL, &size)) {
773 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
777 /** Grow the bsock buffer to fit our message if necessary */
778 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
779 sd->msg = realloc_pool_memory(sd->msg, size);
782 /** Send our header */
783 sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
784 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
786 /** Encode signature data */
787 if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
788 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
794 sd->signal(BNET_EOD); /* end of checksum */
797 /** Terminate any digest and send it to Storage daemon */
801 sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
802 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
804 size = CRYPTO_DIGEST_MAX_SIZE;
806 /** Grow the bsock buffer to fit our message if necessary */
807 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
808 sd->msg = realloc_pool_memory(sd->msg, size);
811 if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
812 Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
816 /* Keep the checksum if this file is a hardlink */
817 if (ff_pkt->linked) {
818 ff_pkt_set_link_digest(ff_pkt, digest_stream, sd->msg, size);
823 sd->signal(BNET_EOD); /* end of checksum */
826 /* Check if original file has a digest, and send it */
827 if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) {
828 Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len);
829 sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream);
831 sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len);
832 memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len);
833 sd->msglen = ff_pkt->digest_len;
836 sd->signal(BNET_EOD); /* end of hardlink record */
843 if (jcr->is_canceled()) {
844 Dmsg0(100, "Job canceled by user.\n");
847 if (plugin_started) {
848 send_plugin_name(jcr, sd, false); /* signal end of plugin data */
850 if (ff_pkt->opt_plugin) {
851 jcr->plugin_sp = NULL; /* sp is local to this function */
852 jcr->plugin_ctx = NULL;
854 jcr->opt_plugin = false;
857 crypto_digest_free(digest);
859 if (signing_digest) {
860 crypto_digest_free(signing_digest);
863 crypto_sign_free(sig);
869 * Send data read from an already open file descriptor.
871 * We return 1 on sucess and 0 on errors.
874 * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
876 * Currently this is not a problem as the only other stream, resource forks,
877 * are not handled as sparse files.
879 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
880 DIGEST *signing_digest)
882 BSOCK *sd = jcr->store_bsock;
883 uint64_t fileAddr = 0; /* file address */
885 int32_t rsize = jcr->buf_size; /* read buffer size */
887 CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
888 const uint8_t *cipher_input;
889 uint32_t cipher_input_len;
890 uint32_t cipher_block_size;
891 uint32_t encrypted_len;
892 #ifdef FD_NO_SEND_TEST
897 rbuf = sd->msg; /* read buffer */
898 wbuf = sd->msg; /* write buffer */
899 cipher_input = (uint8_t *)rbuf; /* encrypt uncompressed data */
901 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
903 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
904 uLong compress_len = 0;
905 uLong max_compress_len = 0;
906 const Bytef *cbuf = NULL;
910 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_GZIP) {
911 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
912 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
913 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
915 cbuf = (Bytef *)jcr->compress_buf;
916 max_compress_len = jcr->compress_buf_size; /* set max length */
918 wbuf = jcr->compress_buf; /* compressed output here */
919 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
922 * Only change zlib parameters if there is no pending operation.
923 * This should never happen as deflatereset is called after each
927 if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
928 /** set gzip compression level - must be done per file */
929 if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
930 ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
931 Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
932 jcr->setJobStatus(JS_ErrorTerminated);
941 comp_stream_header ch;
943 memset(&ch, 0, sizeof(comp_stream_header));
946 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_LZO1X) {
947 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
948 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
949 cbuf2 = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
950 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
952 cbuf = (Bytef *)jcr->compress_buf;
953 cbuf2 = (Bytef *)jcr->compress_buf + sizeof(comp_stream_header);
954 max_compress_len = jcr->compress_buf_size; /* set max length */
956 ch.magic = COMPRESS_LZO1X;
957 ch.version = COMP_HEAD_VERSION;
958 wbuf = jcr->compress_buf; /* compressed output here */
959 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
963 const uint32_t max_compress_len = 0;
966 if (ff_pkt->flags & FO_ENCRYPT) {
967 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
968 Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
971 /** Allocate the cipher context */
972 if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true,
973 &cipher_block_size)) == NULL) {
974 /* Shouldn't happen! */
975 Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
980 * Grow the crypto buffer, if necessary.
981 * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
982 * We grow crypto_buf to the maximum number of blocks that
983 * could be returned for the given read buffer size.
984 * (Using the larger of either rsize or max_compress_len)
986 jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf,
987 (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) +
988 cipher_block_size - 1) / cipher_block_size * cipher_block_size);
990 wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
994 * Send Data header to Storage daemon
995 * <file-index> <stream> <expected stream length>
997 if (!sd->fsend("%ld %d %lld", jcr->JobFiles, stream,
998 (int64_t)ff_pkt->statp.st_size)) {
999 if (!jcr->is_job_canceled()) {
1000 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1005 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
1008 * Make space at beginning of buffer for fileAddr because this
1009 * same buffer will be used for writing if compression is off.
1011 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1012 rbuf += OFFSET_FADDR_SIZE;
1013 rsize -= OFFSET_FADDR_SIZE;
1014 #ifdef HAVE_FREEBSD_OS
1016 * To read FreeBSD partitions, the read size must be
1017 * a multiple of 512.
1019 rsize = (rsize/512) * 512;
1023 /** a RAW device read on win32 only works if the buffer is a multiple of 512 */
1025 if (S_ISBLK(ff_pkt->statp.st_mode))
1026 rsize = (rsize/512) * 512;
1030 * Read the file data
1032 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
1034 /** Check for sparse blocks */
1035 if (ff_pkt->flags & FO_SPARSE) {
1037 bool allZeros = false;
1038 if ((sd->msglen == rsize &&
1039 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
1040 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
1041 (uint64_t)ff_pkt->statp.st_size == 0)) {
1042 allZeros = is_buf_zero(rbuf, rsize);
1045 /** Put file address as first data in buffer */
1046 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1047 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
1049 fileAddr += sd->msglen; /* update file address */
1050 /** Skip block of all zeros */
1052 continue; /* skip block of zeros */
1054 } else if (ff_pkt->flags & FO_OFFSETS) {
1056 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1057 ser_uint64(ff_pkt->bfd.offset); /* store offset in begin of buffer */
1060 jcr->ReadBytes += sd->msglen; /* count bytes read */
1062 /** Uncompressed cipher input length */
1063 cipher_input_len = sd->msglen;
1065 /** Update checksum if requested */
1067 crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
1070 /** Update signing digest if requested */
1071 if (signing_digest) {
1072 crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
1076 /** Do compression if turned on */
1077 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1078 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1080 ((z_stream*)jcr->pZLIB_compress_workset)->next_in = (Bytef *)rbuf;
1081 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in = sd->msglen;
1082 ((z_stream*)jcr->pZLIB_compress_workset)->next_out = (Bytef *)cbuf;
1083 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
1085 if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1086 Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1087 jcr->setJobStatus(JS_ErrorTerminated);
1090 compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1091 /** reset zlib stream to be able to begin from scratch again */
1092 if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1093 Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1094 jcr->setJobStatus(JS_ErrorTerminated);
1098 Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", compress_len,
1101 sd->msglen = compress_len; /* set compressed length */
1102 cipher_input_len = compress_len;
1106 /** Do compression if turned on */
1107 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1108 lzo_uint len; /* TODO: See with the latest patch how to handle lzo_uint with 64bit */
1111 ser_begin(cbuf, sizeof(comp_stream_header));
1113 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1115 lzores = lzo1x_1_compress((const unsigned char*)rbuf, sd->msglen, cbuf2,
1116 &len, jcr->LZO_compress_workset);
1118 if (lzores == LZO_E_OK && compress_len <= max_compress_len) {
1119 /* complete header */
1120 ser_uint32(COMPRESS_LZO1X);
1121 ser_uint32(compress_len);
1122 ser_uint16(ch.level);
1123 ser_uint16(ch.version);
1125 /** this should NEVER happen */
1126 Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1127 jcr->setJobStatus(JS_ErrorTerminated);
1131 Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", compress_len,
1134 compress_len += sizeof(comp_stream_header); /* add size of header */
1135 sd->msglen = compress_len; /* set compressed length */
1136 cipher_input_len = compress_len;
1141 * Note, here we prepend the current record length to the beginning
1142 * of the encrypted data. This is because both sparse and compression
1143 * restore handling want records returned to them with exactly the
1144 * same number of bytes that were processed in the backup handling.
1145 * That is, both are block filters rather than a stream. When doing
1146 * compression, the compression routines may buffer data, so that for
1147 * any one record compressed, when it is decompressed the same size
1148 * will not be obtained. Of course, the buffered data eventually comes
1149 * out in subsequent crypto_cipher_update() calls or at least
1150 * when crypto_cipher_finalize() is called. Unfortunately, this
1151 * "feature" of encryption enormously complicates the restore code.
1153 if (ff_pkt->flags & FO_ENCRYPT) {
1154 uint32_t initial_len = 0;
1157 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1158 cipher_input_len += OFFSET_FADDR_SIZE;
1161 /** Encrypt the length of the input block */
1162 uint8_t packet_len[sizeof(uint32_t)];
1164 ser_begin(packet_len, sizeof(uint32_t));
1165 ser_uint32(cipher_input_len); /* store data len in begin of buffer */
1166 Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
1168 if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
1169 (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
1170 /** Encryption failed. Shouldn't happen. */
1171 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1175 /** Encrypt the input block */
1176 if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len,
1177 (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
1178 if ((initial_len + encrypted_len) == 0) {
1179 /** No full block of data available, read more data */
1182 Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len,
1184 sd->msglen = initial_len + encrypted_len; /* set encrypted length */
1186 /** Encryption failed. Shouldn't happen. */
1187 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1192 /* Send the buffer to the Storage daemon */
1193 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1194 sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
1196 sd->msg = wbuf; /* set correct write buffer */
1198 if (!jcr->is_job_canceled()) {
1199 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1204 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1206 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1207 sd->msg = msgsave; /* restore read buffer */
1209 } /* end while read file data */
1211 if (sd->msglen < 0) { /* error */
1213 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1214 ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1215 if (jcr->JobErrors++ > 1000) { /* insanity check */
1216 Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors);
1218 } else if (ff_pkt->flags & FO_ENCRYPT) {
1220 * For encryption, we must call finalize to push out any
1223 if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf,
1225 /* Padding failed. Shouldn't happen. */
1226 Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1230 /** Note, on SSL pre-0.9.7, there is always some output */
1231 if (encrypted_len > 0) {
1232 sd->msglen = encrypted_len; /* set encrypted length */
1233 sd->msg = jcr->crypto.crypto_buf; /* set correct write buffer */
1235 if (!jcr->is_job_canceled()) {
1236 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1241 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1242 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1243 sd->msg = msgsave; /* restore bnet buffer */
1247 if (!sd->signal(BNET_EOD)) { /* indicate end of file data */
1248 if (!jcr->is_job_canceled()) {
1249 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1255 /** Free the cipher context */
1257 crypto_cipher_free(cipher_ctx);
1262 /** Free the cipher context */
1264 crypto_cipher_free(cipher_ctx);
1267 sd->msg = msgsave; /* restore bnet buffer */
1272 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
1274 BSOCK *sd = jcr->store_bsock;
1275 char attribs[MAXSTRING];
1276 char attribsExBuf[MAXSTRING];
1277 char *attribsEx = NULL;
1281 int hangup = get_hangup();
1282 #ifdef FD_NO_SEND_TEST
1286 Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1287 /** Find what data stream we will use, then encode the attributes */
1288 if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1289 /* This should not happen */
1290 Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1293 encode_stat(attribs, &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream);
1295 /** Now possibly extend the attributes */
1296 if (IS_FT_OBJECT(ff_pkt->type)) {
1297 attr_stream = STREAM_RESTORE_OBJECT;
1299 attribsEx = attribsExBuf;
1300 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1303 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1306 jcr->JobFiles++; /* increment number of files sent */
1307 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
1308 pm_strcpy(jcr->last_fname, ff_pkt->fname);
1311 /* Debug code: check if we must hangup */
1312 if (hangup && (jcr->JobFiles > (uint32_t)hangup)) {
1313 Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
1319 * Send Attributes header to Storage daemon
1320 * <file-index> <stream> <info>
1322 if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1323 if (!jcr->is_canceled()) {
1324 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1329 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1332 * Send file attributes to Storage daemon
1335 * Filename (full path)
1336 * Encoded attributes
1337 * Link name (if type==FT_LNK or FT_LNKSAVED)
1338 * Encoded extended-attributes (for Win32)
1340 * or send Restore Object to Storage daemon
1344 * Object_len (possibly compressed)
1345 * Object_full_len (not compressed)
1346 * Object_compression
1349 * Binary Object data
1351 * For a directory, link is the same as fname, but with trailing
1352 * slash. For a linked file, link is the link.
1354 if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { /* already stripped */
1357 switch (ff_pkt->type) {
1360 Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
1361 stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
1362 ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
1363 ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
1368 /* Here link is the canonical filename (i.e. with trailing slash) */
1369 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1370 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
1371 attribsEx, 0, ff_pkt->delta_seq, 0);
1373 case FT_PLUGIN_CONFIG:
1374 case FT_RESTORE_FIRST:
1375 comp_len = ff_pkt->object_len;
1376 ff_pkt->object_compression = 0;
1377 if (ff_pkt->object_len > 1000) {
1378 /* Big object, compress it */
1379 comp_len = ff_pkt->object_len + 1000;
1380 POOLMEM *comp_obj = get_memory(comp_len);
1381 /* *** FIXME *** check Zdeflate error */
1382 Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
1383 if (comp_len < ff_pkt->object_len) {
1384 ff_pkt->object = comp_obj;
1385 ff_pkt->object_compression = 1; /* zlib level 9 compression */
1387 /* Uncompressed object smaller, use it */
1388 comp_len = ff_pkt->object_len;
1390 Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
1392 sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
1393 jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
1394 comp_len, ff_pkt->object_len, ff_pkt->object_compression,
1395 ff_pkt->fname, 0, ff_pkt->object_name, 0);
1396 sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
1397 memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
1398 /* Note we send one extra byte so Dir can store zero after object */
1399 sd->msglen += comp_len + 1;
1401 if (ff_pkt->object_compression) {
1402 free_and_null_pool_memory(ff_pkt->object);
1406 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
1407 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
1408 ff_pkt->delta_seq, 0);
1411 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1412 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
1413 attribsEx, 0, ff_pkt->delta_seq, 0);
1417 if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) {
1418 unstrip_path(ff_pkt);
1421 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1422 if (!stat && !jcr->is_job_canceled()) {
1423 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1426 sd->signal(BNET_EOD); /* indicate end of attributes data */
1431 * Do in place strip of path
1433 static bool do_strip(int count, char *in)
1439 /** Copy to first path separator -- Win32 might have c: ... */
1440 while (*in && !IsPathSeparator(*in)) {
1443 if (*in) { /* Not at the end of the string */
1445 numsep++; /* one separator seen */
1447 for (stripped=0; stripped<count && *in; stripped++) {
1448 while (*in && !IsPathSeparator(*in)) {
1449 in++; /* skip chars */
1452 numsep++; /* count separators seen */
1453 in++; /* skip separator */
1457 while (*in) { /* copy to end */
1458 if (IsPathSeparator(*in)) {
1464 Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1465 stripped, count, numsep, numsep>count);
1466 return stripped==count && numsep>count;
1470 * If requested strip leading components of the path so that we can
1471 * save file as if it came from a subdirectory. This is most useful
1472 * for dealing with snapshots, by removing the snapshot directory, or
1473 * in handling vendor migrations where files have been restored with
1474 * a vendor product into a subdirectory.
1476 void strip_path(FF_PKT *ff_pkt)
1478 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1479 Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1482 if (!ff_pkt->fname_save) {
1483 ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1484 ff_pkt->link_save = get_pool_memory(PM_FNAME);
1486 pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1487 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1488 pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1489 Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1490 strlen(ff_pkt->link));
1495 * Strip path. If it doesn't succeed put it back. If
1496 * it does, and there is a different link string,
1497 * attempt to strip the link. If it fails, back them
1499 * Do not strip symlinks.
1500 * I.e. if either stripping fails don't strip anything.
1502 if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1503 unstrip_path(ff_pkt);
1506 /** Strip links but not symlinks */
1507 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1508 if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1509 unstrip_path(ff_pkt);
1514 Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1518 void unstrip_path(FF_PKT *ff_pkt)
1520 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1523 strcpy(ff_pkt->fname, ff_pkt->fname_save);
1524 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1525 Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1527 strcpy(ff_pkt->link, ff_pkt->link_save);
1528 Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1529 strlen(ff_pkt->link_save));
1534 static void close_vss_backup_session(JCR *jcr)
1536 #if defined(WIN32_VSS)
1537 /* STOP VSS ON WIN32 */
1538 /* tell vss to close the backup session */
1540 if (g_pVSSClient->CloseBackup()) {
1541 /* inform user about writer states */
1542 for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1543 int msg_type = M_INFO;
1544 if (g_pVSSClient->GetWriterState(i) < 1) {
1545 msg_type = M_WARNING;
1548 Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1551 /* Generate Job global writer metadata */
1552 WCHAR *metadata = g_pVSSClient->GetMetadata();
1554 FF_PKT *ff_pkt = jcr->ff;
1555 ff_pkt->fname = (char *)"*all*"; /* for all plugins */
1556 ff_pkt->type = FT_RESTORE_FIRST;
1558 ff_pkt->object_name = (char *)"job_metadata.xml";
1559 ff_pkt->object = (char *)metadata;
1560 ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1561 ff_pkt->object_index = (int)time(NULL);
1562 save_file(jcr, ff_pkt, true);