]> git.sur5r.net Git - bacula/bacula/commitdiff
- DVD writing/reading seems to be mostly working.
authorKern Sibbald <kern@sibbald.com>
Sat, 18 Jun 2005 13:22:36 +0000 (13:22 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 18 Jun 2005 13:22:36 +0000 (13:22 +0000)
- Set execute bits on dvd-freespace and dvd-writepart
- Make dvd-freespace use existing dummy file.
- Modify dvd-freespace to pickup size from Track Size:

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

20 files changed:
bacula/Makefile.in
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/kes-1.37
bacula/scripts/dvd-freespace.in
bacula/scripts/dvd-writepart.in
bacula/src/lib/bpipe.c
bacula/src/lib/signal.c
bacula/src/stored/acquire.c
bacula/src/stored/butil.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/dvd.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/reserve.c
bacula/src/version.h

index ccdec6f3c18fd3ba5266239be7d6dc69aae7a2c6..abc9c6f4b7338c8d032b68203aaf2e2b1d9950b1 100755 (executable)
@@ -163,8 +163,9 @@ Makefile: Makefile.in
 Makefiles:
        $(SHELL) config.status
        (cd scripts; \
-       chmod 755 startmysql stopmysql bacula fd startit stopit btraceback; \
-       chmod 755 mtx-changer bconsole gconsole devel_bacula)
+       chmod 755 startmysql stopmysql bacula startit stopit btraceback; \
+       chmod 755 mtx-changer bconsole gconsole devel_bacula; \
+       chmod 755 dvd-freespace dvd-writepart)
 
        (cd src/cats; \
        chmod 755 create_bacula_database      update_bacula_tables     make_bacula_tables; \
index 2a7b01e454338fbb0b2d43556b2d23c5e72acef3..d03826333090ad4bebb12d42c3c86d82bc5f864e 100644 (file)
@@ -1983,6 +1983,7 @@ AC_OUTPUT([autoconf/Make.common \
 
 cd scripts
 chmod 755 startmysql stopmysql bacula startit stopit btraceback mtx-changer
+chmod 755 dvd-writepart dvd-freespace
 chmod 755 bconsole gconsole mtx-changer devel_bacula logrotate
 cd ..
 
index a351ee5f2909d1bb7c2fa973c3102e80b1e7cdbc..22b70a59fc0ba133fad74547195e6d72d1dd7e70 100755 (executable)
@@ -23116,6 +23116,7 @@ fi
 
 cd scripts
 chmod 755 startmysql stopmysql bacula startit stopit btraceback mtx-changer
+chmod 755 dvd-writepart dvd-freespace
 chmod 755 bconsole gconsole mtx-changer devel_bacula logrotate
 cd ..
 
index 6fa8ae7c342247bc5872292efc89cf13d81cc88c..8afdc5d36132d7fef26654dfbf70d3943b76d933 100644 (file)
@@ -16,13 +16,9 @@ Version 1.37                Kern (see below)
 #7   Single Job Writing to Multiple Storage Devices
      (probably not this version)
 
-##   Integrate web-bacula into a new Bacula project with
-     bimagemgr.
 ##   Create a new GUI chapter explaining all the GUI programs.
 
 Autochangers:
-- 7. Implement new Console commands to allow offlining/reserving drives,
-     and possibly manipulating the autochanger (much asked for).
 -    Make "update slots" when pointing to Autochanger, remove
      all Volumes from other drives.  "update slots all-drives"?
 
@@ -53,22 +49,8 @@ Document:
 - Document the multiple-drive-changer.txt script.
 
 For 1.37:
-- Add # Job Level date to bsr file
-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-=== rate design
-  jcr->last_rate
-  jcr->last_runtime
-  MA = (last_MA * 3 + rate) / 4
-  rate = (bytes - last_bytes) / (runtime - last_runtime)
-- Despool attributes simultaneously with data in a separate
-  thread, rejoined at end of data spooling.
-- Implement Files/Bytes,... stats for restore job.
-- Implement Total Bytes Written, ... for restore job.
 - Add setting Volume State via Python.
-- Max Vols limit in Pool off by one?
 - Make bootstrap file handle multiple MediaTypes (SD)
-- Test restoring into a user restricted directory on Win32 -- see
-  bug report.
 - --without-openssl breaks at least on Solaris.
 - Python:
   - Make a callback when Rerun failed levels is called.
@@ -88,13 +70,25 @@ For 1.37:
 - Add global lock on all devices when creating a device structure.
 
 Maybe in 1.37:
-- Add start/end date editing in messages (%t %T, %e?) ...
-- Add ClientDefs similar to JobDefs.
-- Print more info when bextract -p accepts a bad block.
 - To mark files as deleted, run essentially a Verify to disk, and
   when a file is found missing (MarkId != JobId), then create
   a new File record with FileIndex == -1. This could be done
   by the FD at the same time as the backup.
+=== rate design
+  jcr->last_rate
+  jcr->last_runtime
+  MA = (last_MA * 3 + rate) / 4
+  rate = (bytes - last_bytes) / (runtime - last_runtime)
+- Max Vols limit in Pool off by one?
+- Implement Files/Bytes,... stats for restore job.
+- Implement Total Bytes Written, ... for restore job.
+- Despool attributes simultaneously with data in a separate
+  thread, rejoined at end of data spooling.
+- 7. Implement new Console commands to allow offlining/reserving drives,
+     and possibly manipulating the autochanger (much asked for).
+- Add start/end date editing in messages (%t %T, %e?) ...
+- Add ClientDefs similar to JobDefs.
+- Print more info when bextract -p accepts a bad block.
 - Fix FD JobType to be set before RunBeforeJob in FD.
 - Look at adding full Volume and Pool information to a Volume 
   label so that bscan can get *all* the info. 
@@ -1288,3 +1282,8 @@ Block Position: 0
      in an Autochanger.
 - Upgrade to MySQL 4.1.12 See:  
   http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
+- Add # Job Level date to bsr file
+- Implement "PreferMountedVolumes = yes|no" in Job resource.
+##   Integrate web-bacula into a new Bacula project with
+     bimagemgr.
+
index 866b5cc78b2c083ac1d0ab882e13ece9568e68a2..786fae41e811a437f297cfa5586fa59e17021fa7 100644 (file)
@@ -4,6 +4,11 @@
 General:
 
 Changes to 1.37.24:
+18Jun05
+- DVD writing/reading seems to be mostly working.
+- Set execute bits on dvd-freespace and dvd-writepart
+- Make dvd-freespace use existing dummy file.
+- Modify dvd-freespace to pickup size from Track Size:
 16Jun05
 - Add Date, Job, level to updates to .bsr file in 
   dird/backup.c
index 105e6d922f6c578cfe164e84beeee4d0d6122d7c..7503260ee7edce2988d2b7b573f271479d50b1e6 100755 (executable)
@@ -32,7 +32,6 @@ growisofsparams=""
 import popen2
 import os
 import errno
-import tempfile
 import sys
 
 if len(sys.argv) != 3:
@@ -54,10 +53,18 @@ def gettotalsize():
       sys.exit(0)
    if os.WEXITSTATUS(status) != 0:
       print -errno.EPIPE
-      print 'Cannot get media info.'
+      print "Cannot get media info from " + dvdrwmediainfo
       sys.exit(0)
    while 1:
       result = processi.fromchild.readline()
+      if result.find("Track Size:") > -1:
+        index = result.find("*2KB")
+        if index > 0: 
+           return long(result[12:index]) * 2048
+        else:
+           print -errno.EPIPE
+           print "Invalid format in media info lead-out line from " + dvdrwmediainfo
+           sys.exit(0)
       if result.find("Legacy lead-out at:") > -1:
         index = result.find("=")
         if index > -1:
@@ -66,7 +73,7 @@ def gettotalsize():
               print -errno.EPIPE
               print "Invalid format in media info lead-out line from " + dvdrwmediainfo
               sys.exit(0)
-           return int(res)
+           return long(res)
         else:
            print -errno.EPIPE
            print "Invalid format in media info lead-out line from " + dvdrwmediainfo
@@ -76,12 +83,12 @@ def gettotalsize():
         print "Cannot get media lead-out index from " + dvdrwmediainfo
         sys.exit(0)
 
-tmpfile = tempfile.NamedTemporaryFile()
 if part_num == 0:
    flag = "-Z"
 else:
    flag = "-M"
-cmd=growisofs + " " + growisofsparams + " -use-the-force-luke=tty -dry-run -quiet " + flag + " " + device + " -R " + tmpfile.name
+# the growisofs at the end is a dummy
+cmd=growisofs + " " + growisofsparams + " -use-the-force-luke=tty -dry-run -quiet " + flag + " " + device + " -R " + growisofs
 process = popen2.Popen4(cmd)
 status = process.wait()
 if not os.WIFEXITED(status):
@@ -111,10 +118,10 @@ while 1:
         print -errno.EPIPE
         print "Wrong seek argument in the output from " + growisofs
         sys.exit(0)
-      size = int(res)*32*1024
+      size = long(res)*32*1024
       size = gettotalsize()-(size+margin)
       if size < 0:
         size = 0
       print size
-      print "No error occured"
+      print "No error occurred"
       sys.exit(0)
index 43734d2a0026d53d3b16a391eeb5c5e01b146182..5de917c8e4c308555d6059b64762bfe1333aeb24 100644 (file)
@@ -26,7 +26,7 @@ GROWARGS="-use-the-force-luke=tty -quiet"
 #GROWARGS="${GROWARGS} -use-the-force-luke=notray"
 
 # Uncomment the following line if you have a Linux kernel >=2.6.8, and
-# if you want to allow a session to start behind the 4gb boundary.
+# if you want to allow a session to start beyond the 4gb boundary.
 #GROWARGS="${GROWARGS} -use-the-force-luke=4gms"
 
 #### You should probably not modify anything below this line
index 4778b84aad62cbb50e69b9ac5f0975947e5d3eb2..1002e70ba616689c37be3bd19438e7edaf14fe3a 100644 (file)
@@ -30,7 +30,7 @@
 #include "jcr.h"
 
 int execvp_errors[] = {EACCES, ENOEXEC, EFAULT, EINTR, E2BIG,
-                    ENAMETOOLONG, ENOMEM, ETXTBSY, ENOENT};
+                     ENAMETOOLONG, ENOMEM, ETXTBSY, ENOENT};
 int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int));
 
 
@@ -61,7 +61,7 @@ BPIPE *open_bpipe(char *prog, int wait, const char *mode)
    tprog = get_pool_memory(PM_FNAME);
    pm_strcpy(tprog, prog);
    build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
-#ifdef xxxxxx
+#ifdef  xxxxxx
    printf("argc=%d\n", bargc);
    for (i=0; i<bargc; i++) {
       printf("argc=%d argv=%s:\n", i, bargv[i]);
@@ -79,8 +79,8 @@ BPIPE *open_bpipe(char *prog, int wait, const char *mode)
    if (mode_read && pipe(readp) == -1) {
       save_errno = errno;
       if (mode_write) {
-        close(writep[0]);
-        close(writep[1]);
+         close(writep[0]);
+         close(writep[1]);
       }
       free(bpipe);
       errno = save_errno;
@@ -88,50 +88,50 @@ BPIPE *open_bpipe(char *prog, int wait, const char *mode)
    }
    /* Start worker process */
    switch (bpipe->worker_pid = fork()) {
-   case -1:                          /* error */
+   case -1:                           /* error */
       save_errno = errno;
       if (mode_write) {
-        close(writep[0]);
-        close(writep[1]);
+         close(writep[0]);
+         close(writep[1]);
       }
       if (mode_read) {
-        close(readp[0]);
-        close(readp[1]);
+         close(readp[0]);
+         close(readp[1]);
       }
       free(bpipe);
       errno = save_errno;
       return NULL;
 
-   case 0:                           /* child */
+   case 0:                            /* child */
       if (mode_write) {
-        close(writep[1]);
-        dup2(writep[0], 0);          /* Dup our write to his stdin */
+         close(writep[1]);
+         dup2(writep[0], 0);          /* Dup our write to his stdin */
       }
       if (mode_read) {
-        close(readp[0]);             /* Close unused child fds */
-        dup2(readp[1], 1);           /* dup our read to his stdout */
-        dup2(readp[1], 2);           /*   and his stderr */
+         close(readp[0]);             /* Close unused child fds */
+         dup2(readp[1], 1);           /* dup our read to his stdout */
+         dup2(readp[1], 2);           /*   and his stderr */
       }
-      closelog();                    /* close syslog if open */
-      for (i=3; i<=32; i++) {        /* close any open file descriptors */
-        close(i);
+      closelog();                     /* close syslog if open */
+      for (i=3; i<=32; i++) {         /* close any open file descriptors */
+         close(i);
       }
-      execvp(bargv[0], bargv);       /* call the program */
+      execvp(bargv[0], bargv);        /* call the program */
       /* Convert errno into an exit code for later analysis */
       for (i=0; i< num_execvp_errors; i++) {
-        if (execvp_errors[i] == errno) {
-           exit(200 + i);            /* exit code => errno */
-        }
+         if (execvp_errors[i] == errno) {
+            exit(200 + i);            /* exit code => errno */
+         }
       }
-      exit(255);                     /* unknown errno */
+      exit(255);                      /* unknown errno */
 
 
 
-   default:                          /* parent */
+   default:                           /* parent */
       break;
    }
    if (mode_read) {
-      close(readp[1]);               /* close unused parent fds */
+      close(readp[1]);                /* close unused parent fds */
       bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
    }
    if (mode_write) {
@@ -154,7 +154,7 @@ int close_wpipe(BPIPE *bpipe)
    if (bpipe->wfd) {
       fflush(bpipe->wfd);
       if (fclose(bpipe->wfd) != 0) {
-        stat = 0;
+         stat = 0;
       }
       bpipe->wfd = NULL;
    }
@@ -165,7 +165,7 @@ int close_wpipe(BPIPE *bpipe)
  * Close both pipes and free resources
  *
  *  Returns: 0 on success
- *          berrno on failure
+ *           berrno on failure
  */
 int close_bpipe(BPIPE *bpipe)
 {
@@ -187,7 +187,7 @@ int close_bpipe(BPIPE *bpipe)
    }
 
    if (bpipe->wait == 0) {
-      wait_option = 0;               /* wait indefinitely */
+      wait_option = 0;                /* wait indefinitely */
    } else {
       wait_option = WNOHANG;          /* don't hang */
    }
@@ -197,37 +197,37 @@ int close_bpipe(BPIPE *bpipe)
    for ( ;; ) {
       Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
       do {
-        wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
+         wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
       } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
       if (wpid == bpipe->worker_pid || wpid == -1) {
-        stat = errno;
+         stat = errno;
          Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
             wpid==-1?strerror(errno):"none");
-        break;
+         break;
       }
       Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
             wpid==-1?strerror(errno):"none");
       if (remaining_wait > 0) {
-        bmicrosleep(1, 0);           /* wait one second */
-        remaining_wait--;
+         bmicrosleep(1, 0);           /* wait one second */
+         remaining_wait--;
       } else {
-        stat = ETIME;                /* set error status */
-        wpid = -1;
+         stat = ETIME;                /* set error status */
+         wpid = -1;
          break;                       /* don't wait any longer */
       }
    }
    if (wpid > 0) {
       if (WIFEXITED(chldstatus)) {    /* process exit()ed */
-        stat = WEXITSTATUS(chldstatus);
-        if (stat != 0) {
+         stat = WEXITSTATUS(chldstatus);
+         if (stat != 0) {
             Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
-           stat |= b_errno_exit;        /* exit status returned */
-        }
+            stat |= b_errno_exit;        /* exit status returned */
+         }
          Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
       } else if (WIFSIGNALED(chldstatus)) {  /* process died */
-        stat = WTERMSIG(chldstatus);
+         stat = WTERMSIG(chldstatus);
          Dmsg1(800, "Child died from signale %d\n", stat);
-        stat |= b_errno_signal;      /* exit signal returned */
+         stat |= b_errno_signal;      /* exit signal returned */
       }
    }
    if (bpipe->timer_id) {
@@ -247,7 +247,7 @@ int close_bpipe(BPIPE *bpipe)
  * Contrary to my normal calling conventions, this program
  *
  *  Returns: 0 on success
- *          non-zero on error == berrno status
+ *           non-zero on error == berrno status
  */
 int run_program(char *prog, int wait, POOLMEM *results)
 {
@@ -264,9 +264,9 @@ int run_program(char *prog, int wait, POOLMEM *results)
       results[0] = 0;
       fgets(results, sizeof_pool_memory(results), bpipe->rfd);
       if (feof(bpipe->rfd)) {
-        stat1 = 0;
+         stat1 = 0;
       } else {
-        stat1 = ferror(bpipe->rfd);
+         stat1 = ferror(bpipe->rfd);
       }
       if (stat1 < 0) {
          Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
@@ -291,7 +291,7 @@ int run_program(char *prog, int wait, POOLMEM *results)
  * Contrary to my normal calling conventions, this program
  *
  *  Returns: 0 on success
- *          non-zero on error == berrno status
+ *           non-zero on error == berrno status
  *
  */
 int run_program_full_output(char *prog, int wait, POOLMEM *results)
@@ -320,24 +320,24 @@ int run_program_full_output(char *prog, int wait, POOLMEM *results)
       Dmsg1(800, "Run program fgets=%s", tmp);
       pm_strcat(results, tmp);
       if (feof(bpipe->rfd)) {
-        stat1 = 0;
-         Dmsg1(100, "Run program fgets stat=%d\n", stat1);
-        break;
+         stat1 = 0;
+         Dmsg1(900, "Run program fgets stat=%d\n", stat1);
+         break;
       } else {
-        stat1 = ferror(bpipe->rfd);
+         stat1 = ferror(bpipe->rfd);
       }
       if (stat1 < 0) {
-         Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
-        break;
+         Dmsg2(900, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
+         break;
       } else if (stat1 != 0) {
-         Dmsg1(100, "Run program fgets stat=%d\n", stat1);
+         Dmsg1(900, "Run program fgets stat=%d\n", stat1);
       }
    }
    
    stat2 = close_bpipe(bpipe);
    stat1 = stat2 != 0 ? stat2 : stat1;
    
-   Dmsg1(100, "Run program returning %d\n", stat);
+   Dmsg1(900, "Run program returning %d\n", stat);
    free_pool_memory(tmp);
    return stat1;
 }
@@ -365,25 +365,25 @@ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv)
    }
    if (*p) {
       while (*p && argc < MAX_ARGV) {
-        q = p;
-        if (quote) {
-           while (*q && *q != quote)
-           q++;
-           quote = 0;
-        } else {
+         q = p;
+         if (quote) {
+            while (*q && *q != quote)
+            q++;
+            quote = 0;
+         } else {
             while (*q && *q != ' ')
-           q++;
-        }
-        if (*q)
+            q++;
+         }
+         if (*q)
             *(q++) = '\0';
-        bargv[argc++] = p;
-        p = q;
+         bargv[argc++] = p;
+         p = q;
          while (*p && (*p == ' ' || *p == '\t'))
-           p++;
+            p++;
          if (*p == '\"' || *p == '\'') {
-           quote = *p;
-           p++;
-        }
+            quote = *p;
+            p++;
+         }
       }
    }
    *bargc = argc;
index 7d03d2b85ef233109b3259a6d4c5769ef5564564..83333deb58490d740b48e6dcff782a40ee70acce 100644 (file)
@@ -75,7 +75,7 @@ extern "C" void signal_handler(int sig)
    if (already_dead) {
       exit(1);
    }
-   Dmsg2(200, "sig=%d %s\n", sig, sig_names[sig]);
+   Dmsg2(900, "sig=%d %s\n", sig, sig_names[sig]);
    /* Ignore certain signals -- SIGUSR2 used to interrupt threads */
    if (sig == SIGCHLD || sig == SIGUSR2) {
       return;
@@ -98,33 +98,33 @@ extern "C" void signal_handler(int sig)
       int exelen = strlen(exepath);
 
       fprintf(stderr, "Kaboom! %s, %s got signal %d. Attempting traceback.\n",
-             exename, my_name, sig);
+              exename, my_name, sig);
       fprintf(stderr, "Kaboom! exepath=%s\n", exepath);
 
       if (exelen + 12 > (int)sizeof(btpath)) {
-        bstrncpy(btpath, "btraceback", sizeof(btpath));
+         bstrncpy(btpath, "btraceback", sizeof(btpath));
       } else {
-        bstrncpy(btpath, exepath, sizeof(btpath));
-        if (btpath[exelen-1] == '/') {
-           btpath[exelen-1] = 0;
-        }
-        bstrncat(btpath, "/btraceback", sizeof(btpath));
+         bstrncpy(btpath, exepath, sizeof(btpath));
+         if (btpath[exelen-1] == '/') {
+            btpath[exelen-1] = 0;
+         }
+         bstrncat(btpath, "/btraceback", sizeof(btpath));
       }
       if (exepath[exelen-1] != '/') {
-        strcat(exepath, "/");
+         strcat(exepath, "/");
       }
       strcat(exepath, exename);
       if (!working_directory) {
-        working_directory = buf;
-        *buf = 0;
+         working_directory = buf;
+         *buf = 0;
       }
       if (*working_directory == 0) {
-        strcpy((char *)working_directory, "/tmp/");
+         strcpy((char *)working_directory, "/tmp/");
       }
       if (chdir(working_directory) != 0) {  /* dump in working directory */
-        berrno be;
-        Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory,  be.strerror());
-        strcpy((char *)working_directory, "/tmp/");
+         berrno be;
+         Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory,  be.strerror());
+         strcpy((char *)working_directory, "/tmp/");
       }
       unlink("./core");               /* get rid of any old core file */
       sprintf(pid_buf, "%d", (int)main_pid);
@@ -132,21 +132,21 @@ extern "C" void signal_handler(int sig)
       Dmsg1(300, "btpath=%s\n", btpath);
       Dmsg1(300, "exepath=%s\n", exepath);
       switch (pid = fork()) {
-      case -1:                       /* error */
-        fprintf(stderr, "Fork error: ERR=%s\n", strerror(errno));
-        break;
-      case 0:                        /* child */
-        argv[0] = btpath;            /* path to btraceback */
-        argv[1] = exepath;           /* path to exe */
-        argv[2] = pid_buf;
-        argv[3] = (char *)NULL;
-        fprintf(stderr, "Calling: %s %s %s\n", btpath, exepath, pid_buf);
-        if (execv(btpath, argv) != 0) {
-           printf("execv: %s failed: ERR=%s\n", btpath, strerror(errno));
-        }
-        exit(-1);
-      default:                       /* parent */
-        break;
+      case -1:                        /* error */
+         fprintf(stderr, "Fork error: ERR=%s\n", strerror(errno));
+         break;
+      case 0:                         /* child */
+         argv[0] = btpath;            /* path to btraceback */
+         argv[1] = exepath;           /* path to exe */
+         argv[2] = pid_buf;
+         argv[3] = (char *)NULL;
+         fprintf(stderr, "Calling: %s %s %s\n", btpath, exepath, pid_buf);
+         if (execv(btpath, argv) != 0) {
+            printf("execv: %s failed: ERR=%s\n", btpath, strerror(errno));
+         }
+         exit(-1);
+      default:                        /* parent */
+         break;
       }
       /* Parent continue here, waiting for child */
       sigdefault.sa_flags = 0;
@@ -155,15 +155,15 @@ extern "C" void signal_handler(int sig)
 
       sigaction(sig,  &sigdefault, NULL);
       if (pid > 0) {
-        Dmsg0(500, "Doing waitpid\n");
-        waitpid(pid, NULL, 0);       /* wait for child to produce dump */
-        fprintf(stderr, "Traceback complete, attempting cleanup ...\n");
-        Dmsg0(500, "Done waitpid\n");
-        exit_handler(sig);           /* clean up if possible */
-        Dmsg0(500, "Done exit_handler\n");
+         Dmsg0(500, "Doing waitpid\n");
+         waitpid(pid, NULL, 0);       /* wait for child to produce dump */
+         fprintf(stderr, "Traceback complete, attempting cleanup ...\n");
+         Dmsg0(500, "Done waitpid\n");
+         exit_handler(sig);           /* clean up if possible */
+         Dmsg0(500, "Done exit_handler\n");
       } else {
-        Dmsg0(500, "Doing sleep\n");
-        bmicrosleep(30, 0);
+         Dmsg0(500, "Doing sleep\n");
+         bmicrosleep(30, 0);
       }
       fprintf(stderr, "It looks like the traceback worked ...\n");
    }
@@ -274,65 +274,65 @@ void init_signals(void terminate(int sig))
    sigfillset(&sigdefault.sa_mask);
 
 
-   sigaction(SIGPIPE,  &sigignore, NULL);
-   sigaction(SIGCHLD,  &sighandle, NULL);
-   sigaction(SIGCONT,  &sigignore, NULL);
-   sigaction(SIGPROF,  &sigignore, NULL);
-   sigaction(SIGWINCH, &sigignore, NULL);
-   sigaction(SIGIO,    &sighandle, NULL);
+   sigaction(SIGPIPE,   &sigignore, NULL);
+   sigaction(SIGCHLD,   &sighandle, NULL);
+   sigaction(SIGCONT,   &sigignore, NULL);
+   sigaction(SIGPROF,   &sigignore, NULL);
+   sigaction(SIGWINCH,  &sigignore, NULL);
+   sigaction(SIGIO,     &sighandle, NULL);
 
-   sigaction(SIGINT,   &sigdefault, NULL);
-   sigaction(SIGXCPU,  &sigdefault, NULL);
-   sigaction(SIGXFSZ,  &sigdefault, NULL);
+   sigaction(SIGINT,    &sigdefault, NULL);
+   sigaction(SIGXCPU,   &sigdefault, NULL);
+   sigaction(SIGXFSZ,   &sigdefault, NULL);
 
-   sigaction(SIGHUP,   &sigignore, NULL);
-   sigaction(SIGQUIT,  &sighandle, NULL);
-   sigaction(SIGILL,   &sighandle, NULL);
-   sigaction(SIGTRAP,  &sighandle, NULL);
-/* sigaction(SIGABRT,  &sighandle, NULL);   */
+   sigaction(SIGHUP,    &sigignore, NULL);
+   sigaction(SIGQUIT,   &sighandle, NULL);
+   sigaction(SIGILL,    &sighandle, NULL);
+   sigaction(SIGTRAP,   &sighandle, NULL);
+/* sigaction(SIGABRT,   &sighandle, NULL);   */
 #ifdef SIGEMT
-   sigaction(SIGEMT,   &sighandle, NULL);
+   sigaction(SIGEMT,    &sighandle, NULL);
 #endif
 #ifdef SIGIOT
-/* sigaction(SIGIOT,   &sighandle, NULL);  used by debugger */
+/* sigaction(SIGIOT,    &sighandle, NULL);  used by debugger */
 #endif
-   sigaction(SIGBUS,   &sighandle, NULL);
-   sigaction(SIGFPE,   &sighandle, NULL);
-   sigaction(SIGKILL,  &sighandle, NULL);
-   sigaction(SIGUSR1,  &sighandle, NULL);
-   sigaction(SIGSEGV,  &sighandle, NULL);
-   sigaction(SIGUSR2,  &sighandle, NULL);
-   sigaction(SIGALRM,  &sighandle, NULL);
-   sigaction(SIGTERM,  &sighandle, NULL);
+   sigaction(SIGBUS,    &sighandle, NULL);
+   sigaction(SIGFPE,    &sighandle, NULL);
+   sigaction(SIGKILL,   &sighandle, NULL);
+   sigaction(SIGUSR1,   &sighandle, NULL);
+   sigaction(SIGSEGV,   &sighandle, NULL);
+   sigaction(SIGUSR2,   &sighandle, NULL);
+   sigaction(SIGALRM,   &sighandle, NULL);
+   sigaction(SIGTERM,   &sighandle, NULL);
 #ifdef SIGSTKFLT
    sigaction(SIGSTKFLT, &sighandle, NULL);
 #endif
-   sigaction(SIGSTOP,  &sighandle, NULL);
-   sigaction(SIGTSTP,  &sighandle, NULL);
-   sigaction(SIGTTIN,  &sighandle, NULL);
-   sigaction(SIGTTOU,  &sighandle, NULL);
-   sigaction(SIGURG,   &sighandle, NULL);
+   sigaction(SIGSTOP,   &sighandle, NULL);
+   sigaction(SIGTSTP,   &sighandle, NULL);
+   sigaction(SIGTTIN,   &sighandle, NULL);
+   sigaction(SIGTTOU,   &sighandle, NULL);
+   sigaction(SIGURG,    &sighandle, NULL);
    sigaction(SIGVTALRM, &sighandle, NULL);
 #ifdef SIGPWR
-   sigaction(SIGPWR,   &sighandle, NULL);
+   sigaction(SIGPWR,    &sighandle, NULL);
 #endif
 #ifdef SIGWAITING
    sigaction(SIGWAITING,&sighandle, NULL);
 #endif
 #ifdef SIGLWP
-   sigaction(SIGLWP,   &sighandle, NULL);
+   sigaction(SIGLWP,    &sighandle, NULL);
 #endif
 #ifdef SIGFREEZE
    sigaction(SIGFREEZE, &sighandle, NULL);
 #endif
 #ifdef SIGTHAW
-   sigaction(SIGTHAW,  &sighandle, NULL);
+   sigaction(SIGTHAW,   &sighandle, NULL);
 #endif
 #ifdef SIGCANCEL
    sigaction(SIGCANCEL, &sighandle, NULL);
 #endif
 #ifdef SIGLOST
-   sigaction(SIGLOST,  &sighandle, NULL);
+   sigaction(SIGLOST,   &sighandle, NULL);
 #endif
 }
 #endif
index c33cd835db0330632ffd368f725928833215d9ad..fea9842ebb4bcb2dc2339fd7600b4acec399741f 100644 (file)
@@ -246,7 +246,7 @@ default_path:
          
          /* If the device requires mount, close it, so the device can be ejected.
           * FIXME: This should perhaps be done for all devices. */
-         if (dev_cap(dev, CAP_REQMOUNT)) {
+         if (dev->requires_mount()) {
             force_close_device(dev);
          }
          
index 3af683fa1c7b3904d73a1e066d2315e436fe1eeb..c4cda7c9d2833f3ba9e006a09da0ac808e7d60ed 100644 (file)
@@ -165,6 +165,7 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
    create_restore_volume_list(jcr);
 
    if (mode) {                        /* read only access? */
+      Dmsg0(100, "Acquire device for read\n");
       if (!acquire_device_for_read(dcr)) {
          return NULL;
       }
index 9b26837d6cb2dbc493671ba4d7f009a8115a50d1..b9bc31921a6fcc52daf83322f4f7f32ce526dc3b 100644 (file)
@@ -181,7 +181,7 @@ init_dev(JCR *jcr, DEVRES *device)
     * - Check that the mount point is available 
     * - Check that (un)mount commands are defined
     */
-   if (dev->is_file() && device->cap_bits & CAP_REQMOUNT) {
+   if (dev->is_file() && dev->requires_mount()) {
       if (stat(device->mount_point, &statp) < 0) {
          berrno be;
          dev->dev_errno = errno;
@@ -278,13 +278,14 @@ DEVICE::open(char *VolName, int mode)
       VolCatInfo.VolCatName[0] = 0;
    }
 
-   Dmsg3(29, "open dev: tape=%d dev_name=%s vol=%s\n", is_tape(),
-         dev_name, VolCatInfo.VolCatName);
+   Dmsg4(29, "open dev: tape=%d dev_name=%s vol=%s mode=%d\n", is_tape(),
+         dev_name, VolCatInfo.VolCatName, mode);
    state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
    label_type = B_BACULA_LABEL;
    if (is_tape() || is_fifo()) {
       open_tape_device(this, mode);
    } else {
+      Dmsg1(100, "call open_file_device mode=%d\n", mode);
       open_file_device(this, mode);
    }
    return fd;
@@ -382,37 +383,46 @@ static void open_file_device(DEVICE *dev, int mode)
 {
    POOL_MEM archive_name(PM_FNAME);
    struct stat filestat;
+
    /*
     * Handle opening of File Archive (not a tape)
     */     
-   if (dev->part == 0) {
-      dev->file_size = 0;
-   }
-   dev->part_size = 0;
-   
-   /* if num_parts has not been set, but VolCatInfo is available, copy
-    * it from the VolCatInfo.VolCatParts */
-   if (dev->num_parts < dev->VolCatInfo.VolCatParts) {
-      dev->num_parts = dev->VolCatInfo.VolCatParts;
-   }
-   
+   Dmsg3(29, "Enter: open_file_dev: %s dev=%s mode=%d\n", dev->is_dvd()?"DVD":"disk",
+         archive_name.c_str(), mode);
+
    if (dev->VolCatInfo.VolCatName[0] == 0) {
       Mmsg(dev->errmsg, _("Could not open file device %s. No Volume name given.\n"),
          dev->print_name());
       dev->fd = -1;
       return;
    }
-   get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
 
-   if (mount_dev(dev, 1) < 0) {
-      Mmsg(dev->errmsg, _("Could not mount device %s.\n"),
-           dev->print_name());
-      Emsg0(M_FATAL, 0, dev->errmsg);
-      dev->fd = -1;
-      return;
+   if (dev->is_dvd()) {
+      if (dev->part == 0) {
+         dev->file_size = 0;
+      }
+      dev->part_size = 0;
+      
+      /* if num_parts has not been set, but VolCatInfo is available, copy
+       * it from the VolCatInfo.VolCatParts */
+      if (dev->num_parts < dev->VolCatInfo.VolCatParts) {
+         dev->num_parts = dev->VolCatInfo.VolCatParts;
+      }
+      
+      get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
+
+      if (mount_dev(dev, 1) < 0) {
+         Mmsg(dev->errmsg, _("Could not mount device %s.\n"),
+              dev->print_name());
+         Emsg0(M_FATAL, 0, dev->errmsg);
+         dev->fd = -1;
+         return;
+      }
+   } else {
+      get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
    }
          
-   Dmsg3(29, "open dev: device is %s (mode:%d)\n", dev->is_dvd()?"DVD":"disk",
+   Dmsg3(29, "open dev: %s dev=%s mode=%d\n", dev->is_dvd()?"DVD":"disk",
          archive_name.c_str(), mode);
    dev->openmode = mode;
    
@@ -459,7 +469,7 @@ static void open_file_device(DEVICE *dev, int mode)
    Dmsg5(29, "open dev: %s fd=%d opened, part=%d/%d, part_size=%u\n", 
       dev->is_dvd()?"DVD":"disk", dev->fd, dev->part, dev->num_parts, 
       dev->part_size);
-   if (dev->is_dvd() && (dev->mode != OPEN_READ_ONLY) && 
+   if (dev->is_dvd() && (mode != OPEN_READ_ONLY) && 
        (dev->free_space_errno == 0 || dev->num_parts == dev->part)) {
       update_free_space_dev(dev);
    }
@@ -1581,7 +1591,7 @@ bool truncate_dev(DEVICE *dev)
    if (dev->num_parts > 0) {
       dev->num_parts = 0;
       dev->VolCatInfo.VolCatParts = 0;
-      if (open_first_part(dev) < 0) {
+      if (open_first_part(dev, OPEN_READ_WRITE) < 0) {
          berrno be;
          Mmsg1(dev->errmsg, "Unable to truncate device, because I'm unable to open the first part. ERR=%s\n", be.strerror());
       }
index 425700a71290966437b516f6431f2fd826525908..362063243863a565117bcd2e90526cbf9d793bc5 100644 (file)
@@ -249,6 +249,7 @@ public:
 
    /* Methods */
    int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; }
+   int requires_mount() const { return capabilities & CAP_REQMOUNT; }
    int is_tape() const { return state & ST_TAPE; }
    int is_file() const { return state & ST_FILE; }
    int is_fifo() const { return state & ST_FIFO; }
index 33fb6329e2cdf31ac01940b6d82aa8e6edaed9d7..1ac5062c16c3d46fddca2a5e4a3087ca41ca6041 100644 (file)
@@ -427,6 +427,9 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
    }
 
 bail_out:
+   if (!dev->is_open()) {
+      free_volume(dev);
+   }
    give_back_device_lock(dev, &hold);
    return;
 }
index 74804915d0d3a069af701c2113a80423feb07843..24b387762512600131a054fd3e6e5d1343389443 100644 (file)
@@ -39,9 +39,11 @@ void get_filename(DEVICE *dev, char *VolumeName, POOL_MEM& archive_name)
    char partnumber[20];
    
    if (dev->is_dvd()) {
-         /* If we try to open the last part, just open it from disk, 
-         * otherwise, open it from the spooling directory */
-      if (dev->part < dev->num_parts) {
+      /* If we try to open the last part, just open it from disk, 
+       * otherwise, open it from the spooling directory.
+       */
+      Dmsg2(100, "part=%d num_parts=%d\n", dev->part, dev->num_parts);
+      if (dev->num_parts == 0 || dev->part < dev->num_parts) {
          pm_strcpy(archive_name, dev->device->mount_point);
       } else {
          /* Use the working directory if spool directory is not defined */
@@ -73,10 +75,10 @@ void get_filename(DEVICE *dev, char *VolumeName, POOL_MEM& archive_name)
  */
 bool mount_dev(DEVICE* dev, int timeout) 
 {
+   Dmsg0(900, "Enter mount_dev\n");
    if (dev->is_mounted()) {
-      Dmsg0(100, "mount_dev: Device already mounted\n");
       return true;
-   } else if (dev_cap(dev, CAP_REQMOUNT)) {
+   } else if (dev->requires_mount()) {
       return do_mount_dev(dev, 1, timeout);
    }       
    return true;
@@ -88,10 +90,10 @@ bool mount_dev(DEVICE* dev, int timeout)
  */
 bool unmount_dev(DEVICE *dev, int timeout) 
 {
+   Dmsg0(900, "Enter unmount_dev\n");
    if (dev->is_mounted()) {
       return do_mount_dev(dev, 0, timeout);
    }
-   Dmsg0(100, "mount_dev: Device already unmounted\n");
    return true;
 }
 
@@ -100,7 +102,6 @@ static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
 {
    POOL_MEM ocmd(PM_FNAME);
    POOLMEM* results;
-   results = get_pool_memory(PM_MESSAGE);
    char* icmd;
    int status, timeout;
    
@@ -118,24 +119,24 @@ static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
    
    edit_device_codes_dev(dev, ocmd.c_str(), icmd);
    
-   Dmsg2(29, "do_mount_dev: cmd=%s state=%d\n", ocmd.c_str(), dev->is_mounted());
+   Dmsg2(200, "do_mount_dev: cmd=%s mounted=%d\n", ocmd.c_str(), dev->is_mounted());
 
    if (dotimeout) {
-      /* Try at most 5 times to (un)mount the device. This should perhaps be configurable. */
-      timeout = 5;
-   }
-   else {
+      /* Try at most 1 time to (un)mount the device. This should perhaps be configurable. */
+      timeout = 1;
+   } else {
       timeout = 0;
    }
+   results = get_pool_memory(PM_MESSAGE);
    /* If busy retry each second */
    while ((status = run_program_full_output(ocmd.c_str(), 
                        dev->max_open_wait/2, results)) != 0) {
-      if (--timeout > 0) {
-         Dmsg2(40, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
+      if (timeout-- > 0) {
+         Dmsg2(400, "Device %s cannot be (un)mounted. Retrying... ERR=%s\n", dev->dev_name, results);
          /* Sometimes the device cannot be mounted because it is already mounted.
           * Try to unmount it, then remount it */
          if (mount) {
-            Dmsg1(40, "Trying to unmount the device %s...\n", dev->dev_name);
+            Dmsg1(400, "Trying to unmount the device %s...\n", dev->dev_name);
             do_mount_dev(dev, 0, 0);
          }
          bmicrosleep(1, 0);
@@ -149,20 +150,24 @@ static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
    }
    
    dev->set_mounted(mount);              /* set/clear mounted flag */
+   free_pool_memory(results);
 
 get_out:
-   free_pool_memory(results);
-   Dmsg1(29, "do_mount_dev: end_state=%d\n", dev->is_mounted());
+   Dmsg1(29, "Exit do_mount_dev: mounted=%d\n", dev->is_mounted());
    return true;
 }
 
-/* Only for devices that require a mount.
- * Try to find the Volume name of the loaded device, and open the
- * first part of this volume. 
+/* Only for devices that require a mount -- currently DVDs only
+ *
+ * Try to find the Volume name of the loaded device.
+ *
+ * Returns true  if read_dev_volume_label can now read the label,
+ *               NOTE!!! at this point the device may not be
+ *               opened.
+ *               Maybe it should open the first part.  ***FIXME***
  *
- * Returns 0 if read_dev_volume_label can now read the label,
- *        -1 if an error occured,  and read_dvd_volume_label
- *            must abort with an IO_ERROR.
+ *         false if an error occured, and read_dvd_volume_label
+ *               must abort with an IO_ERROR.
  *
  * To find the Volume name, it lists all the files on the DVD,
  * and searches for a file which has a minimum size (500 bytes).
@@ -177,12 +182,10 @@ get_out:
  * the label name of the current volume. We can also check that the currently
  * mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
  *
- * Note that if the right volume is mounted, open_mounted_dev returns 
- *  the same result as an usual dev->open().
  */
-int open_mounted_dev(DEVICE *dev) 
+bool can_open_mounted_dev(DEVICE *dev) 
 {
-   Dmsg1(29, "open_mounted_dev: dev=%s\n", dev->dev_name);
+   Dmsg1(29, "Enter: dev=%s\n", dev->dev_name);
    POOL_MEM guessedname(PM_FNAME);
    DIR* dp;
    struct dirent *entry, *result;
@@ -191,13 +194,13 @@ int open_mounted_dev(DEVICE *dev)
    int name_max;
    
    if (!dev->is_dvd()) {
-      Dmsg1(100, "open_mounted_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
-      return 0;
+      Dmsg1(100, "device does not require mount, returning 0. dev=%s\n", dev->dev_name);
+      return true;
    }
 
 #ifndef HAVE_DIRENT_H
-   Dmsg0(29, "open_mounted_dev: readdir not available, cannot guess volume name\n");
-   return 0
+   Dmsg0(29, "readdir not available, cannot guess volume name\n");
+   return true
 #endif
    
    update_free_space_dev(dev);
@@ -205,11 +208,11 @@ int open_mounted_dev(DEVICE *dev)
    if (mount_dev(dev, 1) < 0) {
       /* If the device cannot be mounted, check if it is writable */
       if (dev->have_media()) {
-         Dmsg1(100, "open_mounted_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
-         return 0;
+         Dmsg1(100, "device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
+         return true;
       } else {
-         Dmsg1(100, "open_mounted_dev: device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
-         return -1;
+         Dmsg1(100, "device cannot be mounted, and is not writable, returning -1. dev=%s\n", dev->dev_name);
+         return false;
       }
    }
       
@@ -221,17 +224,18 @@ int open_mounted_dev(DEVICE *dev)
    if (!(dp = opendir(dev->device->mount_point))) {
       berrno be;
       dev->dev_errno = errno;
-      Dmsg3(29, "open_mounted_dev: failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
-      return -1;
+      Dmsg3(29, "failed to open dir %s (dev=%s), ERR=%s\n", dev->device->mount_point, dev->dev_name, be.strerror());
+      return false;
    }
    
    entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
    while (1) {
       if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
          dev->dev_errno = ENOENT;
-         Dmsg2(29, "open_mounted_dev: failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
+         Dmsg2(29, "failed to find suitable file in dir %s (dev=%s)\n", dev->device->mount_point, dev->dev_name);
          closedir(dp);
-         return -1;
+         free(entry);
+         return false;
       }
       
       ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
@@ -248,13 +252,13 @@ int open_mounted_dev(DEVICE *dev)
       
       if (stat(guessedname.c_str(), &statp) < 0) {
          berrno be;
-         Dmsg3(29, "open_mounted_dev: failed to stat %s (dev=%s), ERR=%s\n",
+         Dmsg3(29, "failed to stat %s (dev=%s), ERR=%s\n",
                guessedname.c_str(), dev->dev_name, be.strerror());
          continue;
       }
       
       if (!S_ISREG(statp.st_mode) || (statp.st_size < 500)) {
-         Dmsg2(100, "open_mounted_dev: %s is not a regular file, or less than 500 bytes (dev=%s)\n", 
+         Dmsg2(100, "%s is not a regular file, or less than 500 bytes (dev=%s)\n", 
                guessedname.c_str(), dev->dev_name);
          continue;
       }
@@ -275,7 +279,7 @@ int open_mounted_dev(DEVICE *dev)
       if ((stat(guessedname.c_str(), &statp) < 0) || (statp.st_size < 500)) {
          /* The file with extension truncated does not exists or is too small, so use it with its extension. */
          berrno be;
-         Dmsg3(100, "open_mounted_dev: failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n", 
+         Dmsg3(100, "failed to stat %s (dev=%s), using the file with its extension, ERR=%s\n", 
                guessedname.c_str(), dev->dev_name, be.strerror());
          pm_strcpy(guessedname, dev->device->mount_point);
          if (guessedname.c_str()[strlen(guessedname.c_str())-1] != '/') {
@@ -286,35 +290,36 @@ int open_mounted_dev(DEVICE *dev)
       }
       break;
    }
-   
    closedir(dp);
+   free(entry);
    
    if (dev->fd >= 0) {
       close(dev->fd);
    }
      
+   Dmsg1(100, "open(%s) read-only\n", guessedname.c_str());
    if ((dev->fd = open(guessedname.c_str(), O_RDONLY | O_BINARY)) < 0) {
       berrno be;
       dev->dev_errno = errno;
-      Dmsg3(29, "open_mounted_dev: failed to open %s (dev=%s), ERR=%s\n", 
+      Dmsg3(29, "failed to open %s (dev=%s), ERR=%s\n", 
             guessedname.c_str(), dev->dev_name, be.strerror());
-      if (open_first_part(dev) < 0) {
+      Dmsg0(100, "Call open_first_part\n");
+      if (open_first_part(dev, OPEN_READ_ONLY) < 0) {
          berrno be;
          dev->dev_errno = errno;
          Mmsg1(&dev->errmsg, _("Could not open_first_part, ERR=%s\n"), be.strerror());
          Emsg0(M_FATAL, 0, dev->errmsg);         
       }
-      return -1;
+      return false;
    }
    dev->part_start = 0;
    dev->part_size = statp.st_size;
    dev->part = 0;
    dev->set_opened();
    dev->use_count = 1;
+   Dmsg2(29, "Exit: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
    
-   Dmsg2(29, "open_mounted_dev: %s opened (dev=%s)\n", guessedname.c_str(), dev->dev_name);
-   
-   return 0;
+   return true;
 }
 
 
@@ -418,8 +423,7 @@ static int dvd_write_part(DEVICE *dev)
       dev->dev_errno = EIO;
       free_pool_memory(results);
       return -1;
-   }
-   else {
+   } else {
       Dmsg1(29, "dvd_write_part: command output=%s\n", results);
       POOL_MEM archive_name(PM_FNAME);
       get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
@@ -437,7 +441,8 @@ static int dvd_write_part(DEVICE *dev)
 int open_next_part(DEVICE *dev)
 {
       
-   Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
+   Dmsg3(29, "Enter: open_next_part %s %s %d\n", dev->dev_name, 
+         dev->VolCatInfo.VolCatName, dev->openmode);
    /* When appending, do not open a new part if the current is empty */
    if (dev->can_append() && (dev->part == dev->num_parts) && 
        (dev->part_size == 0)) {
@@ -509,9 +514,10 @@ int open_next_part(DEVICE *dev)
  *  - Close the fd
  *  - Reopen the device
  */
-int open_first_part(DEVICE *dev
+int open_first_part(DEVICE *dev, int mode)
 {
-   Dmsg3(29, "open_first_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
+   Dmsg3(29, "Enter: open_first_part dev=%s Vol=%s mode=%d\n", dev->dev_name, 
+         dev->VolCatInfo.VolCatName, dev->openmode);
    if (dev->fd >= 0) {
       close(dev->fd);
    }
@@ -521,9 +527,9 @@ int open_first_part(DEVICE *dev)
    dev->part_start = 0;
    dev->part = 0;
    
-   Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName, 
-         dev->openmode);
-   if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
+   Dmsg2(50, "Call dev->open(vol=%s, mode=%d)\n", dev->VolCatInfo.VolCatName, 
+         mode);
+   if (dev->open(dev->VolCatInfo.VolCatName, mode) < 0) {
       Dmsg0(50, "open dev() failed\n");
       return -1;
    }
@@ -565,7 +571,7 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
           * We need to access a previous part, 
           * so just load the first one, and seek again
           * until the right one is loaded */
-         if (open_first_part(dev) < 0) {
+         if (open_first_part(dev, dev->openmode) < 0) {
             Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
             return -1;
          }
@@ -604,10 +610,9 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
           * This is the only way to be sure we compute the right file address. */
          /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
          openmode = dev->openmode;
-         dev->openmode = OPEN_READ_ONLY;
          
          /* Works because num_parts > 0. */
-         if (open_first_part(dev) < 0) {
+         if (open_first_part(dev, OPEN_READ_ONLY) < 0) {
             Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
             return -1;
          }
index e56de483e6040336f68c15ab9ee99a28fd1471b7..2e11958ae3f5d6b4e180b337d733c73a4a9a6f5a 100644 (file)
@@ -237,7 +237,7 @@ int read_dvd_volume_label(DCR *dcr, bool write)
    int vol_label_status;
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
-   Dmsg3(100, "Enter read_dvd_volume_label device=%s vol=%s dev_Vol=%s\n",
+   Dmsg3(100, "Enterdvd_volume_label device=%s vol=%s dev_Vol=%s\n",
          dev->print_name(), dcr->VolumeName, dev->VolHdr.VolumeName);
    
    if (!dev->is_dvd()) {  
@@ -254,7 +254,7 @@ int read_dvd_volume_label(DCR *dcr, bool write)
     * For mounted devices, try to guess the Volume name
     * and read the label if possible.
     */
-   if (open_mounted_dev(dev) < 0) {     
+   if (!can_open_mounted_dev(dev)) {     
       if (!write || dcr->VolCatInfo.VolCatParts > 0) {
          Mmsg2(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
                dev->print_name(), dcr->VolumeName);
@@ -262,8 +262,9 @@ int read_dvd_volume_label(DCR *dcr, bool write)
          return VOL_NO_LABEL;
       }
       
-      if (write && dev->free_space_errno < 0) {
-         Dmsg0(100, "Leave read_dvd_volume_label !free_space VOL_NO_MEDIA\n");
+      /* At this point, we are writing */
+      if (dev->free_space_errno < 0) {
+         Dmsg0(100, "Exit: read_dvd_volume_label !free_space VOL_NO_MEDIA\n");
          Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"),
                dev->print_name(), dev->errmsg);
          return VOL_NO_MEDIA;
@@ -273,7 +274,7 @@ int read_dvd_volume_label(DCR *dcr, bool write)
        * If we can't guess the name, and we are writing, 
        * just reopen the right file with open_first_part.
        */
-      if (open_first_part(dev) < 0) {
+      if (open_first_part(dev, OPEN_READ_WRITE) < 0) {
          berrno be;
          Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"),
                dev->print_name(), be.strerror());
@@ -283,7 +284,11 @@ int read_dvd_volume_label(DCR *dcr, bool write)
       
       Dmsg0(100, "Leave read_dvd_volume_label !open_mounted_dev\n");
       return read_dev_volume_label(dcr);
+
    } else {
+      /* 
+       * If we get here, we can open the mounted device
+       */
       if (write && dcr->dev->free_space_errno < 0) {
          Dmsg0(100, "Leave read_dvd_volume_label !free_space VOL_NO_MEDIA\n");
          Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"),
@@ -291,20 +296,20 @@ int read_dvd_volume_label(DCR *dcr, bool write)
          return VOL_NO_MEDIA;
       }
       
-      vol_label_status = read_dev_volume_label(dcr);
-
       if (!write || dcr->VolCatInfo.VolCatParts > 0) {
-         Dmsg0(100, "Leave read_dvd_volume_label (open_mounted_dev && (!write || dcr->VolCatInfo.VolCatParts > 0))\n");
-         return vol_label_status;
+         Dmsg0(100, "Exit: read_dvd_volume_label (open_mounted_dev && (!write || dcr->VolCatInfo.VolCatParts > 0))\n");
+         return read_dev_volume_label(dcr);
       }
       
-      if (open_first_part(dcr->dev) < 0) {
+      /* At this point, we are writing */
+      if (open_first_part(dcr->dev, OPEN_READ_WRITE) < 0) {
          berrno be;
          Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"),
                dev->print_name(), be.strerror());
          Dmsg0(100, "Leave read_dvd_volume_label VOL_IO_ERROR (open_mounted_dev && !open_first_part)\n");
          return VOL_IO_ERROR;
       }
+      vol_label_status = read_dev_volume_label(dcr);
       
       /* When writing, if the guessed volume name is not the right volume name, 
        * report the error, otherwise, just continue with the right file.
index e2da90428ddd13bb2d07cc2ab010abd9a5d4f21c..3f7d154cba76d27dd47a31812116a10f49bbf6e6 100644 (file)
@@ -309,7 +309,7 @@ read_volume:
       }
       ask = true;
       /* Needed, so the medium can be changed */
-      if (dev_cap(dev, CAP_REQMOUNT)) {
+      if (dev->requires_mount()) {
          close_device(dev);  
       }
       goto mount_next_vol;
index 14c24c4b65bc1b6fb8a76cc1da2f893b65d08d2c..3cac3a8c31d7a9d19c64c8aeea47815d87d76391 100644 (file)
@@ -80,9 +80,9 @@ void    display_tape_error_status(JCR *jcr, DEVICE *dev);
 /* From dev.c */
 DEVICE  *init_dev(JCR *jcr, DEVRES *device);
 off_t    lseek_dev(DEVICE *dev, off_t offset, int whence);
-int      open_first_part(DEVICE *dev);
+int      open_first_part(DEVICE *dev, int mode);
 int      open_next_part(DEVICE *dev);
-int      open_mounted_dev(DEVICE *dev);
+bool     can_open_mounted_dev(DEVICE *dev);
 bool     truncate_dev(DEVICE *dev);
 void     term_dev(DEVICE *dev);
 char *   strerror_dev(DEVICE *dev);
index 7b7215dd65d31f9609eb1d1ffedb1a484113010e..ba58b00fc26876035c59acc44d7a06a0d0f87ffb 100644 (file)
@@ -225,7 +225,6 @@ static bool use_storage_cmd(JCR *jcr)
    bool ok;       
    int Copy, Stripe;
    DIRSTORE *store;
-   char *device_name;
    RCTX rctx;
    rctx.jcr = jcr;
 #ifdef implemented
@@ -273,6 +272,7 @@ static bool use_storage_cmd(JCR *jcr)
 #ifdef DEVELOPER
    /* This loop is debug code and can be removed */
    /* ***FIXME**** remove after 1.38 release */
+   char *device_name;
    foreach_alist(store, jcr->dirstore) {
       Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n", 
          store->name, store->media_type, store->pool_name, 
index 241e020736f86c276794e8791f4631307af12273..c3234424166fc62c7a81b0e8d6ebd5de92ee3665 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
 #define VERSION "1.37.24"
-#define BDATE   "16 June 2005"
-#define LSMDATE "16Jun05"
+#define BDATE   "18 June 2005"
+#define LSMDATE "18Jun05"
 
 /* Debug flags */
 #undef  DEBUG
@@ -12,7 +12,7 @@
 #define TRACE_FILE 1
 
 /* If this is set stdout will not be closed on startup */
-/* #define DEVELOPER 1 */
+#define DEVELOPER 1