X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fcatreq.c;h=0cf0b6d92fb07e852dc4625046e30ad5461b5697;hb=9890727d214be9b91ad676e518bdbdfa7f4f4f22;hp=1f765da18b324d91a4c120f40bfa594e82c33bab;hpb=34fa5a0e5ecb8bbfe7f1ddde176f03859909b055;p=bacula%2Fbacula diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 1f765da18b..0cf0b6d92f 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-2010 Free Software Foundation Europe e.V. + Copyright (C) 2001-2012 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. @@ -114,7 +114,6 @@ void catalog_request(JCR *jcr, BSOCK *bs) utime_t VolFirstWritten; utime_t VolLastWritten; - memset(&mr, 0, sizeof(mr)); memset(&sdmr, 0, sizeof(sdmr)); memset(&jm, 0, sizeof(jm)); Dsm_check(100); @@ -141,7 +140,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) ok = db_get_pool_record(jcr, jcr->db, &pr); if (ok) { mr.PoolId = pr.PoolId; - mr.StorageId = jcr->wstore->StorageId; + set_storageid_in_mr(jcr->wstore, &mr); mr.ScratchPoolId = pr.ScratchPoolId; ok = find_next_volume_for_append(jcr, &mr, index, fnv_create_vol, fnv_prune); Dmsg3(050, "find_media ok=%d idx=%d vol=%s\n", ok, index, mr.VolumeName); @@ -201,7 +200,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { /* Not suitable volume */ - bs->fsend(_("1998 Volume \"%s\" status is %s, %s.\n"), mr.VolumeName, + bs->fsend(_("1998 Volume \"%s\" catalog status is %s, %s.\n"), mr.VolumeName, mr.VolStatus, reason); } @@ -281,14 +280,14 @@ void catalog_request(JCR *jcr, BSOCK *bs) * However, do so only if we are writing the tape, i.e. * the number of VolWrites has increased. */ - if (jcr->wstore && jcr->wstore->StorageId && sdmr.VolWrites > mr.VolWrites) { + if (jcr->wstore && sdmr.VolWrites > mr.VolWrites) { 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; - } + /* Update StorageId after write */ + set_storageid_in_mr(jcr->wstore, &mr); + } else { + /* Nothing written, reset same StorageId */ + set_storageid_in_mr(NULL, &mr); } /* Copy updated values to original media record */ @@ -357,6 +356,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog request: %s"), omsg); free_memory(omsg); } + Dmsg1(400, ">CatReq response: %s", bs->msg); Dmsg1(400, "Leave catreq jcr 0x%x\n", jcr); return; @@ -393,8 +393,9 @@ 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); /* VolSessionId */ unser_uint32(VolSessionTime); /* VolSessionTime */ @@ -403,9 +404,32 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) 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 + * 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); @@ -416,7 +440,7 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) if (jcr->cached_attribute) { Dmsg2(400, "Cached attr. Stream=%d fname=%s\n", ar->Stream, ar->fname); if (!db_create_attributes_record(jcr, jcr->db, ar)) { - Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); + Jmsg1(jcr, M_FATAL, 0, _("Attribute create error: ERR=%s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } @@ -424,14 +448,26 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) 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, "dirdJobId = jcr->JobId; } - /* - * Restore object */ - if (ar->FileType == FT_RESTORE_FIRST) { - ROBJECT_DBR ro; - POOLMEM *attrEx = get_pool_memory(PM_MESSAGE); - char *p; - memset(&ro, 0, sizeof(ro)); - ro.full_fname = fname; - ro.Stream = Stream; - ro.FileType = ar->FileType; - ro.FileIndex = FileIndex; - ro.JobId = ar->JobId; - p = ar->attr; /* point to attributes */ - while (*p++ != 0) /* skip attributes */ - { } - while (*p++ != 0) /* skip link */ - { } - /* We have an object, so do a binary copy */ - ro.object_len = msglen + jcr->attr - p; - attrEx = check_pool_memory_size(attrEx, ro.object_len + 1); - memcpy(attrEx, p, ro.object_len); - ro.object = attrEx; - /* Add a EOS for those who attempt to print the object */ - p = attrEx + ro.object_len; - *p = 0; - Dmsg7(000, "fname=%s stream=%d FT=%d FI=%d JobId=%d, obj_len=%d\nobj=\"%s\"\n", - ro.full_fname, ro.Stream, ro.FileType, ro.FileIndex, ro.JobId, - ro.object_len, attrEx); - /* 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)); - } - free_pool_memory(attrEx); - } else { - ar->Digest = NULL; - ar->DigestType = CRYPTO_DIGEST_NONE; - jcr->cached_attribute = true; - } + ar->Digest = NULL; + ar->DigestType = CRYPTO_DIGEST_NONE; + jcr->cached_attribute = true; 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) { - Jmsg(jcr, M_WARNING, 0, _("Got %s but not same File as attributes\n"), stream_to_ascii(Stream)); + Jmsg3(jcr, M_WARNING, 0, _("%s not same File=%d as attributes=%d\n"), + stream_to_ascii(Stream), FileIndex, ar->FileIndex); } else { /* Update digest in catalog */ char digestbuf[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; @@ -587,8 +635,7 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) bool ret=false; int32_t pktsiz; size_t nbytes; - ssize_t last = 0, size = 0; - int count = 0; + ssize_t size = 0; int32_t msglen; /* message length */ POOLMEM *msg = get_pool_memory(PM_MESSAGE); FILE *spool_fd=NULL; @@ -626,9 +673,6 @@ bool despool_attributes_from_file(JCR *jcr, const char *file) goto bail_out; } size += nbytes; - if ((++count & 0x3F) == 0) { - last = size; - } } if (!jcr->is_job_canceled()) { update_attribute(jcr, msg, msglen);