[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bacula-devel] Patch: Migration media table update wrong source storage


<pmc@xxxxxxxxxxxxxxxxxxxxxxx> aka Peter Much schrieb
mit Datum Tue, 26 Feb 2008 17:01:36 GMT in m2n.bacula.devel:

|Abstract:
|---------
|Migration jobs may update table media.storage attribute of source
|volume with value of target volume.
|
|
|Impact:
|-------
|Any subsequent restore from that source volume may fail due to media
|mismatch.
|The reason why this went undetected seems to be that usually
|migration is used to empty the source volume, so there will be no 
|more restores from it.
|
|
|Comment:
|--------
|I am not very happy with that fix. It lacks transparency and does
|not follow an object-oriented approach.
|I have also not checked the various implications and relations of
|the involved variables under any configuration beyond the one I am
|using. In short: it just fixes my problem.
|
|
|Patch:
|------
|--- src/dird/catreq.c.orig      Fri Oct 26 19:19:39 2007
|+++ src/dird/catreq.c   Sun Feb 10 04:28:54 2008
|@@ -271,6 +271,13 @@
|       if (mr.VolBlocks != sdmr.VolBlocks) {
|          mr.LastWritten = sdmr.LastWritten;
|       }
|+      if (jcr->wstore && jcr->wstore->StorageId) {
|+         /* On migrate check if volume has been written, otherwise
|+          * the read volume would also (wrongly) updated */
|+         if (jcr->JobType != JT_MIGRATE || mr.VolBlocks != sdmr.VolBlocks) {
|+            mr.StorageId = jcr->wstore->StorageId;
|+         }
|+      }
|       /* Copy updated values to original media record */
|       mr.VolJobs      = sdmr.VolJobs;
|       mr.VolFiles     = sdmr.VolFiles;
|@@ -285,9 +292,6 @@
|       mr.VolWriteTime = sdmr.VolWriteTime;
|       mr.VolParts     = sdmr.VolParts;
|       bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
|-      if (jcr->wstore && jcr->wstore->StorageId) {
|-         mr.StorageId = jcr->wstore->StorageId;
|-      }
| 
|       Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n",
|mr.VolStatus, mr.VolumeName);
|       /*

Dear all,

I have an extension proposal to that referenced Patch, respectively
the updated version that makes it into 2.2.9.

A really funny race has happened to me. Funny, because it is
complicated, but it seems understandable and logical. It fascinated
me. 

We have said that during a migration the jobmedia record of the
/read/ Media in the Catalog might be updated, and then might use 
the storage_id value of the /write/ Media.
So now we block these updates, /if/ the used length (NumBlocks) 
of the respective Media has /not changed/ (because then it is 
likely the read Media).

Now there is one case where the used length of the read Media
will change. That is, when the read Media is written at nearly 
the same time by another job!
Unlikely as it may be, this actually happened to me - the following
way: 
A Migrate reads a job that stretches over two Volumes. At the time
when the Migrate wants to mount the next Volume, this next Volume
is currently written by another job. So the Migrate has to wait
for it. At that time the Migrate seems to have already fetched 
the Volume data from the Catalog! Now when the write completes,
that will update the Catalog. And when the Migrate finally completes
it will write back the -now oldfashioned and wrong- data - and 
because now the Size differs, this will not be catched with the new 
patch. 
At next occasion we then get a size mismatch.

This can only happen with autochangers, and it can only happen
with disk volumes - because for tape volumes it is already catched
in catreq.c - these have a count of VolFiles, which Disk Volumes
seem not to have.
Therefore I might suggest to catch it also for disk volumes.
Patch based on 2.2.9-p3

--- src/dird/catreq.c.orig	2008-03-22 10:34:20.000000000 +0100
+++ src/dird/catreq.c	2008-04-09 02:01:07.000000000 +0200
@@ -255,7 +255,7 @@
          /*
           * Insanity check for VolFiles get set to a smaller value
           */
-         if (sdmr.VolFiles < mr.VolFiles) {
+         if (sdmr.VolFiles < mr.VolFiles || sdmr.VolBlocks < mr.VolBlocks) {
             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);

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Bacula-devel mailing list
Bacula-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/bacula-devel


This mailing list archive is a service of Copilotco.