X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Fbackup.c;h=60beddb80c8e233f3062f3e8ee3d0e0825f02545;hb=7fc5fe1b10047210db9c20ccb415d9ac87f6eee1;hp=5faeb259dc4ac134e24b75d6dbc31dd38a7bd420;hpb=8733d549220a2e7a400be2328e3dbd7d92df9c2c;p=bacula%2Fbacula diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 5faeb259dc..60beddb80c 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -6,7 +6,7 @@ The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -61,6 +61,7 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream); static bool crypto_session_start(JCR *jcr); static void crypto_session_end(JCR *jcr); static bool crypto_session_send(JCR *jcr, BSOCK *sd); +static void close_vss_backup_session(JCR *jcr); /** * Find all the requested files and send them @@ -172,6 +173,8 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) jcr->xattr_data->nr_errors); } + close_vss_backup_session(jcr); + accurate_finish(jcr); /* send deleted or base file list to SD */ stop_heartbeat_monitor(jcr); @@ -299,6 +302,7 @@ static bool crypto_session_send(JCR *jcr, BSOCK *sd) int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { bool do_read = false; + bool plugin_started = false; int stat, data_stream; int rtnstat = 0; DIGEST *digest = NULL; @@ -336,7 +340,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_RESTORE_FIRST: - Dmsg1(00, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname); + Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ @@ -349,8 +353,13 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) case FT_NOFSCHG: /* Suppress message for /dev filesystems */ if (!is_in_fileset(ff_pkt)) { - Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into %s\n"), - ff_pkt->fname, ff_pkt->top_fname, ff_pkt->fname); +#ifdef HAVE_WIN32 + Jmsg(jcr, M_INFO, 1, _(" %s is a junction point or a different filesystem. Will not descend from %s into it.\n"), + ff_pkt->fname, ff_pkt->top_fname); +#else + Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"), + ff_pkt->fname, ff_pkt->top_fname); +#endif } ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; @@ -497,12 +506,17 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) goto bail_out; } send_plugin_name(jcr, sd, true); /* signal start of plugin data */ + plugin_started = true; } /** Send attributes -- must be done after binit() */ if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) { goto bail_out; } + /** Meta data only for restore object */ + if (ff_pkt->type == FT_RESTORE_FIRST) { + goto good_rtn; + } /** Set up the encryption context and send the session data to the SD */ if (has_file_data && jcr->crypto.pki_encrypt) { @@ -528,11 +542,12 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } + if (ff_pkt->cmd_plugin) { do_read = true; } - Dmsg1(400, "do_read=%d\n", do_read); + Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read); if (do_read) { btimer_t *tid; @@ -733,14 +748,14 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) sd->send(); sd->signal(BNET_EOD); /* end of checksum */ } - if (ff_pkt->cmd_plugin) { - send_plugin_name(jcr, sd, false); /* signal end of plugin data */ - } good_rtn: rtnstat = 1; /* good return */ bail_out: + if (ff_pkt->cmd_plugin && plugin_started) { + send_plugin_name(jcr, sd, false); /* signal end of plugin data */ + } if (digest) { crypto_digest_free(digest); } @@ -1095,8 +1110,10 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) { BSOCK *sd = jcr->store_bsock; char attribs[MAXSTRING]; - char attribsEx[MAXSTRING]; + char attribsExBuf[MAXSTRING]; + char *attribsEx = NULL; int attr_stream; + int comp_len; bool stat; #ifdef FD_NO_SEND_TEST return true; @@ -1112,7 +1129,12 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream); /** Now possibly extend the attributes */ - attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt); + if (ff_pkt->type == FT_RESTORE_FIRST) { + attr_stream = STREAM_RESTORE_OBJECT; + } else { + attribsEx = attribsExBuf; + attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt); + } Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx); @@ -1144,6 +1166,17 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) * Link name (if type==FT_LNK or FT_LNKSAVED) * Encoded extended-attributes (for Win32) * + * or send Restore Object to Storage daemon + * File_index + * File_type + * Object_index + * Object_len (possibly compressed) + * Object_full_len (not compressed) + * Object_compression + * Plugin_name + * Object_name + * Binary Object data + * * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ @@ -1164,6 +1197,37 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0); break; + case FT_RESTORE_FIRST: + comp_len = ff_pkt->object_len; + ff_pkt->object_compression = 0; + if (ff_pkt->object_len > 1000) { + /* Big object, compress it */ + int stat; + comp_len = ff_pkt->object_len + 1000; + POOLMEM *comp_obj = get_memory(comp_len); + stat = Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len); + if (comp_len < ff_pkt->object_len) { + ff_pkt->object = comp_obj; + ff_pkt->object_compression = 1; /* zlib level 9 compression */ + } else { + /* Uncompressed object smaller, use it */ + comp_len = ff_pkt->object_len; + } + Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len); + } + sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c", + jcr->JobFiles, ff_pkt->type, ff_pkt->object_index, + comp_len, ff_pkt->object_len, ff_pkt->object_compression, + ff_pkt->fname, 0, ff_pkt->object_name, 0); + sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2); + memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len); + /* Note we send one extra byte so Dir can store zero after object */ + sd->msglen += comp_len + 1; + stat = sd->send(); + if (ff_pkt->object_compression) { + free_and_null_pool_memory(ff_pkt->object); + } + break; default: stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0); @@ -1283,3 +1347,35 @@ void unstrip_path(FF_PKT *ff_pkt) sm_check(__FILE__, __LINE__, true); } } + +static void close_vss_backup_session(JCR *jcr) +{ +#if defined(WIN32_VSS) + /* STOP VSS ON WIN32 */ + /* tell vss to close the backup session */ + if (jcr->VSS) { + if (g_pVSSClient->CloseBackup()) { + /* inform user about writer states */ + for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) { + int msg_type = M_INFO; + if (g_pVSSClient->GetWriterState(i) < 1) { + msg_type = M_WARNING; + jcr->JobErrors++; + } + Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i)); + } + } + WCHAR *metadata = g_pVSSClient->GetMetadata(); + if (metadata) { + FF_PKT *ff_pkt = jcr->ff; + ff_pkt->fname = "job"; + ff_pkt->type = FT_RESTORE_FIRST; + ff_pkt->LinkFI = 0; + ff_pkt->object_name = "job_metadata.xml"; + ff_pkt->object = (char *)metadata; + ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR); + save_file(jcr, ff_pkt, true); + } + } +#endif +}