From: Kern Sibbald Date: Sat, 18 Jun 2005 13:22:36 +0000 (+0000) Subject: - DVD writing/reading seems to be mostly working. X-Git-Tag: Release-7.0.0~8693 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=9a05a8a7097a412451eb08678863005da472120e;p=bacula%2Fbacula - 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: git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2138 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/Makefile.in b/bacula/Makefile.in index ccdec6f3c1..abc9c6f4b7 100755 --- a/bacula/Makefile.in +++ b/bacula/Makefile.in @@ -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; \ diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 2a7b01e454..d038263330 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -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 .. diff --git a/bacula/configure b/bacula/configure index a351ee5f29..22b70a59fc 100755 --- a/bacula/configure +++ b/bacula/configure @@ -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 .. diff --git a/bacula/kernstodo b/bacula/kernstodo index 6fa8ae7c34..8afdc5d361 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -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. + diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 866b5cc78b..786fae41e8 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -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 diff --git a/bacula/scripts/dvd-freespace.in b/bacula/scripts/dvd-freespace.in index 105e6d922f..7503260ee7 100755 --- a/bacula/scripts/dvd-freespace.in +++ b/bacula/scripts/dvd-freespace.in @@ -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) diff --git a/bacula/scripts/dvd-writepart.in b/bacula/scripts/dvd-writepart.in index 43734d2a00..5de917c8e4 100644 --- a/bacula/scripts/dvd-writepart.in +++ b/bacula/scripts/dvd-writepart.in @@ -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 diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index 4778b84aad..1002e70ba6 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -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; iworker_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; diff --git a/bacula/src/lib/signal.c b/bacula/src/lib/signal.c index 7d03d2b85e..83333deb58 100644 --- a/bacula/src/lib/signal.c +++ b/bacula/src/lib/signal.c @@ -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 diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index c33cd835db..fea9842ebb 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -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); } diff --git a/bacula/src/stored/butil.c b/bacula/src/stored/butil.c index 3af683fa1c..c4cda7c9d2 100644 --- a/bacula/src/stored/butil.c +++ b/bacula/src/stored/butil.c @@ -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; } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 9b26837d6c..b9bc31921a 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -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()); } diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 425700a712..3620632438 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -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; } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 33fb6329e2..1ac5062c16 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -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; } diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 74804915d0..24b3877625 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -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; } diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index e56de483e6..2e11958ae3 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -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, "Enter: dvd_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. diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index e2da90428d..3f7d154cba 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -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; diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 14c24c4b65..3cac3a8c31 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -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); diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 7b7215dd65..ba58b00fc2 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -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, diff --git a/bacula/src/version.h b/bacula/src/version.h index 241e020736..c323442416 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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