X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fcatreq.c;h=b1504fe86cadcc8f0c1464c4df6feb85a6edc184;hb=4e502c79e55a6e7de8f9109e96322481d189acd9;hp=adc03c8bd3207998b58c4749b56d837c3fed7e10;hpb=86d794263a9bddd4ff65974bbf75363e611f8b44;p=bacula%2Fbacula diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index adc03c8bd3..b1504fe86c 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -1,28 +1,14 @@ -/* - * - * Bacula Director -- catreq.c -- handles the message channel - * catalog request from the Storage daemon. - * - * Kern Sibbald, March MMI - * - * This routine runs as a thread and must be thread reentrant. - * - * Basic tasks done here: - * Handle Catalog services. - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2006 Free Software Foundation Europe e.V. + Copyright (C) 2001-2008 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 - License as published by the Free Software Foundation plus additions - that are listed in the file LICENSE. + License as published by the Free Software Foundation and included + in the file LICENSE. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -34,11 +20,25 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark ofJohn Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * + * Bacula Director -- catreq.c -- handles the message channel + * catalog request from the Storage daemon. + * + * Kern Sibbald, March MMI + * + * This routine runs as a thread and must be thread reentrant. + * + * Basic tasks done here: + * Handle Catalog services. + * + * Version $Id$ + */ #include "bacula.h" #include "dird.h" @@ -54,10 +54,10 @@ static char Find_media[] = "CatReq Job=%127s FindMedia=%d pool_name=%127s media_ static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n"; static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s" - " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u" - " VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s" - " Slot=%d relabel=%d InChanger=%d VolReadTime=%" lld " VolWriteTime=%" lld - " VolFirstWritten=%" lld " VolParts=%u\n"; + " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%lld VolMounts=%u" + " VolErrors=%u VolWrites=%u MaxVolBytes=%lld EndTime=%lld VolStatus=%10s" + " Slot=%d relabel=%d InChanger=%d VolReadTime=%lld VolWriteTime=%lld" + " VolFirstWritten=%lld VolParts=%u\n"; static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia " " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u " @@ -83,15 +83,15 @@ static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr jcr->MediaId = mr->MediaId; pm_strcpy(jcr->VolumeName, mr->VolumeName); bash_spaces(mr->VolumeName); - stat = bnet_fsend(sd, OK_media, mr->VolumeName, mr->VolJobs, + stat = sd->fsend(OK_media, mr->VolumeName, mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), mr->VolMounts, mr->VolErrors, mr->VolWrites, edit_uint64(mr->MaxVolBytes, ed2), edit_uint64(mr->VolCapacityBytes, ed3), mr->VolStatus, mr->Slot, mr->MaxVolJobs, mr->MaxVolFiles, mr->InChanger, - edit_uint64(mr->VolReadTime, ed4), - edit_uint64(mr->VolWriteTime, ed5), + edit_int64(mr->VolReadTime, ed4), + edit_int64(mr->VolWriteTime, ed5), mr->EndFile, mr->EndBlock, mr->VolParts, mr->LabelType, @@ -113,10 +113,12 @@ void catalog_request(JCR *jcr, BSOCK *bs) uint32_t Stripe; uint64_t MediaId; utime_t VolFirstWritten; + utime_t VolLastWritten; memset(&mr, 0, sizeof(mr)); memset(&sdmr, 0, sizeof(sdmr)); memset(&jm, 0, sizeof(jm)); + Dsm_check(1); /* * Request to find next appendable Volume for this Job @@ -125,7 +127,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (!jcr->db) { omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); - bnet_fsend(bs, _("1990 Invalid Catalog Request: %s"), omsg); + bs->fsend(_("1990 Invalid Catalog Request: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog request; DB not open: %s"), omsg); free_memory(omsg); return; @@ -141,8 +143,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (ok) { mr.PoolId = pr.PoolId; mr.StorageId = jcr->wstore->StorageId; - ok = find_next_volume_for_append(jcr, &mr, index, true /*permit create new vol*/); - Dmsg3(100, "find_media idx=%d ok=%d vol=%s\n", index, ok, mr.VolumeName); + 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); } /* * Send Find Media response to Storage daemon @@ -150,7 +152,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (ok) { send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { - bnet_fsend(bs, _("1901 No Media.\n")); + bs->fsend(_("1901 No Media.\n")); Dmsg0(500, "1901 No Media.\n"); } @@ -189,6 +191,9 @@ void catalog_request(JCR *jcr, BSOCK *bs) check_if_volume_valid_or_recyclable(jcr, &mr, &reason); } } + if (!reason && mr.Enabled != 1) { + reason = _("is not Enabled"); + } if (reason == NULL) { /* * Send Find Media response to Storage daemon @@ -196,12 +201,12 @@ void catalog_request(JCR *jcr, BSOCK *bs) send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { /* Not suitable volume */ - bnet_fsend(bs, _("1998 Volume \"%s\" status is %s, %s.\n"), mr.VolumeName, + bs->fsend(_("1998 Volume \"%s\" status is %s, %s.\n"), mr.VolumeName, mr.VolStatus, reason); } } else { - bnet_fsend(bs, _("1997 Volume \"%s\" not in catalog.\n"), mr.VolumeName); + bs->fsend(_("1997 Volume \"%s\" not in catalog.\n"), mr.VolumeName); Dmsg1(100, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); } @@ -213,7 +218,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs, &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors, &sdmr.VolWrites, &sdmr.MaxVolBytes, - &sdmr.LastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger, + &VolLastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime, &sdmr.VolWriteTime, &VolFirstWritten, &sdmr.VolParts) == 19) { @@ -225,7 +230,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"), mr.VolumeName, db_strerror(jcr->db)); - bnet_fsend(bs, _("1991 Catalog Request for vol=%s failed: %s"), + bs->fsend(_("1991 Catalog Request for vol=%s failed: %s"), mr.VolumeName, db_strerror(jcr->db)); db_unlock(jcr->db); return; @@ -255,13 +260,31 @@ void catalog_request(JCR *jcr, BSOCK *bs) Jmsg(jcr, M_FATAL, 0, _("Volume Files at %u being set to %u" " for Volume \"%s\". This is incorrect.\n"), mr.VolFiles, sdmr.VolFiles, mr.VolumeName); - bnet_fsend(bs, _("1992 Update Media error. VolFiles=%u, CatFiles=%u\n"), + bs->fsend(_("1992 Update Media error. VolFiles=%u, CatFiles=%u\n"), sdmr.VolFiles, mr.VolFiles); db_unlock(jcr->db); return; } } Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); + + /* + * Check if the volume has been written by the job, + * and update the LastWritten field if needed. + */ + if (mr.VolBlocks != sdmr.VolBlocks && VolLastWritten != 0) { + mr.LastWritten = VolLastWritten; + } + + /* + * Update to point to the last device used to write the Volume. + * 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) { + mr.StorageId = jcr->wstore->StorageId; + } + /* Copy updated values to original media record */ mr.VolJobs = sdmr.VolJobs; mr.VolFiles = sdmr.VolFiles; @@ -270,15 +293,15 @@ void catalog_request(JCR *jcr, BSOCK *bs) mr.VolMounts = sdmr.VolMounts; mr.VolErrors = sdmr.VolErrors; mr.VolWrites = sdmr.VolWrites; - mr.LastWritten = sdmr.LastWritten; mr.Slot = sdmr.Slot; mr.InChanger = sdmr.InChanger; - mr.VolReadTime = sdmr.VolReadTime; - mr.VolWriteTime = sdmr.VolWriteTime; mr.VolParts = sdmr.VolParts; bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus)); - if (jcr->wstore->StorageId) { - mr.StorageId = jcr->wstore->StorageId; + if (sdmr.VolReadTime >= 0) { + mr.VolReadTime = sdmr.VolReadTime; + } + if (sdmr.VolWriteTime >= 0) { + mr.VolWriteTime = sdmr.VolWriteTime; } Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName); @@ -289,7 +312,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (!db_update_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error updating Media record. %s"), db_strerror(jcr->db)); - bnet_fsend(bs, _("1993 Update Media error\n")); + bs->fsend(_("1993 Update Media error\n")); Dmsg0(400, "send error\n"); } else { (void)has_volume_expired(jcr, &mr); @@ -315,16 +338,16 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error creating JobMedia record. %s"), db_strerror(jcr->db)); - bnet_fsend(bs, _("1991 Update JobMedia error\n")); + bs->fsend(_("1992 Create JobMedia error\n")); } else { Dmsg0(400, "JobMedia record created\n"); - bnet_fsend(bs, OK_create); + bs->fsend(OK_create); } } else { omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); - bnet_fsend(bs, _("1990 Invalid Catalog Request: %s"), omsg); + bs->fsend(_("1990 Invalid Catalog Request: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog request: %s"), omsg); free_memory(omsg); } @@ -337,8 +360,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) * Update File Attributes in the catalog with data * sent by the Storage daemon. Note, we receive the whole * attribute record, but we select out only the stat packet, - * VolSessionId, VolSessionTime, FileIndex, and file name - * to store in the catalog. + * VolSessionId, VolSessionTime, FileIndex, file type, and + * file name to store in the catalog. */ void catalog_update(JCR *jcr, BSOCK *bs) { @@ -348,21 +371,23 @@ void catalog_update(JCR *jcr, BSOCK *bs) uint32_t FileIndex; uint32_t data_len; char *p; + int filetype; int len; char *fname, *attr; ATTR_DBR *ar = NULL; POOLMEM *omsg; - if (!jcr->pool->catalog_files) { - return; /* user disabled cataloging */ + Dsm_check(1); + if (job_canceled(jcr) || !jcr->pool->catalog_files) { + goto bail_out; /* user disabled cataloging */ } if (!jcr->db) { omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); - bnet_fsend(bs, _("1991 Invalid Catalog Update: %s"), omsg); + bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg); free_memory(omsg); - return; + goto bail_out; } /* Start transaction allocates jcr->attr and jcr->ar if needed */ @@ -405,6 +430,7 @@ void catalog_update(JCR *jcr, BSOCK *bs) p = jcr->attr - bs->msg + p; /* point p into jcr->attr */ skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); + filetype = str_to_int32(p); /* TODO: choose between unserialize and str_to_int32 */ skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; @@ -415,7 +441,11 @@ void catalog_update(JCR *jcr, BSOCK *bs) Dmsg1(400, "dirdattr = attr; ar->fname = fname; - ar->FileIndex = FileIndex; + if (filetype == FT_DELETED) { + ar->FileIndex = 0; /* special value */ + } else { + ar->FileIndex = FileIndex; + } ar->Stream = Stream; ar->link = NULL; if (jcr->mig_jcr) { @@ -481,4 +511,8 @@ void catalog_update(JCR *jcr, BSOCK *bs) } } } +bail_out: + if (job_canceled(jcr)) { + cancel_storage_daemon_job(jcr); + } }