From 90978629d514df0357a7842a39eba3cd1e99a0a2 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 1 Apr 2003 17:19:49 +0000 Subject: [PATCH] Documentation updates git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@408 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 2 + bacula/src/dird/catreq.c | 275 ++++++++++++++++++------------------ bacula/src/stored/acquire.c | 9 +- bacula/src/stored/mount.c | 11 +- 4 files changed, 157 insertions(+), 140 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 69054e2f85..7074895bbd 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -20,6 +20,8 @@ Testing to do: (painful) - multiple simultaneous Volumes For 1.30 release: +- add #define ENABLE_NLS for Gnome compile on SuSE. +- Need define of int_least16_t in sha1.h for SuSE. - Figure out how to use ssh to protect Bacula communications. - Fix "access not allowed" for backup of files on WinXP. - Issue message to mount a new tape before the rewind. diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 0eec8efbaf..fce8ccced9 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -8,7 +8,7 @@ * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: - * Handle Catalog services. + * Handle Catalog services. * * Version $Id$ */ @@ -85,7 +85,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) mr.PoolId = jcr->PoolId; strcpy(mr.MediaType, jcr->store->media_type); Dmsg2(120, "CatReq FindMedia: Id=%d, MediaType=%s\n", - mr.PoolId, mr.MediaType); + mr.PoolId, mr.MediaType); /* * Find the Next Volume for Append */ @@ -95,79 +95,79 @@ next_volume: Dmsg2(100, "catreq after find_next_vol ok=%d FW=%d\n", ok, mr.FirstWritten); if (!ok) { Dmsg1(200, "No next volume found. RecycleOldest=%d\n", - jcr->pool->recycle_oldest_volume); - if (jcr->pool->recycle_oldest_volume) { + jcr->pool->recycle_oldest_volume); + if (jcr->pool->recycle_oldest_volume) { Dmsg0(200, "Request to find oldest volume.\n"); - /* Find oldest volume to recycle */ - ok = db_find_next_volume(jcr, jcr->db, -1, &mr); + /* Find oldest volume to recycle */ + ok = db_find_next_volume(jcr, jcr->db, -1, &mr); Dmsg1(400, "Find oldest=%d\n", ok); - if (ok) { - UAContext ua; + if (ok) { + UAContext ua; Dmsg0(400, "Try purge.\n"); - /* Try to purge oldest volume */ - create_ua_context(jcr, &ua); - ok = purge_jobs_from_volume(&ua, &mr); - free_ua_context(&ua); - if (ok) { - ok = recycle_oldest_purged_volume(jcr, &mr); + /* Try to purge oldest volume */ + create_ua_context(jcr, &ua); + ok = purge_jobs_from_volume(&ua, &mr); + free_ua_context(&ua); + if (ok) { + ok = recycle_oldest_purged_volume(jcr, &mr); Dmsg1(400, "Recycle after recycle oldest=%d\n", ok); - } - } - } - if (!ok) { - /* Well, try finding recycled tapes */ - ok = find_recycled_volume(jcr, &mr); + } + } + } + if (!ok) { + /* Well, try finding recycled tapes */ + ok = find_recycled_volume(jcr, &mr); Dmsg2(100, "find_recycled_volume1 %d FW=%d\n", ok, mr.FirstWritten); - if (!ok) { - prune_volumes(jcr); - ok = recycle_oldest_purged_volume(jcr, &mr); + if (!ok) { + prune_volumes(jcr); + ok = recycle_oldest_purged_volume(jcr, &mr); Dmsg2(200, "find_recycled_volume2 %d FW=%d\n", ok, mr.FirstWritten); - if (!ok) { - /* See if we can create a new Volume */ - ok = newVolume(jcr, &mr); - } - } - } + if (!ok) { + /* See if we can create a new Volume */ + ok = newVolume(jcr, &mr); + } + } + } } /* Check if use duration has expired */ Dmsg2(100, "VolJobs=%d FirstWritten=%d\n", mr.VolJobs, mr.FirstWritten); if (ok && mr.VolJobs > 0 && mr.VolUseDuration > 0 && strcmp(mr.VolStatus, "Append") == 0) { - utime_t now = time(NULL); - if (mr.VolUseDuration <= (now - mr.FirstWritten)) { + utime_t now = time(NULL); + if (mr.VolUseDuration <= (now - mr.FirstWritten)) { Dmsg4(100, "Duration=%d now=%d start=%d now-start=%d\n", - (int)mr.VolUseDuration, (int)now, (int)mr.FirstWritten, - (int)(now-mr.FirstWritten)); + (int)mr.VolUseDuration, (int)now, (int)mr.FirstWritten, + (int)(now-mr.FirstWritten)); Jmsg(jcr, M_INFO, 0, _("Max configured use duration exceeded. " "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Used"); /* yes, mark as used */ - if (!db_update_media_record(jcr, jcr->db, &mr)) { + if (!db_update_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating Media record. %s"), - db_strerror(jcr->db)); - } else if (retry++ < 200) { /* sanity check */ - goto next_volume; - } else { - Jmsg(jcr, M_ERROR, 0, _( + db_strerror(jcr->db)); + } else if (retry++ < 200) { /* sanity check */ + goto next_volume; + } else { + Jmsg(jcr, M_ERROR, 0, _( "We seem to be looping trying to find the next volume. I give up. Ask operator.\n")); - } - ok = FALSE; /* give up */ - } + } + ok = FALSE; /* give up */ + } } /* * Send Find Media response to Storage daemon */ if (ok) { - char ed1[50], ed2[50], ed3[50]; - jcr->MediaId = mr.MediaId; - pm_strcpy(&jcr->VolumeName, mr.VolumeName); - bash_spaces(mr.VolumeName); - bnet_fsend(bs, 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); + char ed1[50], ed2[50], ed3[50]; + jcr->MediaId = mr.MediaId; + pm_strcpy(&jcr->VolumeName, mr.VolumeName); + bash_spaces(mr.VolumeName); + bnet_fsend(bs, 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); Dmsg1(200, "Find media: %s", bs->msg); } else { bnet_fsend(bs, "1999 No Media\n"); @@ -183,47 +183,54 @@ next_volume: */ unbash_spaces(mr.VolumeName); if (db_get_media_record(jcr, jcr->db, &mr)) { - int VolSuitable = 0; - jcr->MediaId = mr.MediaId; + int VolSuitable = 0; + char *reason = ""; /* detailed reason for rejection */ + jcr->MediaId = mr.MediaId; Dmsg1(120, "VolumeInfo MediaId=%d\n", jcr->MediaId); - pm_strcpy(&jcr->VolumeName, mr.VolumeName); - if (!writing) { - VolSuitable = 1; /* accept anything for read */ - } else { - /* - * Make sure this volume is suitable for this job, i.e. - * it is either Append or Recycle and Media Type matches - * and Pool allows any volume. - */ - if (mr.PoolId == jcr->PoolId && - (strcmp(mr.VolStatus, "Append") == 0 || - strcmp(mr.VolStatus, "Recycle") == 0) && - strcmp(mr.MediaType, jcr->store->media_type) == 0 && - jcr->pool->accept_any_volume) { - VolSuitable = 1; - } - } - if (VolSuitable) { - char ed1[50], ed2[50], ed3[50]; - /* - * Send Find Media response to Storage daemon - */ - bash_spaces(mr.VolumeName); - bnet_fsend(bs, 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); + pm_strcpy(&jcr->VolumeName, mr.VolumeName); + if (!writing) { + VolSuitable = 1; /* accept anything for read */ + } else { + /* + * SD wants to write this Volume, so make + * sure it is suitable for this job, i.e. + * Pool matches, and it is either Append or Recycle + * and Media Type matches and Pool allows any volume. + */ + if (mr.PoolId != jcr->PoolId) { + reason = "not in Pool"; + } else if (strcmp(mr.VolStatus, "Append") != 0 && + strcmp(mr.VolStatus, "Recycle") != 0) { + reason = "not Append or Recycle"; + } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) { + reason = "not correct MediaType"; + } else if (!jcr->pool->accept_any_volume) { + reason = "Volume not in sequence"; + } else { + VolSuitable = 1; + } + } + if (VolSuitable) { + char ed1[50], ed2[50], ed3[50]; + /* + * Send Find Media response to Storage daemon + */ + bash_spaces(mr.VolumeName); + bnet_fsend(bs, 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); Dmsg1(200, "Vol Info: %s", bs->msg); - } else { - /* Not suitable volume */ - bnet_fsend(bs, "1998 Volume \"%s\"not appropriate.\n", - mr.VolumeName); - } + } else { + /* Not suitable volume */ + bnet_fsend(bs, "1998 Volume \"%s\" %s.\n", + mr.VolumeName, reason); + } } else { - bnet_fsend(bs, "1999 Volume \"%s\" not found.\n", mr.VolumeName); + bnet_fsend(bs, "1999 Volume \"%s\" not in catalog.\n", mr.VolumeName); } @@ -237,17 +244,17 @@ next_volume: &sdmr.Slot, &relabel) == 14) { Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, - mr.VolStatus, sdmr.VolStatus); + mr.VolStatus, sdmr.VolStatus); bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */ 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)); + mr.VolumeName, db_strerror(jcr->db)); bnet_fsend(bs, "1991 Catalog Request failed: %s", db_strerror(jcr->db)); - return; + return; } /* Set first written time if this is first job */ if (mr.VolJobs == 0 || sdmr.VolJobs == 1) { - mr.FirstWritten = jcr->start_time; /* use Job start time as first write */ + mr.FirstWritten = jcr->start_time; /* use Job start time as first write */ } Dmsg2(200, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); /* Copy updated values to original media record */ @@ -268,48 +275,48 @@ next_volume: /* Check limits and expirations if "Append" and not a relable request */ if (strcmp(mr.VolStatus, "Append") == 0 && !relabel) { - /* First handle Max Volume Bytes */ - if ((mr.MaxVolBytes > 0 && mr.VolBytes >= mr.MaxVolBytes)) { + /* First handle Max Volume Bytes */ + if ((mr.MaxVolBytes > 0 && mr.VolBytes >= mr.MaxVolBytes)) { Jmsg(jcr, M_INFO, 0, _("Max Volume bytes exceeded. " "Marking Volume \"%s\" as Full.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Full"); - /* Now see if Volume should only be used once */ - } else if (mr.VolBytes > 0 && jcr->pool->use_volume_once) { + /* Now see if Volume should only be used once */ + } else if (mr.VolBytes > 0 && jcr->pool->use_volume_once) { Jmsg(jcr, M_INFO, 0, _("Volume used once. " "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Used"); - /* Now see if Max Jobs written to volume */ - } else if (mr.MaxVolJobs > 0 && mr.MaxVolJobs <= mr.VolJobs) { + /* Now see if Max Jobs written to volume */ + } else if (mr.MaxVolJobs > 0 && mr.MaxVolJobs <= mr.VolJobs) { Jmsg(jcr, M_INFO, 0, _("Max Volume jobs exceeded. " "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Used"); - /* Now see if Max Files written to volume */ - } else if (mr.MaxVolFiles > 0 && mr.MaxVolFiles <= mr.VolFiles) { + /* Now see if Max Files written to volume */ + } else if (mr.MaxVolFiles > 0 && mr.MaxVolFiles <= mr.VolFiles) { Jmsg(jcr, M_INFO, 0, _("Max Volume files exceeded. " "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Used"); - /* Finally, check Use duration expiration */ - } else if (mr.VolUseDuration > 0) { - utime_t now = time(NULL); - /* See if Vol Use has expired */ - if (mr.VolUseDuration <= (now - mr.FirstWritten)) { + /* Finally, check Use duration expiration */ + } else if (mr.VolUseDuration > 0) { + utime_t now = time(NULL); + /* See if Vol Use has expired */ + if (mr.VolUseDuration <= (now - mr.FirstWritten)) { Jmsg(jcr, M_INFO, 0, _("Max configured use duration exceeded. " "Marking Volume \"%s\"as Used.\n"), mr.VolumeName); strcpy(mr.VolStatus, "Used"); /* yes, mark as used */ - } - } + } + } } Dmsg2(200, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName); if (db_update_media_record(jcr, jcr->db, &mr)) { - bnet_fsend(bs, OK_update); + bnet_fsend(bs, OK_update); Dmsg0(190, "send OK\n"); } else { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating Media record. %s"), - db_strerror(jcr->db)); + db_strerror(jcr->db)); bnet_fsend(bs, "1992 Update Media error\n"); Dmsg0(190, "send error\n"); } @@ -324,14 +331,14 @@ next_volume: jm.JobId = jcr->JobId; jm.MediaId = jcr->MediaId; Dmsg6(100, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", - jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); + jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"), - db_strerror(jcr->db)); + db_strerror(jcr->db)); bnet_fsend(bs, "1991 Update JobMedia error\n"); } else { Dmsg0(100, "JobMedia record created\n"); - bnet_fsend(bs, OK_update); + bnet_fsend(bs, OK_update); } } else { @@ -365,12 +372,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg) if (!jcr->pool->catalog_files) { return; } - db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ - skip_nonspaces(&p); /* UpdCat */ + db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ + skip_nonspaces(&p); /* UpdCat */ skip_spaces(&p); - skip_nonspaces(&p); /* Job=nnn */ + skip_nonspaces(&p); /* Job=nnn */ skip_spaces(&p); - skip_nonspaces(&p); /* FileAttributes */ + skip_nonspaces(&p); /* FileAttributes */ p += 1; unser_begin(p, 0); unser_uint32(VolSessionId); @@ -385,12 +392,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg) VolSessionId, VolSessionTime, FileIndex, Stream, data_len); if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_WIN32_ATTRIBUTES) { - skip_nonspaces(&p); /* skip FileIndex */ + skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); - skip_nonspaces(&p); /* skip FileType */ + skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; - len = strlen(fname); /* length before attributes */ + len = strlen(fname); /* length before attributes */ attr = &fname[len+1]; Dmsg2(109, "dirdFileIndex != FileIndex) { Jmsg(jcr, M_WARNING, 0, "Got MD5/SHA1 but not same File as attributes\n"); } else { - /* Update signature in catalog */ - char SIGbuf[50]; /* 24 bytes should be enough */ - int len, type; - if (Stream == STREAM_MD5_SIGNATURE) { - len = 16; - type = MD5_SIG; - } else { - len = 20; - type = SHA1_SIG; - } - bin_to_base64(SIGbuf, fname, len); + /* Update signature in catalog */ + char SIGbuf[50]; /* 24 bytes should be enough */ + int len, type; + if (Stream == STREAM_MD5_SIGNATURE) { + len = 16; + type = MD5_SIG; + } else { + len = 20; + type = SHA1_SIG; + } + bin_to_base64(SIGbuf, fname, len); Dmsg3(190, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream); - if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) { + if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"), - db_strerror(jcr->db)); - } + db_strerror(jcr->db)); + } } } } diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 36781dd589..a2971c17b3 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -67,7 +67,7 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) } pm_strcpy(&jcr->VolumeName, vol->VolumeName); - for (;;) { + for (int i=0; i<5; i++) { if (job_cancelled(jcr)) { Mmsg0(&dev->errmsg, _("Job cancelled.\n")); goto get_out; /* error return */ @@ -90,6 +90,7 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Dmsg0(200, "calling read-vol-label\n"); switch (read_dev_volume_label(jcr, dev, block)) { case VOL_OK: + stat = 1; break; /* got it */ case VOL_IO_ERROR: /* @@ -123,10 +124,14 @@ default_path: } break; } + if (stat == 0) { + Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device \"%s\".\n"), + dev_name(dev)); + goto get_out; + } dev->state |= ST_READ; attach_jcr_to_device(dev, jcr); /* attach jcr to device */ - stat = 1; /* good return */ if ((dev->state & ST_TAPE) && vol->start_file > 0) { Dmsg1(200, "====== Got start_file = %d\n", vol->start_file); Jmsg(jcr, M_INFO, 0, _("Forward spacing to file %d.\n"), vol->start_file); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index ebe6031ced..2e6a8c45b5 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -53,7 +53,8 @@ int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release mount_next_vol: if (retry++ > 5) { - Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"), dev_name(dev)); + Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"), + dev_name(dev)); return 0; } if (job_cancelled(jcr)) { @@ -187,9 +188,11 @@ read_volume: /* Check if this is a valid Volume in the pool */ strcpy(jcr->VolumeName, dev->VolHdr.VolName); if (!dir_get_volume_info(jcr, 1)) { - Mmsg(&jcr->errmsg, _("Wanted Volume \"%s\".\n\ - Actual Volume \"%s\" not acceptable.\n"), - dev->VolCatInfo.VolCatName, dev->VolHdr.VolName); + Mmsg(&jcr->errmsg, _("Wanted Volume \"%s\".\n" + " Actual Volume \"%s\" not acceptable because:\n" + " %s\n"), + dev->VolCatInfo.VolCatName, dev->VolHdr.VolName, + jcr->dir_bsock->msg); /* Restore desired volume name, note device info out of sync */ memcpy(&jcr->VolCatInfo, &dev->VolCatInfo, sizeof(jcr->VolCatInfo)); goto mount_error; -- 2.39.5