]> git.sur5r.net Git - bacula/bacula/commitdiff
kes When doing a label, pass the VolBytes back to the Director,
authorKern Sibbald <kern@sibbald.com>
Sat, 2 Sep 2006 17:18:08 +0000 (17:18 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 2 Sep 2006 17:18:08 +0000 (17:18 +0000)
     which puts it in the catalog.
kes  Print an error message if the user attempts to prune an
     archived Volume.
kes  Need to start using %ld when sscanfing 32 bit values.
kes  Update the free
kes  Correct the counting of VolCatBytes for DVDs.
kes  Add code to mount.c to require that VolCatBytes corresponds to
     what is actually found when doing an append.
kes  Update freespace only after writing on the DVD.
kes  Remove code that blows away the current part in the spool file.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3401 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/kernstodo
bacula/src/dird/ua_label.c
bacula/src/dird/ua_prune.c
bacula/src/lib/attr.c
bacula/src/lib/bpipe.c
bacula/src/lib/btime.c
bacula/src/lib/scan.c
bacula/src/stored/askdir.c
bacula/src/stored/block.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dircmd.c
bacula/src/stored/dvd.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/version.h
bacula/technotes-1.39

index 5a301625519c695698817945abb15b7b1ef39e9a..4b5e303f54aefb040053826ad07c3cb762b27d04 100644 (file)
@@ -33,6 +33,8 @@ Document:
 Priority:
 
 For 1.39:
+- When reading through parts on the DVD, the DVD is mounted and
+  unmounted for each part.
 - Restricted consoles start in the Default catalog even if it
   is not permitted.
 - Make sure that the restore options don't permit "seeing" other
@@ -1654,4 +1656,6 @@ Block Position: 0
 - Fix ClientRunBefore/AfterJob compatibility.
 - Ensure that connection to daemon failure always indicates what
   daemon it was trying to connect to.
+- Freespace on DVD requested over and over even with no intervening
+  writes.
 
index c7d546f4b56b771165b9f0cb470f513ab22732df..b60ba3df9329b9098c9942b26569ebdcc7177a50 100644 (file)
@@ -540,7 +540,7 @@ static void label_from_barcodes(UAContext *ua, int drive)
        */
       if (is_cleaning_tape(ua, &mr, &pr)) {
          if (media_record_exists) {      /* we update it */
-            mr.VolBytes = 1;
+            mr.VolBytes = 1;             /* any bytes to indicate it exists */
             bstrncpy(mr.VolStatus, "Cleaning", sizeof(mr.VolStatus));
             mr.MediaType[0] = 0;
             mr.StorageId = store->StorageId;
@@ -630,6 +630,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    char dev_name[MAX_NAME_LENGTH];
    bool ok = false;
    bool is_dvd = false;
+   uint64_t VolBytes = 0;
 
    if (!(sd=open_sd_bsock(ua))) {
       return false;
@@ -659,13 +660,13 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    }
 
    while (bnet_recv(sd) >= 0) {
+      int dvd;
       bsendmsg(ua, "%s", sd->msg);
-      if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
+      if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu DVD=%d ", &VolBytes,
+                 &dvd) == 2) {
+         is_dvd = dvd;
          ok = true;
       }
-      if (strncmp(sd->msg, "3000 OK label. DVD=1 ", 21) == 0) {
-         is_dvd = true;
-      }
    }
    unbash_spaces(mr->VolumeName);
    unbash_spaces(mr->MediaType);
@@ -679,7 +680,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    }
    if (ok) {
       if (media_record_exists) {      /* we update it */
-         mr->VolBytes = 1;
+         mr->VolBytes = VolBytes;
          mr->InChanger = 1;
          mr->StorageId = ua->jcr->wstore->StorageId;
          if (!db_update_media_record(ua->jcr, ua->db, mr)) {
@@ -688,7 +689,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
          }
       } else {                        /* create the media record */
          set_pool_dbr_defaults_in_media_dbr(mr, pr);
-         mr->VolBytes = 1;               /* flag indicating Volume labeled */
+         mr->VolBytes = VolBytes;
          mr->InChanger = 1;
          mr->StorageId = ua->jcr->wstore->StorageId;
          mr->Enabled = 1;
index dd0b8aa8698993c692fec4f2c0bca5c2e025bda5..fb530d51c9ac6fefca193aa58d7eda2354fe13d2 100644 (file)
@@ -174,6 +174,10 @@ int prunecmd(UAContext *ua, const char *cmd)
       if (!select_pool_and_media_dbr(ua, &pr, &mr)) {
          return false;
       }
+      if (mr.Enabled == 2) {
+         bsendmsg(ua, _("Cannot prune Volume \"%s\" because it is archived.\n"),
+            mr.VolumeName);
+      }
       if (!confirm_retention(ua, &mr.VolRetention, "Volume")) {
          return false;
       }
index 34a0088d94b595bf685cbe74ee290452c52f5950..ac509288cd641fd6c447cb882b27e45f3fbb3470 100644 (file)
@@ -59,7 +59,7 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr)
     */
    attr->stream = stream;
    Dmsg1(400, "Attr: %s\n", rec);
-   if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) {
+   if (sscanf(rec, "%ld %ld", &attr->file_index, &attr->type) != 2) {
       Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec);
       Dmsg1(100, "\nError scanning attributes. %s\n", rec);
       return 0;
index 7b1535e4b0b5e8ac49598806a438ce1c78cc56f1..e20a3dea733a0b3f6da3e8bb2101dc6d6c1239f2 100644 (file)
@@ -247,7 +247,7 @@ int close_bpipe(BPIPE *bpipe)
       stop_child_timer(bpipe->timer_id);
    }
    free(bpipe);
-   Dmsg2(200, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
+   Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
    return stat;
 }
 
index 79fc7578f96af9ccc57b86e865a97ffab1fb1aab..7011b74a9dda4f83560f9f95c1b3952c75be1a68 100644 (file)
@@ -4,22 +4,17 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   Copyright (C) 2000-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   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 along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -34,8 +29,8 @@
  *     and is 1 Jan 1970 at 0:0 UTC
  *
  *  The major two times that should be left are:
- *     btime_t (64 bit integer in microseconds base Epoch)
- *     utime_t (64 bit integer in seconds base Epoch)
+ *     btime_t  (64 bit integer in microseconds base Epoch)
+ *     utime_t  (64 bit integer in seconds base Epoch)
  */
 
 #include "bacula.h"
@@ -111,7 +106,7 @@ utime_t str_to_utime(char *str)
    time_t ttime;
 
    if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
-                                       &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+                                        &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
       return 0;
    }
    if (tm.tm_mon > 0) {
@@ -168,7 +163,7 @@ utime_t btime_to_utime(btime_t bt)
  */
 int tm_wom(int mday, int wday)
 {
-   int fs;                      /* first sunday */
+   int fs;                       /* first sunday */
    fs = (mday%7) - wday;
    if (fs <= 0) {
       fs += 7;
@@ -234,7 +229,7 @@ void get_current_time(struct date_time *dt)
 }
 
 
-/*  date_encode  --  Encode civil date as a Julian day number. */
+/*  date_encode  --  Encode civil date as a Julian day number.  */
 
 /* Deprecated. Do not use. */
 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
@@ -252,44 +247,44 @@ fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
     y = year;
 
     if (m <= 2) {
-       y--;
-       m += 12;
+        y--;
+        m += 12;
     }
 
     /* Determine whether date is in Julian or Gregorian calendar based on
        canonical date of calendar reform. */
 
     if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
-       b = 0;
+        b = 0;
     } else {
-       a = ((int) (y / 100));
-       b = 2 - a + (a / 4);
+        a = ((int) (y / 100));
+        b = 2 - a + (a / 4);
     }
 
     return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
-               day + b - 1524.5);
+                day + b - 1524.5);
 }
 
 /*  time_encode  --  Encode time from hours, minutes, and seconds
-                    into a fraction of a day.  */
+                     into a fraction of a day.  */
 
 /* Deprecated. Do not use. */
 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
-                  float32_t second_fraction)
+                   float32_t second_fraction)
 {
     ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
     return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
-                    second_fraction;
+                     second_fraction;
 }
 
 /*  date_time_encode  --  Set day number and fraction from date
-                         and time.  */
+                          and time.  */
 
 /* Deprecated. Do not use. */
 void date_time_encode(struct date_time *dt,
-                     uint32_t year, uint8_t month, uint8_t day,
-                     uint8_t hour, uint8_t minute, uint8_t second,
-                     float32_t second_fraction)
+                      uint32_t year, uint8_t month, uint8_t day,
+                      uint8_t hour, uint8_t minute, uint8_t second,
+                      float32_t second_fraction)
 {
     dt->julian_day_number = date_encode(year, month, day);
     dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
@@ -299,7 +294,7 @@ void date_time_encode(struct date_time *dt,
 
 /* Deprecated. Do not use. */
 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
-                uint8_t *day)
+                 uint8_t *day)
 {
     fdate_t z, f, a, alpha, b, c, d, e;
 
@@ -308,10 +303,10 @@ void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
     f = date - z;
 
     if (z < 2299161.0) {
-       a = z;
+        a = z;
     } else {
-       alpha = floor((z - 1867216.25) / 36524.25);
-       a = z + 1 + alpha - floor(alpha / 4);
+        alpha = floor((z - 1867216.25) / 36524.25);
+        a = z + 1 + alpha - floor(alpha / 4);
     }
 
     b = a + 1524;
@@ -328,7 +323,7 @@ void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
 
 /* Deprecated. Do not use. */
 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
-                uint8_t *second, float32_t *second_fraction)
+                 uint8_t *second, float32_t *second_fraction)
 {
     uint32_t ij;
 
@@ -337,30 +332,30 @@ void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
     *minute = (uint8_t) ((ij / 60L) % 60L);
     *second = (uint8_t) (ij % 60L);
     if (second_fraction != NULL) {
-       *second_fraction = (float32_t)(time - floor(time));
+        *second_fraction = (float32_t)(time - floor(time));
     }
 }
 
 /*  date_time_decode  --  Decode a Julian day and day fraction
-                         into civil date and time.  */
+                          into civil date and time.  */
 
 /* Deprecated. Do not use. */
 void date_time_decode(struct date_time *dt,
-                     uint32_t *year, uint8_t *month, uint8_t *day,
-                     uint8_t *hour, uint8_t *minute, uint8_t *second,
-                     float32_t *second_fraction)
+                      uint32_t *year, uint8_t *month, uint8_t *day,
+                      uint8_t *hour, uint8_t *minute, uint8_t *second,
+                      float32_t *second_fraction)
 {
     date_decode(dt->julian_day_number, year, month, day);
     time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
 }
 
 /*  tm_encode  --  Encode a civil date and time from a tm structure
- *                to a Julian day and day fraction.
+ *                 to a Julian day and day fraction.
  */
 
 /* Deprecated. Do not use. */
 void tm_encode(struct date_time *dt,
-                     struct tm *tm)
+                      struct tm *tm)
 {
     uint32_t year;
     uint8_t month, day, hour, minute, second;
@@ -377,11 +372,11 @@ void tm_encode(struct date_time *dt,
 
 
 /*  tm_decode  --  Decode a Julian day and day fraction
-                  into civil date and time in tm structure */
+                   into civil date and time in tm structure */
 
 /* Deprecated. Do not use. */
 void tm_decode(struct date_time *dt,
-                     struct tm *tm)
+                      struct tm *tm)
 {
     uint32_t year;
     uint8_t month, day, hour, minute, second;
@@ -398,21 +393,21 @@ void tm_decode(struct date_time *dt,
 
 
 /*  date_time_compare  --  Compare two dates and times and return
-                          the relationship as follows:
+                           the relationship as follows:
 
-                                   -1    dt1 < dt2
-                                    0    dt1 = dt2
-                                    1    dt1 > dt2
+                                    -1    dt1 < dt2
+                                     0    dt1 = dt2
+                                     1    dt1 > dt2
 */
 
 /* Deprecated. Do not use. */
 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
 {
     if (dt1->julian_day_number == dt2->julian_day_number) {
-       if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
-           return 0;
-       }
-       return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
+        if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
+            return 0;
+        }
+        return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
     }
     return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;
 }
index 53c40242104bf875df494576396a809dad3f7ab2..5e9403fd54a5f59889bd99b52d8c319f8e6cb2d8 100644 (file)
@@ -339,7 +339,9 @@ switch_top:
             }
             vp = (void *)va_arg(ap, void *);
 //          Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp);
-            if (l < 2) {
+            if (l == 0) {
+               *((int *)vp) = (int)value;
+            } else if (l == 1) {
                *((uint32_t *)vp) = (uint32_t)value;
 //             Dmsg0(000, "Store 32 bit int\n");
             } else {
index be5411e3cf69ebdafc6b85d1976149631a054c24..54e125d92c58f142c98ffc58ad227ac3d76b86fa 100644 (file)
@@ -41,12 +41,12 @@ static char Job_status[]     = "Status Job=%s JobStatus=%d\n";
 
 
 /* Responses received from the Director */
-static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u"
-   " VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u"
-   " MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s"
-   " Slot=%d MaxVolJobs=%u MaxVolFiles=%u InChanger=%d"
-   " VolReadTime=%" lld " VolWriteTime=%" lld " EndFile=%u EndBlock=%u"
-   " VolParts=%u LabelType=%d";
+static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%lu"
+   " VolBlocks=%lu VolBytes=%lld VolMounts=%lu VolErrors=%lu VolWrites=%lu"
+   " MaxVolBytes=%lld VolCapacityBytes=%lld VolStatus=%20s"
+   " Slot=%ld MaxVolJobs=%lu MaxVolFiles=%lu InChanger=%ld"
+   " VolReadTime=%lld VolWriteTime=%lld EndFile=%lu EndBlock=%lu"
+   " VolParts=%lu LabelType=%ld";
 
 
 static char OK_create[] = "1000 OK CreateJobMedia\n";
@@ -153,7 +153,7 @@ static bool do_get_volume_info(DCR *dcr)
     BSOCK *dir = jcr->dir_bsock;
     VOLUME_CAT_INFO vol;
     int n;
-    int InChanger;
+    int32_t InChanger;
 
     dcr->VolumeName[0] = 0;           /* No volume */
     if (bnet_recv(dir) <= 0) {
@@ -302,7 +302,6 @@ bool dir_update_volume_info(DCR *dcr, bool label)
    /* Just labeled or relabeled the tape */
    if (label) {
       bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
-      vol->VolCatBytes = 1;           /* indicates tape labeled */
    }
    pm_strcpy(VolumeName, vol->VolCatName);
    bash_spaces(VolumeName);
index 69f9ab616b15e34f366b976fd6fd211e3fce2e66..2c5f5c9ff96487064bce61786c8c77436149c066 100644 (file)
@@ -570,8 +570,9 @@ bool write_block_to_dev(DCR *dcr)
    }
 
    /* We successfully wrote the block, now do housekeeping */
-
-   dev->VolCatInfo.VolCatBytes += block->binbuf;
+   Dmsg2(400, "VolCatBytes=%d newVolCatBytes=%d\n", (int)dev->VolCatInfo.VolCatBytes,
+      (int)(dev->VolCatInfo.VolCatBytes+wlen));
+   dev->VolCatInfo.VolCatBytes += wlen;         
    dev->VolCatInfo.VolCatBlocks++;
    dev->EndBlock = dev->block_num;
    dev->EndFile  = dev->file;
@@ -836,6 +837,10 @@ static bool do_dvd_size_checks(DCR *dcr)
          return false;
       }
    }
+
+   if (!dev->is_freespace_ok()) {
+      update_free_space_dev(dev);
+   }
    
    if (!dev->is_freespace_ok()) { /* Error while getting free space */
       char ed1[50], ed2[50];
index 6fe9210bad5a81635c8974c9cb98a27caf72405d..f3c4b4d55ee7a4882a40bb882e4a55e20e575592 100644 (file)
@@ -167,7 +167,7 @@ int main(int margc, char *margv[])
    }
    x32 = 123456789;
    bsnprintf(buf, sizeof(buf), "%u", x32);
-   i = bsscanf(buf, "%u", &y32);
+   i = bsscanf(buf, "%lu", &y32);
    if (i != 1 || x32 != y32) {
       Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32);
       exit(1);
index 1cdf259efc03ff39706c8e8ffd0eaee96c8e5f20..2ba6fa455f48a577a46c29c7f47166cfd7898246 100644 (file)
@@ -1783,12 +1783,12 @@ void DEVICE::close()
       int status;
 
       part = num_dvd_parts;
-      Dmsg3(100, "Remove empty part in close call make_dvd_filename. part=%d num=%d vol=%s\n", 
-         part, num_dvd_parts, VolCatInfo.VolCatName);
       make_spooled_dvd_filename(this, archive_name);
       /* Check that the part file is empty */
       status = stat(archive_name.c_str(), &statp);
       if (status == 0 && statp.st_size == 0) {
+         Dmsg3(100, "Unlink empty part in close call make_dvd_filename. part=%d num=%d vol=%s\n", 
+                part, num_dvd_parts, VolCatInfo.VolCatName);
          Dmsg1(100, "unlink(%s)\n", archive_name.c_str());
          unlink(archive_name.c_str());
          set_part_spooled(false);        /* no spooled part left */
index 877b4b01b2cfc66c6ee3a12c70a09abb35e57ec4..eb8fb3671874ffeba6c3259fa21b170c0748052e 100644 (file)
@@ -391,13 +391,14 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
    int label_status;
    int mode;
    const char *volname = (relabel == 0) ? newname : oldname;
+   char ed1[50];
 
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
 
    Dmsg0(90, "try_autoload_device - looking for volume_info\n");
    if (relabel && dev->is_dvd()) {
-      dcr->VolCatInfo.VolCatParts=1;
+      dcr->VolCatInfo.VolCatParts=0;
    }
 
    if (!try_autoload_device(dcr->jcr, slot, volname)) {
@@ -462,8 +463,9 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
       }
       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
       /* The following 3000 OK label. string is scanned in ua_label.c */
-      bnet_fsend(dir, "3000 OK label. DVD=%d Volume=\"%s\" Device=\"%s\"\n",
-         dev->is_dvd()?1:0, newname, dev->print_name());
+      bnet_fsend(dir, "3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n",
+                 edit_uint64(dev->VolCatInfo.VolCatBytes, ed1),
+                 dev->is_dvd()?1:0, newname, dev->print_name());
       break;
    case VOL_NO_MEDIA:
       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
index 6c826ba4c3ab1d118cfc497811d754334810f1f2..bfa47a4a0bf3a1fd42d8a0358aaaab52dcfed646 100644 (file)
@@ -138,7 +138,7 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
    Dmsg1(20, "Run mount prog=%s\n", ocmd.c_str());
    while ((status = run_program_full_output(ocmd.c_str(), 
                        dev->max_open_wait/2, results)) != 0) {
-      Dmsg2(99, "Mount status=%d result=%s\n", status, results);
+      Dmsg2(20, "Mount status=%d result=%s\n", status, results);
       /* Doesn't work with internationalization (This is not a problem) */
       if (mount && fnmatch("*is already mounted on*", results, 0) == 0) {
          break;
@@ -261,6 +261,10 @@ bool update_free_space_dev(DEVICE* dev)
    char ed1[50];
    bool ok = false;
    int status;
+
+   if (!dev->is_dvd() || dev->is_freespace_ok()) {
+      return true;
+   }
    
    /* The device must be mounted in order to dvd-freespace to work */
    mount_dvd(dev, 1);
@@ -271,7 +275,7 @@ bool update_free_space_dev(DEVICE* dev)
    if (!icmd) {
       dev->free_space = 0;
       dev->free_space_errno = 0;
-      dev->clear_freespace_ok();   /* No valid freespace */
+      dev->clear_freespace_ok();              /* No valid freespace */
       dev->clear_media();
       Dmsg2(29, "ERROR: update_free_space_dev: free_space=%s, free_space_errno=%d (!icmd)\n", 
             edit_uint64(dev->free_space, ed1), dev->free_space_errno);
@@ -292,6 +296,7 @@ bool update_free_space_dev(DEVICE* dev)
       berrno be;
       Dmsg1(20, "Run freespace prog=%s\n", ocmd.c_str());
       status = run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results);
+      Dmsg2(20, "Freespace status=%d result=%s\n", status, results);
       if (status == 0) {
          free = str_to_int64(results);
          Dmsg1(400, "Free space program run: Freespace=%s\n", results);
@@ -352,6 +357,8 @@ bool dvd_write_part(DCR *dcr)
    DEVICE *dev = dcr->dev;
    POOL_MEM archive_name(PM_FNAME);
    
+   dev->clear_freespace_ok();             /* need to update freespace */
+
    /* Don't write empty part files.
     * This is only useful when growisofs does not support write beyond
     * the 4GB boundary.
@@ -409,14 +416,17 @@ bool dvd_write_part(DCR *dcr)
     * in case of a serious emergency.
     */
 
-   if (dev->part == 1)
+   if (dev->part == 1) {
       timeout = 16000;
-   else
+   } else {
       timeout = dev->max_open_wait + (dev->part_size/(1350*1024/4));
+   }
 
-   Dmsg2(20, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
+   Dmsg2(20, "Write part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
    status = run_program_full_output(ocmd.c_str(), timeout, results.c_str());
+   Dmsg2(20, "Write part status=%d result=%s\n", status, results.c_str());
 
+   dev->truncated_dvd = false;
    if (status != 0) {
       Jmsg2(dcr->jcr, M_FATAL, 0, _("Error writing part %d to the DVD: ERR=%s\n"),
          dev->part, results.c_str());
@@ -426,19 +436,15 @@ bool dvd_write_part(DCR *dcr)
       dev->dev_errno = EIO;
       mark_volume_in_error(dcr);
       sm_check(__FILE__, __LINE__, false);
-      dev->truncated_dvd = false;
       return false;
    }
    Jmsg(dcr->jcr, M_INFO, 0, _("Part %d written to DVD.\n"), dev->part);
    Dmsg2(400, "dvd_write_part: Part %d written to DVD\nResults: %s\n",
             dev->part, results.c_str());
     
-   if (dev->truncated_dvd) {
-      dev->truncated_dvd = false;      /* turn off flag */
-   } else {                            /* DVD part written */
-      dev->num_dvd_parts++;            /* there is now one more part on DVD */
-      dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
-   }
+   dev->num_dvd_parts++;            /* there is now one more part on DVD */
+   dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
+   Dmsg1(000, "Update num_parts=%d\n", dev->num_dvd_parts);
 
    /* Delete spool file */
    make_spooled_dvd_filename(dev, archive_name);
@@ -507,6 +513,7 @@ int dvd_open_next_part(DCR *dcr)
    dev->part++;
    Dmsg2(29, "Inc part=%d num_dvd_parts=%d\n", dev->part, dev->num_dvd_parts);
 
+   /* Are we working on a part past what is written in the DVD? */
    if (dev->num_dvd_parts < dev->part) {
       POOL_MEM archive_name(PM_FNAME);
       struct stat buf;
@@ -514,7 +521,7 @@ int dvd_open_next_part(DCR *dcr)
        * First check what is on DVD.  If our part is there, we
        *   are in trouble, so bail out.
        * NB: This is however not a problem if we are writing the first part.
-       * It simply means that we are overriding an existing volume...
+       * It simply means that we are over writing an existing volume...
        */
       if (dev->num_dvd_parts > 0) {
          make_mounted_dvd_filename(dev, archive_name);   /* makes dvd name */
@@ -527,13 +534,14 @@ int dvd_open_next_part(DCR *dcr)
          }
       }
 
+#ifdef neeeded
       Dmsg2(400, "num_dvd_parts=%d part=%d\n", dev->num_dvd_parts, dev->part);
       make_spooled_dvd_filename(dev, archive_name);   /* makes spool name */
       
       /* Check if the next part exists in spool directory . */
-      Dmsg1(100, "Check if part on spool: $s\n", archive_name.c_str());
+      Dmsg1(100, "Check if part on spool: %s\n", archive_name.c_str());
       if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
-         Dmsg1(29, "open_next_part %s is in the way, deleting it...\n", archive_name.c_str());
+         Dmsg1(29, "======= Part %s is in the way, deleting it...\n", archive_name.c_str());
          /* Then try to unlink it */
          if (unlink(archive_name.c_str()) < 0) {
             berrno be;
@@ -543,6 +551,7 @@ int dvd_open_next_part(DCR *dcr)
             return -1;
          }
       }
+#endif
    }
 
    Dmsg2(400, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, 
@@ -740,7 +749,8 @@ bool dvd_close_job(DCR *dcr)
    JCR *jcr = dcr->jcr;
    bool ok = true;
 
-   /* If the device is a dvd and WritePartAfterJob
+   /*
+    * If the device is a dvd and WritePartAfterJob
     * is set to yes, open the next part, so, in case of a device
     * that requires mount, it will be written to the device.
     */
@@ -853,7 +863,7 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr)
    struct dirent *entry, *result;
    int name_max;
    int count = 0;
-   bool matched = false;
+   bool matched = true;
    struct stat filestat;
       
    name_max = pathconf(".", _PC_NAME_MAX);
index b51ec456618c677baa8f41d436ba309d26279887..0e18e92ea4557261b6dc14cb1b21c908ee85eecf 100644 (file)
@@ -399,6 +399,9 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
       Dmsg0(200, "Error from write volume label.\n");
       return false;
    }
+
+   dev->VolCatInfo.VolCatBytes = 0;        /* reset byte count */
+
    /*
     * If we are not dealing with a streaming device,
     *  write the block now to ensure we have write permission.
@@ -446,7 +449,6 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
    /* Set or reset Volume statistics */
    dev->VolCatInfo.VolCatJobs = 0;
    dev->VolCatInfo.VolCatFiles = 0;
-   dev->VolCatInfo.VolCatBytes = 1;
    dev->VolCatInfo.VolCatErrors = 0;
    dev->VolCatInfo.VolCatBlocks = 0;
    dev->VolCatInfo.VolCatRBytes = 0;
@@ -558,7 +560,7 @@ void create_volume_label(DEVICE *dev, const char *VolName,
 
    bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
    dev->VolHdr.VerNum = BaculaTapeVersion;
-   if (dev->is_dvd()) {
+   if (dvdnow) {
       /* We do not want to re-label a DVD so write VOL_LABEL now */
       dev->VolHdr.LabelType = VOL_LABEL;
    } else {
index 83494eb715fd0748a3a3066f6e0218856e810342..61443a6e7f8370fbc5926024fca8628b11820f1e 100644 (file)
@@ -339,6 +339,22 @@ read_volume:
          mark_volume_in_error(dcr);
          goto mount_next_vol;
       }
+      if (dev->is_dvd()) {
+         char ed1[50], ed2[50];
+         if (dev->VolCatInfo.VolCatBytes == dev->part_start + dev->part_size) {
+            Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
+                 " part=%d size=%s\n"), dcr->VolumeName, 
+                 dev->part, edit_uint64(dev->VolCatInfo.VolCatBytes,ed1));
+         } else {
+            Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because: "
+                 "The sizes do not match! Volume=%s Catalog=%s\n"),
+                 dcr->VolumeName,
+                 edit_uint64(dev->part_start + dev->part_size, ed1),
+                 edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
+            mark_volume_in_error(dcr);
+            goto mount_next_vol;
+         }
+      }
       /* *****FIXME**** we should do some checking for files too */
       if (dev->is_tape()) {
          /*
@@ -350,7 +366,7 @@ read_volume:
                  dcr->VolumeName, dev_file(dev));
          } else {
             Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because:\n"
-"The number of files mismatch! Volume=%u Catalog=%u\n"),
+                 "The number of files mismatch! Volume=%u Catalog=%u\n"),
                  dcr->VolumeName, dev_file(dev), dev->VolCatInfo.VolCatFiles);
             mark_volume_in_error(dcr);
             goto mount_next_vol;
index a4a6aa51dfce4e7dd4082f715c88c5cdf3ec5ec1..b15923ae6d6d12f338875d58cb86d3d3d3c3e72d 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "1.39.21"
-#define BDATE   "01 Septermber 2006"
-#define LSMDATE "01Sep06"
+#define BDATE   "02 Septermber 2006"
+#define LSMDATE "02Sep06"
 #define BYEAR "2006"       /* year for copyright messages in progs */
 
 /* Debug flags */
index 76063d427d12e6030fd296e93e128c57db1de30e..c35abe0968623e423b1c45eb9eab3ac59b10c126 100644 (file)
@@ -1,6 +1,18 @@
               Technical notes on version 1.39  
 
 General:
+02Sep06
+kes  When doing a label, pass the VolBytes back to the Director,
+     which puts it in the catalog.
+kes  Print an error message if the user attempts to prune an
+     archived Volume.
+kes  Need to start using %ld when sscanfing 32 bit values.
+kes  Update the free
+kes  Correct the counting of VolCatBytes for DVDs. 
+kes  Add code to mount.c to require that VolCatBytes corresponds to
+     what is actually found when doing an append.
+kes  Update freespace only after writing on the DVD.
+kes  Remove code that blows away the current part in the spool file.
 01Sep06
 kes  Apply new dvd-handler patch from Richard Mortimer.
 kes  Tweak so that debug level 20 shows only DVD commands.