X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fcatreq.c;h=ab858a90fc68a9eb9ddf3bc48203fdd9b30b7ce5;hb=87187e5526cf427d78cbc3763a8d15df70c2ea3b;hp=00af56fa38d25241265fab2d47e41aaf2fe9228e;hpb=2a9e540ed96e9604e6d1f223ee992e54de6d69a0;p=bacula%2Fbacula diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 00af56fa38..ab858a90fc 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -1,12 +1,12 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2008 Free Software Foundation Europe e.V. + Copyright (C) 2001-2010 Free Software Foundation Europe e.V. 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. @@ -37,7 +37,6 @@ * Basic tasks done here: * Handle Catalog services. * - * Version $Id$ */ #include "bacula.h" @@ -110,7 +109,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) int index, ok, label, writing; POOLMEM *omsg; POOL_DBR pr; - uint32_t Stripe; + uint32_t Stripe, Copy; uint64_t MediaId; utime_t VolFirstWritten; utime_t VolLastWritten; @@ -283,7 +282,13 @@ void catalog_request(JCR *jcr, BSOCK *bs) * the number of VolWrites has increased. */ if (jcr->wstore && jcr->wstore->StorageId && sdmr.VolWrites > mr.VolWrites) { - mr.StorageId = jcr->wstore->StorageId; + Dmsg2(050, "Update StorageId old=%d new=%d\n", + mr.StorageId, jcr->wstore->StorageId); + if (jcr->wstore->StorageId == 0) { + Jmsg(jcr, M_ERROR, 0, _("Attempt to set StorageId to zero.\n")); + } else { + mr.StorageId = jcr->wstore->StorageId; + } } /* Copy updated values to original media record */ @@ -326,7 +331,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) */ } else if (sscanf(bs->msg, Create_job_media, &Job, &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile, - &jm.StartBlock, &jm.EndBlock, &jm.Copy, &Stripe, &MediaId) == 10) { + &jm.StartBlock, &jm.EndBlock, &Copy, &Stripe, &MediaId) == 10) { if (jcr->mig_jcr) { jm.JobId = jcr->mig_jcr->JobId; @@ -368,17 +373,18 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) uint32_t VolSessionId, VolSessionTime; int32_t Stream; uint32_t FileIndex; - uint32_t data_len; char *p; int len; char *fname, *attr; ATTR_DBR *ar = NULL; + uint32_t reclen; /* Start transaction allocates jcr->attr and jcr->ar if needed */ db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ ar = jcr->ar; - /* Start by scanning directly in the message buffer to get Stream + /* + * Start by scanning directly in the message buffer to get Stream * there may be a cached attr so we cannot yet write into * jcr->attr or jcr->ar */ @@ -387,19 +393,48 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) skip_spaces(&p); skip_nonspaces(&p); /* Job=nnn */ skip_spaces(&p); - skip_nonspaces(&p); /* FileAttributes */ + skip_nonspaces(&p); /* "FileAttributes" */ p += 1; + /* The following "SD header" fields are serialized */ unser_begin(p, 0); - unser_uint32(VolSessionId); - unser_uint32(VolSessionTime); - unser_int32(FileIndex); - unser_int32(Stream); - unser_uint32(data_len); - p += unser_length(p); + unser_uint32(VolSessionId); /* VolSessionId */ + unser_uint32(VolSessionTime); /* VolSessionTime */ + unser_int32(FileIndex); /* FileIndex */ + unser_int32(Stream); /* Stream */ + unser_uint32(reclen); /* Record length */ + p += unser_length(p); /* Raw record follows */ + + /** + * At this point p points to the raw record, which varies according + * to what kind of a record (Stream) was sent. Note, the integer + * fields at the beginning of these "raw" records are in ASCII with + * spaces between them so one can use scanf or manual scanning to + * extract the fields. + * + * File Attributes + * File_index + * File type + * Filename (full path) + * Encoded attributes + * Link name (if type==FT_LNK or FT_LNKSAVED) + * Encoded extended-attributes (for Win32) + * Delta sequence number (32 bit int) + * + * Restore Object + * File_index + * File_type + * Object_index + * Object_len (possibly compressed) + * Object_full_len (not compressed) + * Object_compression + * Plugin_name + * Object_name + * Binary Object data + */ Dmsg1(400, "UpdCat msg=%s\n", msg); - Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n", - VolSessionId, VolSessionTime, FileIndex, Stream, data_len); + Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d reclen=%d\n", + VolSessionId, VolSessionTime, FileIndex, Stream, reclen); if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) { if (jcr->cached_attribute) { @@ -407,19 +442,32 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } + jcr->cached_attribute = false; } /* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */ jcr->attr = check_pool_memory_size(jcr->attr, msglen); memcpy(jcr->attr, msg, msglen); p = jcr->attr - msg + p; /* point p into jcr->attr */ - skip_nonspaces(&p); /* skip FileIndex */ + skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); - ar->FileType = str_to_int32(p); /* TODO: choose between unserialize and str_to_int32 */ - skip_nonspaces(&p); /* skip FileType */ + ar->FileType = str_to_int32(p); + skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; len = strlen(fname); /* length before attributes */ attr = &fname[len+1]; + ar->DeltaSeq = 0; + if (ar->FileType == FT_REG) { + p = attr + strlen(attr) + 1; /* point to link */ + p = p + strlen(p) + 1; /* point to extended attributes */ + p = p + strlen(p) + 1; /* point to delta sequence */ + /* + * Older FDs don't have a delta sequence, so check if it is there + */ + if (p - jcr->attr < msglen) { + ar->DeltaSeq = str_to_int32(p); /* delta_seq */ + } + } Dmsg2(400, "dirdmig_jcr) { + ro.JobId = jcr->mig_jcr->JobId; + } else { + ro.JobId = jcr->JobId; + } + + Dmsg1(100, "Robj=%s\n", p); + + skip_nonspaces(&p); /* skip FileIndex */ + skip_spaces(&p); + ro.FileType = str_to_int32(p); /* FileType */ + skip_nonspaces(&p); + skip_spaces(&p); + ro.object_index = str_to_int32(p); /* Object Index */ + skip_nonspaces(&p); + skip_spaces(&p); + ro.object_len = str_to_int32(p); /* object length possibly compressed */ + skip_nonspaces(&p); + skip_spaces(&p); + ro.object_full_len = str_to_int32(p); /* uncompressed object length */ + skip_nonspaces(&p); + skip_spaces(&p); + ro.object_compression = str_to_int32(p); /* compression */ + skip_nonspaces(&p); + skip_spaces(&p); + + ro.plugin_name = p; /* point to plugin name */ + len = strlen(ro.plugin_name); + ro.object_name = &ro.plugin_name[len+1]; /* point to object name */ + len = strlen(ro.object_name); + ro.object = &ro.object_name[len+1]; /* point to object */ + ro.object[ro.object_len] = 0; /* add zero for those who attempt printing */ + Dmsg7(100, "oname=%s stream=%d FT=%d FI=%d JobId=%d, obj_len=%d\nobj=\"%s\"\n", + ro.object_name, ro.Stream, ro.FileType, ro.FileIndex, ro.JobId, + ro.object_len, ro.object); + /* Send it */ + if (!db_create_restore_object_record(jcr, jcr->db, &ro)) { + Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db)); + } + } else if (crypto_digest_stream_type(Stream) != CRYPTO_DIGEST_NONE) { fname = p; if (ar->FileIndex != FileIndex) { @@ -508,25 +602,24 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) */ void catalog_update(JCR *jcr, BSOCK *bs) { - POOLMEM *omsg; - - if (job_canceled(jcr) || !jcr->pool->catalog_files) { - goto bail_out; /* user disabled cataloging */ + if (!jcr->pool->catalog_files) { + return; /* user disabled cataloging */ + } + if (jcr->is_job_canceled()) { + goto bail_out; } if (!jcr->db) { - omsg = get_memory(bs->msglen+1); + POOLMEM *omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg); free_memory(omsg); goto bail_out; - } - update_attribute(jcr, bs->msg, bs->msglen); bail_out: - if (job_canceled(jcr)) { + if (jcr->is_job_canceled()) { cancel_storage_daemon_job(jcr); } } @@ -549,7 +642,7 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) Dmsg0(100, "Begin despool_attributes_from_file\n"); - if (job_canceled(jcr) || !jcr->pool->catalog_files || !jcr->db) { + if (jcr->is_job_canceled() || !jcr->pool->catalog_files || !jcr->db) { goto bail_out; /* user disabled cataloging */ } @@ -584,7 +677,12 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) last = size; } } - update_attribute(jcr, msg, msglen); + if (!jcr->is_job_canceled()) { + update_attribute(jcr, msg, msglen); + if (jcr->is_job_canceled()) { + goto bail_out; + } + } } if (ferror(spool_fd)) { berrno be; @@ -599,7 +697,7 @@ bail_out: fclose(spool_fd); } - if (job_canceled(jcr)) { + if (jcr->is_job_canceled()) { cancel_storage_daemon_job(jcr); }