]> git.sur5r.net Git - bacula/bacula/commitdiff
06Mar05
authorKern Sibbald <kern@sibbald.com>
Sun, 6 Mar 2005 14:56:05 +0000 (14:56 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 6 Mar 2005 14:56:05 +0000 (14:56 +0000)
- Add new run command to Job resource in DIR. This permits
  cloning a job as many times as you want.
- Pass PoolId to SD on Query request. It is now used in the
  Find_media catalog request.
- Reworked the Device resource in the DIR. Eliminated num_waiting
  and use_count, but added max_writers, reserved, and PoolId.
- This DIR is nolonger compatible with previous SDs.
- Add since and cloned keywords to the Console run command
  to support cloning.
- Implemented store_alist_str() to allow multiple string items
  to be specified in a .conf file.
- Added %s (since time) to Job code editing.
- Reworked reserving drives in the SD. It now does it much simpler
  and correctly.
05Mar05
- Integrate HP-UX patch from  Olivier Mehani <olivier.mehani@linbox.com>
- Fix FD job.c to test correctly for no level.

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

28 files changed:
bacula/ReleaseNotes
bacula/autoconf/acconfig.h
bacula/autoconf/config.h.in
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/src/baconfig.h
bacula/src/bacula.h
bacula/src/dird/backup.c
bacula/src/dird/catreq.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/fd_cmds.c
bacula/src/dird/msgchan.c
bacula/src/dird/next_vol.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_run.c
bacula/src/dird/ua_status.c
bacula/src/jcr.h
bacula/src/lib/parse_conf.c
bacula/src/lib/parse_conf.h
bacula/src/lib/util.c
bacula/src/stored/acquire.c
bacula/src/stored/askdir.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/job.c
bacula/src/version.h

index 29c16fdff23f8688c54fa8f8631e12eb5d024d2b..13e985bfe604834704970a06c9fac359db6fedcf 100644 (file)
@@ -1,7 +1,7 @@
 
-          Release Notes for Bacula 1.37.3
+          Release Notes for Bacula 1.37.6
 
-  Bacula code: Total files = 411 Total lines = 122,189 (*.h *.c *.in)
+  Bacula code: Total files = 414 Total lines = 123,723 (*.h *.c *.in)
 
 
 Major Changes:
@@ -23,6 +23,19 @@ Major Changes:
   and regexfile. See below for details.
 
 New Directives:
+- New Run directive in Job resource of DIR. It permits
+  cloning of jobs.  To clone a copy of the current job, use
+     Run = "job-name level=%l since=\"%s\""
+  Note, job-name is normally the same name as the job that
+  is running but there is no restriction on what you put. If you
+  want to start the job by hand and use job overrides such as       
+  storage=xxx, realize that the job will be started with the
+  default storage values not the overrides.  The level=%l guarantees
+  that the chosen level of the job is the same, and the since=... 
+  ensures that the job uses *exactly* the same time/date for incremental
+  and differential jobs. The since=... is ignored when level=Full.
+  A cloned job will not start additional clones, so it is not possible
+  to recurse.
 - New Options keywords in a FileSet directive:
   - WildDir xxx
     Will do a wild card match against directories (files will not
@@ -202,4 +215,3 @@ def NewVolume(j):
     return 1
 ====
 
-
index e93344357f8cdd021563251d9575dffb60b472d6..2b74fa8e21bb3e233a381bf656bc767177f55821 100644 (file)
 
 /* Defined if Gtk+-2.4 or greater is present */
 #undef HAVE_GTK_2_4
+
+/* Needed on HP-UX/g++ systems to support long long ints (int64) */
+#undef _INCLUDE_LONGLONG
+
index 9470a3e23a4d3c0c0c9acaacf86965136e9f48de..9629e4f89b383b71390ee36c7e6054bfe9483b7d 100644 (file)
 /* Defined if Gtk+-2.4 or greater is present */
 #undef HAVE_GTK_2_4
 
+/* Needed on HP-UX/g++ systems to support long long ints (int64) */
+#undef _INCLUDE_LONGLONG
+
+
 /* Define to 1 if the `closedir' function returns void instead of `int'. */
 #undef CLOSEDIR_VOID
 
index bfdbc7e0355c74725eb4ff99d20ae51677bafde2..c0ef4202f0cad79892733332890a226161b54c4a 100644 (file)
@@ -1572,7 +1572,12 @@ AC_CHECK_FUNCS(strtoll, [AC_DEFINE(HAVE_STRTOLL)])
 
 AC_CHECK_FUNCS(chflags) 
 
-AC_CHECK_FUNCS(snprintf vsnprintf gethostid getdomainname)
+AC_CHECK_FUNCS(snprintf vsnprintf gethostid)
+if test "$DISTNAME" = "hpux" ; then
+       echo "*** getdomainname check is disabled for hpux"
+else
+       AC_CHECK_FUNCS(getdomainname)
+fi
 
 dnl# --------------------------------------------------------------------------
 dnl# CHECKING FOR THREAD SAFE FUNCTIONS
@@ -1780,6 +1785,7 @@ hpux)
        DISTVER=`uname -r`
        TAPEDRIVE="/dev/rmt/0hnb"
        PTHREAD_LIB="-lpthread"
+       AC_DEFINE([_INCLUDE_LONGLONG])
   ;;
 irix)
        DISTVER=`uname -r`
index 4aafe1dbb574be389f9c1529f5c1b40f686babef..c4239612c20de21a79ccd77bbfcd9aa6cba80117 100755 (executable)
@@ -18289,8 +18289,112 @@ done
 
 
 
+for ac_func in snprintf vsnprintf gethostid
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
 
-for ac_func in snprintf vsnprintf gethostid getdomainname
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "$DISTNAME" = "hpux" ; then
+       echo "*** getdomainname check is disabled for hpux"
+else
+
+for ac_func in getdomainname
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -18391,6 +18495,7 @@ _ACEOF
 fi
 done
 
+fi
 
 
 
@@ -21381,6 +21486,10 @@ hpux)
        DISTVER=`uname -r`
        TAPEDRIVE="/dev/rmt/0hnb"
        PTHREAD_LIB="-lpthread"
+       cat >>confdefs.h <<\_ACEOF
+#define _INCLUDE_LONGLONG 1
+_ACEOF
+
   ;;
 irix)
        DISTVER=`uname -r`
index fa64ec71ad7260c42a8abf7d7ec78bb1d9b456d6..34896383e5928e42681b982fe9158f971ad83121 100644 (file)
@@ -36,13 +36,6 @@ Autochangers:
    The defined Storage resources are:
 - Copy Changer Device and Changer Command from Autochanger
   to Device resource in SD if none given in Device resource.
-- Doc the following
-  to activate, check or disable the hardware compression feature on my 
-  exb-8900 i use the exabyte "MammothTool" you can get it here:
-  http://www.exabyte.com/support/online/downloads/index.cfm
-  There is a solaris version of this tool. With option -C 0 or 1 you can 
-  disable or activate compression. Start this tool without any options for 
-  a small reference.
 - 3.Prevent two drives requesting the same Volume in any given
      autochanger.
 - 4. Use Changer Device and Changer Command specified in the
@@ -77,6 +70,22 @@ Autochangers Done:
 
 
 For 1.37:
+- By the way: on page http://www.bacula.org/?page=tapedrives , at the 
+  bottom, the link to "Tape Testing Chapter" is broken. It goes to 
+  /html-manual/... while the others point to /rel-manual/...
+- OS linux 2.4
+  1) ADIC, DLT, FastStor 4000, 7*20GB
+  2) Sun, DDS, (Suns name unknown - Archive Python DDS drive), 1.2GB
+  3) Wangtek, QIC, 6525ES, 525MB (fixed block size 1k, block size etc. 
+  driver dependent - aic7xxx works, ncr53c8xx with problems)
+  4) HP, DDS-2, C1553A, 6*4GB
+- Doc the following
+  to activate, check or disable the hardware compression feature on my 
+  exb-8900 i use the exabyte "MammothTool" you can get it here:
+  http://www.exabyte.com/support/online/downloads/index.cfm
+  There is a solaris version of this tool. With option -C 0 or 1 you can 
+  disable or activate compression. Start this tool without any options for 
+  a small reference.
 - Linux Sony LIB-D81, AIT-3 library works.
 - Device resource needs the "name" of the SD.
 - Add and option to see if the file size changed
index 9ce9c4a305a974b9766ade29e84c80d1d8ba9ec6..06baea30ff32941deedc134974ff2bbf159739ad 100644 (file)
@@ -511,6 +511,22 @@ extern "C" int getdomainname(char *name, int len);
 #ifdef HAVE_AIX_OS
 #endif
 
+/* HP-UX 11 specific workarounds */
+
+#ifdef HAVE_HPUX_OS
+# undef h_errno
+extern int h_errno;
+/* the {get,set}domainname() functions exist in HPUX's libc.
+ * the configure script detects that correctly.
+ * the problem is no system headers declares the prototypes for these functions
+ * this is done below
+ */
+extern "C" int getdomainname(char *name, int namelen);
+extern "C" int setdomainname(char *name, int namelen);
+#define uLong unsigned long
+#endif /* HAVE_HPUX_OS */
+
+
 #ifdef HAVE_OSF1_OS
 #undef HAVE_CHFLAGS  /* chflags is incorrectly detected */
 extern "C" int fchdir(int filedes);
index e662530756962c882588a626720a9a9ef260072b..57f59891fbb6468df64046591b572980dfddba70 100644 (file)
@@ -58,6 +58,9 @@
 #include <stdlib.h>
 #endif
 #if HAVE_UNISTD_H
+#  ifdef HAVE_HPUX_OS
+#  undef _INCLUDE_POSIX1C_SOURCE
+#  endif
 #include <unistd.h>
 #endif
 #if HAVE_ALLOCA_H
index ecf379b1cd129921950d30839ed95b5fec7fc8cd..d8dad976b6e44db7cc4720e2564dbda0978c480e 100644 (file)
@@ -97,8 +97,6 @@ bool do_backup_init(JCR *jcr)
    jcr->PoolId = pr.PoolId;              /****FIXME**** this can go away */
    jcr->jr.PoolId = pr.PoolId;
 
-   jcr->since[0] = 0;
-
    if (!get_or_create_fileset_record(jcr, &fsr)) {
       return false;
    }
@@ -106,6 +104,29 @@ bool do_backup_init(JCR *jcr)
 
    get_level_since_time(jcr, jcr->since, sizeof(jcr->since));
 
+   Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->job->run_cmds);
+   if (!jcr->cloned && jcr->job->run_cmds) {
+      char *runcmd;
+      JOB *job = jcr->job;
+      POOLMEM *cmd = get_pool_memory(PM_FNAME);
+      UAContext *ua = new_ua_context(jcr);
+      ua->batch = true;
+      foreach_alist(runcmd, job->run_cmds) {
+         cmd = edit_job_codes(jcr, cmd, runcmd, "");              
+         Mmsg(ua->cmd, "run %s cloned=yes", cmd);
+         Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd);
+        parse_ua_args(ua);                 /* parse command */
+        int stat = run_cmd(ua, ua->cmd);
+        if (stat == 0) {
+            Jmsg(jcr, M_ERROR, 0, _("Could not start clone job.\n"));
+        } else {
+            Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), stat);
+        }
+      }
+      free_ua_context(ua);
+      free_pool_memory(cmd);
+   }
+
    return true;
 }
 
index fd53c276c83f1ea03f9b2b891864a324daf133e0..6df8db94fe382a38eb0b6583392f8414154ac155 100644 (file)
@@ -41,7 +41,7 @@
  */
 
 /* Requests from the Storage daemon */
-static char Find_media[] = "CatReq Job=%127s FindMedia=%d\n";
+static char Find_media[] = "CatReq Job=%127s FindMedia=%d PoolId=%lld\n";
 static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n";
 
 static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s"
@@ -114,7 +114,10 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       free_memory(omsg);
       return;
    }
-   if (sscanf(bs->msg, Find_media, &Job, &index) == 2) {
+   /*
+    * Find next appendable medium for SD
+    */
+   if (sscanf(bs->msg, Find_media, &Job, &index, &mr.PoolId) == 3) {
       ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
       /*
        * Send Find Media response to Storage daemon
index 25c2ecac89616d47f09e51af7de72f5718b1d637..27175cda7019b3e568f640e50c5c51e99868abbc 100644 (file)
@@ -215,7 +215,8 @@ RES_ITEM job_items[] = {
    {"fileset",   store_res,     ITEM(res_job.fileset),  R_FILESET, ITEM_REQUIRED, 0},
    {"schedule",  store_res,     ITEM(res_job.schedule), R_SCHEDULE, 0, 0},
    {"verifyjob", store_res,     ITEM(res_job.verify_job), R_JOB, 0, 0},
-   {"jobdefs",   store_res,     ITEM(res_job.jobdefs),  R_JOBDEFS, 0, 0},
+   {"jobdefs",   store_res,     ITEM(res_job.jobdefs),    R_JOBDEFS, 0, 0},
+   {"run",       store_alist_str, ITEM(res_job.run_cmds), 0, 0, 0},
    {"where",    store_dir,      ITEM(res_job.RestoreWhere), 0, 0, 0},
    {"bootstrap",store_dir,      ITEM(res_job.RestoreBootstrap), 0, 0, 0},
    {"writebootstrap",store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0},
@@ -395,7 +396,7 @@ const char *level_to_str(int level)
    static char level_no[30];
    const char *str = level_no;
 
-   bsnprintf(level_no, sizeof(level_no), "%d", level);    /* default if not found */
+   bsnprintf(level_no, sizeof(level_no), "%c (%d)", level, level);    /* default if not found */
    for (i=0; joblevels[i].level_name; i++) {
       if (level == joblevels[i].level) {
         str = joblevels[i].level_name;
@@ -471,12 +472,14 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       break;
    case R_DEVICE:
       dev = &res->res_dev;
-      sendit(sock, "Device: name=%s ok=%d num_writers=%d num_waiting=%d\n"
-"      use_cnt=%d open=%d append=%d read=%d labeled=%d offline=%d autochgr=%d\n"
-"      volname=%s MediaType=%s\n",
-        dev->hdr.name, dev->found, dev->num_writers, dev->num_waiting,
-        dev->use_count, dev->open, dev->append, dev->read, dev->labeled,
+      char ed1[50];
+      sendit(sock, "Device: name=%s ok=%d num_writers=%d max_writers=%d\n"
+"      reserved=%d open=%d append=%d read=%d labeled=%d offline=%d autochgr=%d\n"
+"      poolid=%s volname=%s MediaType=%s\n",
+        dev->hdr.name, dev->found, dev->num_writers, dev->max_writers,
+        dev->reserved, dev->open, dev->append, dev->read, dev->labeled,
         dev->offline, dev->autochanger,
+        edit_uint64(dev->PoolId, ed1),
         dev->VolumeName, dev->MediaType);
       break;
    case R_STORAGE:
@@ -563,7 +566,12 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
          sendit(sock, "  --> ");
         dump_resource(-type, (RES *)res->res_job.verify_job, sendit, sock);
       }
-      break;
+      if (res->res_job.run_cmds) {
+        char *runcmd;
+        foreach_alist(runcmd, res->res_job.run_cmds) {
+            sendit(sock, "  --> Run=%s\n", runcmd);
+        }
+      }
       if (res->res_job.messages) {
          sendit(sock, "  --> ");
         dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
@@ -948,6 +956,9 @@ void free_resource(RES *sres, int type)
       if (res->res_job.ClientRunAfterJob) {
         free(res->res_job.ClientRunAfterJob);
       }
+      if (res->res_job.run_cmds) {
+        delete res->res_job.run_cmds;
+      }
       if (res->res_job.storage) {
         delete res->res_job.storage;
       }
@@ -1055,6 +1066,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
         res->res_job.dif_pool   = res_all.res_job.dif_pool;
         res->res_job.verify_job = res_all.res_job.verify_job;
         res->res_job.jobdefs    = res_all.res_job.jobdefs;
+        res->res_job.run_cmds   = res_all.res_job.run_cmds;
         break;
       case R_COUNTER:
         if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
index 3bc8ec5a51f84ffbdaa9305d578cfb9cb33fde20..03b14f2d81d271f8956259b4650a80ed03a220d5 100644 (file)
@@ -125,8 +125,8 @@ public:
 
    bool found;                        /* found with SD */
    int num_writers;
-   int num_waiting;
-   int use_count;
+   int max_writers;                   /* = 1 for files */
+   int reserved;                      /* number of reserves */
    bool open;
    bool append;                       /* in append mode */
    bool read;
@@ -134,6 +134,7 @@ public:
    bool autochanger;
    bool offline;
    bool autoselect;
+   uint32_t PoolId;
    char ChangerName[MAX_NAME_LENGTH];
    char VolumeName[MAX_NAME_LENGTH];
    char MediaType[MAX_NAME_LENGTH];
@@ -291,6 +292,7 @@ public:
    POOL      *dif_pool;               /* Pool for Differental backups */
    JOB       *verify_job;             /* Job name to verify */
    JOB       *jobdefs;                /* Job defaults */
+   alist     *run_cmds;               /* Run commands */
    uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
 };
 
index 24e13e6e2d7f2d1bf44c4f050e7d596f0b39f95b..c4c9bba8b77aa2cb25c965a14ff90b8efaaef3c7 100644 (file)
@@ -145,14 +145,22 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
 void get_level_since_time(JCR *jcr, char *since, int since_len)
 {
    int JobLevel;
-   /* Lookup the last FULL backup job to get the time/date for a
-    * differential or incremental save.
-    */
+
+   since[0] = 0;
+   if (jcr->cloned) {
+      if ( jcr->stime && jcr->stime[0]) {
+         bstrncpy(since, ", since=", since_len);
+        bstrncat(since, jcr->stime, since_len);
+      }
+      return;
+   }
    if (!jcr->stime) {
       jcr->stime = get_pool_memory(PM_MESSAGE);
-   }
+   } 
    jcr->stime[0] = 0;
-   since[0] = 0;
+   /* Lookup the last FULL backup job to get the time/date for a
+    * differential or incremental save.
+    */
    switch (jcr->JobLevel) {
    case L_DIFFERENTIAL:
    case L_INCREMENTAL:
index 632b7783a5a054e214ed7ba10ab02d2257e62c35..1c49dfc1224d78d5cdedc08892a3287089159a08 100644 (file)
@@ -43,15 +43,18 @@ static char jobcmd[]     = "JobId=%d job=%s job_name=%s client_name=%s "
    "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s "
    "SpoolData=%d WritePartAfterJob=%d";
 static char use_device[] = "use device=%s media_type=%s pool_name=%s "
-   "pool_type=%s append=%d\n";
+   "pool_type=%s PoolId=%s append=%d\n";
 static char query_device[] = "query device=%s";
 
 /* Response from Storage daemon */
 static char OKjob[]      = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n";
 static char OK_device[]  = "3000 OK use device device=%s\n";
-static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
-   "num_waiting=%d open=%d use_count=%d labeled=%d offline=%d "
+static char OK_query[]   = "3001 OK query "
+   "append=%d read=%d num_writers=%d "
+   "open=%d labeled=%d offline=%d "
+   "reserved=%d max_writers=%d "
    "autoselect=%d autochanger=%d "
+   "poolid=%lld "
    "changer_name=%127s media_type=%127s volume_name=%127s";
 
 /* Storage Daemon requests */
@@ -80,7 +83,7 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
    /*
     *  Open message channel with the Storage daemon
     */
-   Dmsg2(200, "bnet_connect to Storage daemon %s:%d\n", store->address,
+   Dmsg2(100, "bnet_connect to Storage daemon %s:%d\n", store->address,
       store->SDport);
    sd = bnet_connect(jcr, retry_interval, max_retry_time,
           _("Storage daemon"), store->address,
@@ -116,13 +119,17 @@ bool update_device_res(JCR *jcr, DEVICE *dev)
    pm_strcpy(device_name, dev->hdr.name);
    bash_spaces(device_name);
    bnet_fsend(sd, query_device, device_name.c_str());
+   Dmsg1(100, ">stored: %s\n", sd->msg);
    if (bget_dirmsg(sd) > 0) {
-      Dmsg1(400, "<stored: %s", sd->msg);
-      if (sscanf(sd->msg, OK_query, &dev_append, &dev_read,
-         &dev->num_writers, &dev->num_waiting, &dev_open,
-         &dev->use_count, &dev_labeled, &dev_offline, &dev_autoselect, 
-         &dev_autochanger,  changer_name.c_str(), media_type.c_str(),
-         volume_name.c_str()) != 13) {
+      Dmsg1(100, "<stored: %s", sd->msg);
+      if (sscanf(sd->msg, OK_query, 
+         &dev_append, &dev_read,
+         &dev->num_writers, &dev_open,
+         &dev_labeled, &dev_offline, &dev->reserved,
+         &dev->max_writers, &dev_autoselect, 
+         &dev_autochanger,  &dev->PoolId,
+         changer_name.c_str(), media_type.c_str(),
+         volume_name.c_str()) != 14) {
         return false;
       }
       unbash_spaces(changer_name);
@@ -131,6 +138,9 @@ bool update_device_res(JCR *jcr, DEVICE *dev)
       bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName));
       bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
       bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
+      /* Note, these are copied because they are boolean rather than
+       *  integer.
+       */
       dev->open = dev_open;
       dev->append = dev_append;
       dev->read = dev_read;
@@ -155,6 +165,7 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
    BSOCK *sd;
    char auth_key[100];
    POOL_MEM device_name, pool_name, pool_type, media_type;
+   char PoolId[50];
 
    sd = jcr->store_bsock;
    /*
@@ -170,12 +181,12 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
              jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
              jcr->fileset->hdr.name, !jcr->pool->catalog_files,
              jcr->job->SpoolAttributes, jcr->fileset->MD5, jcr->spool_data, jcr->write_part_after_job);
-   Dmsg1(200, "Jobcmd=%s\n", sd->msg);
+   Dmsg1(100, ">stored: %s\n", sd->msg);
    unbash_spaces(jcr->job->hdr.name);
    unbash_spaces(jcr->client->hdr.name);
    unbash_spaces(jcr->fileset->hdr.name);
    if (bget_dirmsg(sd) > 0) {
-       Dmsg1(110, "<stored: %s", sd->msg);
+       Dmsg1(100, "<stored: %s", sd->msg);
        if (sscanf(sd->msg, OKjob, &jcr->VolSessionId,
                  &jcr->VolSessionTime, &auth_key) != 3) {
           Dmsg1(100, "BadJob=%s\n", sd->msg);
@@ -195,6 +206,7 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
    pm_strcpy(pool_name, jcr->pool->hdr.name);
    bash_spaces(pool_type);
    bash_spaces(pool_name);
+   edit_int64(jcr->PoolId, PoolId);
 
    /*
     * We have two loops here. The first comes from the 
@@ -217,10 +229,10 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
         bash_spaces(media_type);
         bnet_fsend(sd, use_device, device_name.c_str(),
                    media_type.c_str(), pool_name.c_str(), pool_type.c_str(),
-                   append);
-         Dmsg1(200, ">stored: %s", sd->msg);
+                   PoolId, append);
+         Dmsg1(100, ">stored: %s", sd->msg);
         if (bget_dirmsg(sd) > 0) {
-            Dmsg1(400, "<stored: %s", sd->msg);
+            Dmsg1(100, "<stored: %s", sd->msg);
            /* ****FIXME**** save actual device name */
            ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1;
            if (ok) {
@@ -240,6 +252,7 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
 // }
    if (ok) {
       ok = bnet_fsend(sd, "run");
+      Dmsg1(100, ">stored: %s\n", sd->msg);
    }
    return ok;
 }
index bf44fc84427889ab333047055d289af2fc6032bb..53e941eaba2f205970bfa370643e92909d10d1d0 100644 (file)
@@ -33,7 +33,7 @@
 
 /*
  *  Items needed:
- *   jcr->PoolId
+ *   mr.PoolId must be set
  *   jcr->store
  *   jcr->db
  *   jcr->pool
@@ -47,9 +47,8 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, bool create)
    bool InChanger;
    STORE *store = jcr->store;
 
-   mr->PoolId = jcr->PoolId;
    bstrncpy(mr->MediaType, store->media_type, sizeof(mr->MediaType));
-   Dmsg2(120, "CatReq FindMedia: Id=%d, MediaType=%s\n", mr->PoolId, mr->MediaType);
+   Dmsg2(100, "CatReq FindMedia: Id=%d, MediaType=%s\n", (int)mr->PoolId, mr->MediaType);
    /*
     * If we are using an Autochanger, restrict Volume
     *  search to the Autochanger on the first pass
index 55420662804cf173d4b41f31cd518a2087b8c25f..af30220093696ad70955b73140c266e850a1b0bc 100644 (file)
@@ -421,6 +421,7 @@ static bool list_nextvol(UAContext *ua)
    MEDIA_DBR mr;
 
    memset(&mr, 0, sizeof(mr));
+   mr.PoolId = jcr->PoolId;
    int i = find_arg_with_value(ua, "job");
    if (i <= 0) {
       if ((job = select_job_resource(ua)) == NULL) {
index 29fba3371d1577e93fb2c7660fdd7c715c64cd73..5cd149e20045665a0bdd0f166014d96a898265fe 100644 (file)
@@ -53,6 +53,8 @@ int run_cmd(UAContext *ua, const char *cmd)
    char *where, *fileset_name, *client_name, *bootstrap;
    const char *replace;
    char *when, *verify_job_name, *catalog_name;
+   char *since = NULL;
+   bool cloned = false;
    int Priority = 0;
    int i, j, opt, files = 0;
    bool kw_ok;
@@ -63,24 +65,26 @@ int run_cmd(UAContext *ua, const char *cmd)
    FILESET *fileset = NULL;
    POOL *pool = NULL;
    static const char *kw[] = {       /* command line arguments */
-      N_("job"),                      /*  Used in a switch() */
-      N_("jobid"),                    /* 1 */
-      N_("client"),                   /* 2 */
-      N_("fd"),
-      N_("fileset"),                  /* 4 */
-      N_("level"),                    /* 5 */
-      N_("storage"),                  /* 6 */
-      N_("sd"),                       /* 7 */
-      N_("pool"),                     /* 8 */
-      N_("where"),                    /* 9 */
-      N_("bootstrap"),                /* 10 */
-      N_("replace"),                  /* 11 */
-      N_("when"),                     /* 12 */
-      N_("priority"),                 /* 13 */
-      N_("yes"),          /* 14 -- if you change this change YES_POS too */
-      N_("verifyjob"),                /* 15 */
-      N_("files"),                    /* 16 number of files to restore */
-       N_("catalog"),                 /* 17 override catalog */
+      "job",                          /*  Used in a switch() */
+      "jobid",                        /* 1 */
+      "client",                       /* 2 */
+      "fd",
+      "fileset",                      /* 4 */
+      "level",                        /* 5 */
+      "storage",                      /* 6 */
+      "sd",                           /* 7 */
+      "pool",                         /* 8 */
+      "where",                        /* 9 */
+      "bootstrap",                    /* 10 */
+      "replace",                      /* 11 */
+      "when",                         /* 12 */
+      "priority",                     /* 13 */
+      "yes",          /* 14  -- if you change this change YES_POS too */
+      "verifyjob",                    /* 15 */
+      "files",                        /* 16 number of files to restore */
+      "catalog",                      /* 17 override catalog */
+      "since",                        /* 18 since */
+      "cloned",                       /* 19 cloned */
       NULL};
 
 #define YES_POS 14
@@ -239,6 +243,16 @@ int run_cmd(UAContext *ua, const char *cmd)
               kw_ok = true;
               break;
 
+           case 18: /* since */
+              since = ua->argv[i];
+              kw_ok = true; 
+              break;
+
+           case 19: /* cloned */
+              cloned = true;
+              kw_ok = true;
+              break;
+
            default:
               break;
            }
@@ -444,6 +458,15 @@ int run_cmd(UAContext *ua, const char *cmd)
       jcr->JobPriority = Priority;
    }
 
+   if (since) {
+      if (!jcr->stime) {
+        jcr->stime = get_pool_memory(PM_MESSAGE);
+      }
+      pm_strcpy(jcr->stime, since);
+   }
+
+   jcr->cloned = cloned;
+
    if (find_arg(ua, _("fdcalled")) > 0) {
       jcr->file_bsock = dup_bsock(ua->UA_sock);
       ua->quit = true;
index 0b204a064e312aca61cf9e570679442d53f35f46..3c6c372ea5b0691106dd07af4207a83954a28a5e 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -108,7 +108,7 @@ int status_cmd(UAContext *ua, const char *cmd)
         do_all_status(ua);
         return 1;
       } else if (strcasecmp(ua->argk[i], _("dir")) == 0 ||
-                strcasecmp(ua->argk[i], _("director")) == 0) {
+                 strcasecmp(ua->argk[i], _("director")) == 0) {
         do_director_status(ua);
         return 1;
       } else if (strcasecmp(ua->argk[i], _("client")) == 0) {
@@ -197,7 +197,7 @@ static void do_all_status(UAContext *ua)
       }
       if (!found) {
         unique_store[i++] = store;
-        Dmsg2(40, "Stuffing: %s:%d\n", store->address, store->SDport);
+         Dmsg2(40, "Stuffing: %s:%d\n", store->address, store->SDport);
       }
    }
    UnlockRes();
@@ -231,7 +231,7 @@ static void do_all_status(UAContext *ua)
       }
       if (!found) {
         unique_client[i++] = client;
-        Dmsg2(40, "Stuffing: %s:%d\n", client->address, client->FDport);
+         Dmsg2(40, "Stuffing: %s:%d\n", client->address, client->FDport);
       }
    }
    UnlockRes();
@@ -252,7 +252,7 @@ static void do_director_status(UAContext *ua)
            HOST_OS, DISTNAME, DISTVER);
    bstrftime_nc(dt, sizeof(dt), daemon_start_time);
    bsendmsg(ua, _("Daemon started %s, %d Job%s run since started.\n"),
-       dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
+        dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
    if (debug_level > 0) {
       char b1[35], b2[35], b3[35], b4[35];
       bsendmsg(ua, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
@@ -372,6 +372,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp)
    JCR *jcr = ua->jcr;
    MEDIA_DBR mr;
    memset(&mr, 0, sizeof(mr));
+   mr.PoolId = jcr->PoolId;
    if (sp->job->JobType == JT_BACKUP) {
       jcr->db = NULL;
       ok = complete_jcr_for_job(jcr, sp->job, sp->pool);
@@ -382,7 +383,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp)
         ok = find_next_volume_for_append(jcr, &mr, 0);
       }
       if (!ok) {
-        bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName));
+         bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName));
       }
    }
    bstrftime_nc(dt, sizeof(dt), sp->runtime);
@@ -503,7 +504,7 @@ static void list_running_jobs(UAContext *ua)
          */
         if (jcr->JobType == JT_CONSOLE) {
            bstrftime_nc(dt, sizeof(dt), jcr->start_time);
-           bsendmsg(ua, _("Console connected at %s\n"), dt);
+            bsendmsg(ua, _("Console connected at %s\n"), dt);
         }
         njobs--;
       }
@@ -527,66 +528,66 @@ static void list_running_jobs(UAContext *ua)
       njobs++;
       switch (jcr->JobStatus) {
       case JS_Created:
-        msg = _("is waiting execution");
+         msg = _("is waiting execution");
         break;
       case JS_Running:
-        msg = _("is running");
+         msg = _("is running");
         break;
       case JS_Blocked:
-        msg = _("is blocked");
+         msg = _("is blocked");
         break;
       case JS_Terminated:
-        msg = _("has terminated");
+         msg = _("has terminated");
         break;
       case JS_ErrorTerminated:
-        msg = _("has erred");
+         msg = _("has erred");
         break;
       case JS_Error:
-        msg = _("has errors");
+         msg = _("has errors");
         break;
       case JS_FatalError:
-        msg = _("has a fatal error");
+         msg = _("has a fatal error");
         break;
       case JS_Differences:
-        msg = _("has verify differences");
+         msg = _("has verify differences");
         break;
       case JS_Canceled:
-        msg = _("has been canceled");
+         msg = _("has been canceled");
         break;
       case JS_WaitFD:
         emsg = (char *) get_pool_memory(PM_FNAME);
-        Mmsg(emsg, _("is waiting on Client %s"), jcr->client->hdr.name);
+         Mmsg(emsg, _("is waiting on Client %s"), jcr->client->hdr.name);
         pool_mem = true;
         msg = emsg;
         break;
       case JS_WaitSD:
         emsg = (char *) get_pool_memory(PM_FNAME);
-        Mmsg(emsg, _("is waiting on Storage %s"), jcr->store->hdr.name);
+         Mmsg(emsg, _("is waiting on Storage %s"), jcr->store->hdr.name);
         pool_mem = true;
         msg = emsg;
         break;
       case JS_WaitStoreRes:
-        msg = _("is waiting on max Storage jobs");
+         msg = _("is waiting on max Storage jobs");
         break;
       case JS_WaitClientRes:
-        msg = _("is waiting on max Client jobs");
+         msg = _("is waiting on max Client jobs");
         break;
       case JS_WaitJobRes:
-        msg = _("is waiting on max Job jobs");
+         msg = _("is waiting on max Job jobs");
         break;
       case JS_WaitMaxJobs:
-        msg = _("is waiting on max total jobs");
+         msg = _("is waiting on max total jobs");
         break;
       case JS_WaitStartTime:
-        msg = _("is waiting for its start time");
+         msg = _("is waiting for its start time");
         break;
       case JS_WaitPriority:
-        msg = _("is waiting for higher priority jobs to finish");
+         msg = _("is waiting for higher priority jobs to finish");
         break;
 
       default:
         emsg = (char *) get_pool_memory(PM_FNAME);
-        Mmsg(emsg, _("is in unknown state %c"), jcr->JobStatus);
+         Mmsg(emsg, _("is in unknown state %c"), jcr->JobStatus);
         pool_mem = true;
         msg = emsg;
         break;
@@ -600,21 +601,21 @@ static void list_running_jobs(UAContext *ua)
            free_pool_memory(emsg);
            pool_mem = false;
         }
-        msg = _("is waiting for a mount request");
+         msg = _("is waiting for a mount request");
         break;
       case JS_WaitMedia:
         if (pool_mem) {
            free_pool_memory(emsg);
            pool_mem = false;
         }
-        msg = _("is waiting for an appendable Volume");
+         msg = _("is waiting for an appendable Volume");
         break;
       case JS_WaitFD:
         if (!pool_mem) {
            emsg = (char *) get_pool_memory(PM_FNAME);
            pool_mem = true;
         }
-        Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
+         Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
              jcr->client->hdr.name, jcr->store->hdr.name);
         msg = emsg;
         break;
@@ -622,7 +623,7 @@ static void list_running_jobs(UAContext *ua)
       switch (jcr->JobType) {
       case JT_ADMIN:
       case JT_RESTORE:
-        bstrncpy(level, "      ", sizeof(level));
+         bstrncpy(level, "      ", sizeof(level));
         break;
       default:
         bstrncpy(level, level_to_str(jcr->JobLevel), sizeof(level));
@@ -669,7 +670,7 @@ static void list_terminated_jobs(UAContext *ua)
       /* There are three periods after the Job name */
       char *p;
       for (int i=0; i<3; i++) {
-        if ((p=strrchr(JobName, '.')) != NULL) {
+         if ((p=strrchr(JobName, '.')) != NULL) {
            *p = 0;
         }
       }
@@ -682,7 +683,7 @@ static void list_terminated_jobs(UAContext *ua)
       switch (je->JobType) {
       case JT_ADMIN:
       case JT_RESTORE:
-        bstrncpy(level, "    ", sizeof(level));
+         bstrncpy(level, "    ", sizeof(level));
         break;
       default:
         bstrncpy(level, level_to_str(je->JobLevel), sizeof(level));
@@ -691,23 +692,23 @@ static void list_terminated_jobs(UAContext *ua)
       }
       switch (je->JobStatus) {
       case JS_Created:
-        termstat = "Created";
+         termstat = "Created";
         break;
       case JS_FatalError:
       case JS_ErrorTerminated:
-        termstat = "Error";
+         termstat = "Error";
         break;
       case JS_Differences:
-        termstat = "Diffs";
+         termstat = "Diffs";
         break;
       case JS_Canceled:
-        termstat = "Cancel";
+         termstat = "Cancel";
         break;
       case JS_Terminated:
-        termstat = "OK";
+         termstat = "OK";
         break;
       default:
-        termstat = "Other";
+         termstat = "Other";
         break;
       }
       bsendmsg(ua, _("%6d  %-6s %8s %14s %-7s  %-8s %s\n"),
index 550be78ef8bc56dbbcad7287d9b8d388f2b698b2..85e8e98923530af0e678bbd94050185553fbd8cb 100644 (file)
@@ -130,6 +130,7 @@ struct JCR {
    time_t end_time;                   /* job end time */
    POOLMEM *client_name;              /* client name */
    POOLMEM *RestoreBootstrap;         /* Bootstrap file to restore */
+   POOLMEM *stime;                    /* start time for incremental/differential */
    char *sd_auth_key;                 /* SD auth key */
    MSGS *jcr_msgs;                    /* Copy of message resource -- actually used */
    uint32_t ClientId;                 /* Client associated with Job */
@@ -174,7 +175,6 @@ struct JCR {
    FileId_t FileId;                   /* Last file id inserted */
    uint32_t FileIndex;                /* Last FileIndex processed */
    POOLMEM *fname;                    /* name to put into catalog */
-   POOLMEM *stime;                    /* start time for incremental/differential */
    JOB_DBR jr;                        /* Job DB record for current job */
    JOB_DBR target_jr;                 /* target job */
    char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */
@@ -190,6 +190,7 @@ struct JCR {
    bool fn_printed;                   /* printed filename */
    bool write_part_after_job;         /* Write part after job in SD */
    bool needs_sd;                     /* set if SD needed by Job */
+   bool cloned;                       /* set if cloned */
 #endif /* DIRECTOR_DAEMON */
 
 
index 031f939d354233ffc02ea6c278c296e87d4abc68..d5dc130815e7ac8a8360143d43f6e1fcc918f85f 100755 (executable)
@@ -528,6 +528,32 @@ void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass)
 }
 
 
+/*
+ * Store a string in an alist.
+ */
+void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+   alist *list;
+
+   if (pass == 2) {
+      if (*(item->value) == NULL) {
+        list = New(alist(10, owned_by_alist));
+      } else {
+        list = (alist *)(*(item->value));    
+      }
+
+      lex_get_token(lc, T_STRING);   /* scan next item */
+      Dmsg4(900, "Append %s to alist %p size=%d %s\n", 
+        lc->str, list, list->size(), item->name);
+      list->append(bstrdup(lc->str));
+      *(item->value) = (char *)list;
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
+
 /*
  * Store default values for Resource from xxxDefs
  * If we are in pass 2, do a lookup of the
index 18a22261da366124bbe5188436afbada1ac2c67d..46f08f2eec2890ffd005fffb3e8db63e0d374400 100644 (file)
@@ -2,7 +2,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -130,6 +130,7 @@ void store_name(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_strname(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_res(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass);
+void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_int(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_pint(LEX *lc, RES_ITEM *item, int index, int pass);
 void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass);
index a7c634b55b68e6302f57a77022e1a3dda6ad7018..ed15119ab3d82f5c366e00e916b01eea32d06dcd 100644 (file)
@@ -109,7 +109,7 @@ unbash_spaces(char *str)
 {
    while (*str) {
      if (*str == 0x1)
-       *str = ' ';
+        *str = ' ';
      str++;
    }
 }
@@ -121,7 +121,7 @@ unbash_spaces(POOL_MEM &pm)
    char *str = pm.c_str();
    while (*str) {
      if (*str == 0x1)
-       *str = ' ';
+        *str = ' ';
      str++;
    }
 }
@@ -240,7 +240,7 @@ void jobstatus_to_ascii(int JobStatus, char *msg, int maxlen)
       if (JobStatus == 0) {
         buf[0] = 0;
       } else {
-        bsnprintf(buf, sizeof(buf), _("Unknown Job termination status=%d"), JobStatus);
+         bsnprintf(buf, sizeof(buf), _("Unknown Job termination status=%d"), JobStatus);
       }
       jobstat = buf;
       break;
@@ -364,22 +364,22 @@ char *encode_mode(mode_t mode, char *buf)
   char *cp = buf;
 
   *cp++ = S_ISDIR(mode) ? 'd' : S_ISBLK(mode)  ? 'b' : S_ISCHR(mode)  ? 'c' :
-         S_ISLNK(mode) ? 'l' : S_ISFIFO(mode) ? 'f' : S_ISSOCK(mode) ? 's' : '-';
+          S_ISLNK(mode) ? 'l' : S_ISFIFO(mode) ? 'f' : S_ISSOCK(mode) ? 's' : '-';
   *cp++ = mode & S_IRUSR ? 'r' : '-';
   *cp++ = mode & S_IWUSR ? 'w' : '-';
   *cp++ = (mode & S_ISUID
-              ? (mode & S_IXUSR ? 's' : 'S')
-              : (mode & S_IXUSR ? 'x' : '-'));
+               ? (mode & S_IXUSR ? 's' : 'S')
+               : (mode & S_IXUSR ? 'x' : '-'));
   *cp++ = mode & S_IRGRP ? 'r' : '-';
   *cp++ = mode & S_IWGRP ? 'w' : '-';
   *cp++ = (mode & S_ISGID
-              ? (mode & S_IXGRP ? 's' : 'S')
-              : (mode & S_IXGRP ? 'x' : '-'));
+               ? (mode & S_IXGRP ? 's' : 'S')
+               : (mode & S_IXGRP ? 'x' : '-'));
   *cp++ = mode & S_IROTH ? 'r' : '-';
   *cp++ = mode & S_IWOTH ? 'w' : '-';
   *cp++ = (mode & S_ISVTX
-              ? (mode & S_IXOTH ? 't' : 'T')
-              : (mode & S_IXOTH ? 'x' : '-'));
+               ? (mode & S_IXOTH ? 't' : 'T')
+               : (mode & S_IXOTH ? 'x' : '-'));
   *cp = '\0';
   return cp;
 }
@@ -407,7 +407,7 @@ int do_shell_expansion(char *name, int name_len)
       cmd =  get_pool_memory(PM_FNAME);
       /* look for shell */
       if ((shellcmd = getenv("SHELL")) == NULL) {
-        shellcmd = "/bin/sh";
+         shellcmd = "/bin/sh";
       }
       pm_strcpy(&cmd, shellcmd);
       pm_strcat(&cmd, " -c \"echo ");
@@ -419,7 +419,7 @@ int do_shell_expansion(char *name, int name_len)
         fgets(line, sizeof(line), bpipe->rfd);
         strip_trailing_junk(line);
         stat = close_bpipe(bpipe);
-        Dmsg2(400, "stat=%d got: %s\n", stat, line);
+         Dmsg2(400, "stat=%d got: %s\n", stat, line);
       } else {
         stat = 1;                    /* error */
       }
@@ -454,7 +454,7 @@ void make_session_key(char *key, char *seed, int mode)
      /* The following creates a seed for the session key generator
        based on a collection of volatile and environment-specific
        information unlikely to be vulnerable (as a whole) to an
-       exhaustive search attack.  If one of these items isn't
+        exhaustive search attack.  If one of these items isn't
        available on your machine, replace it with something
        equivalent or, if you like, just delete it. */
 
@@ -492,7 +492,7 @@ void make_session_key(char *key, char *seed, int mode)
           key[k++] = Rad16(rb & 0xF);
 #undef Rad16
           if (j & 1) {
-             key[k++] = '-';
+              key[k++] = '-';
           }
        }
        key[--k] = 0;
@@ -516,6 +516,7 @@ void make_session_key(char *key, char *seed, int mode)
  *  %j = Unique Job name
  *  %l = job level
  *  %n = Unadorned Job name
+ *  %s = Since time
  *  %t = Job type (Backup, ...)
  *  %r = Recipients
  *  %v = Volume name
@@ -538,85 +539,92 @@ POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to)
    for (p=imsg; *p; p++) {
       if (*p == '%') {
         switch (*++p) {
-        case '%':
-           str = "%";
+         case '%':
+            str = "%";
            break;
-        case 'c':
+         case 'c':
            if (jcr) {
               str = jcr->client_name;
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'd':
-           str = my_name;            /* Director's name */
+         case 'd':
+            str = my_name;            /* Director's name */
            break;
-        case 'e':
+         case 'e':
            if (jcr) {
               str = job_status_to_str(jcr->JobStatus);
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'i':
+         case 'i':
            if (jcr) {
-              bsnprintf(add, sizeof(add), "%d", jcr->JobId);
+               bsnprintf(add, sizeof(add), "%d", jcr->JobId);
               str = add;
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'j':                    /* Job name */
+         case 'j':                    /* Job name */
            if (jcr) {
               str = jcr->Job;
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'l':
+         case 'l':
            if (jcr) {
               str = job_level_to_str(jcr->JobLevel);
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'n':
+         case 'n':
             if (jcr) {
                bstrncpy(name, jcr->Job, sizeof(name));
                /* There are three periods after the Job name */
                for (i=0; i<3; i++) {
-                  if ((q=strrchr(name, '.')) != NULL) {
+                   if ((q=strrchr(name, '.')) != NULL) {
                       *q = 0;
                   }
                }
                str = name;
             } else {
-               str = "*none*";
+                str = "*none*";
             }
             break;
-        case 'r':
+         case 'r':
            str = to;
            break;
-        case 't':
+         case 's':                    /* since time */
+           if (jcr && jcr->stime) {
+              str = jcr->stime;
+           } else {
+               str = "*none*";
+           }
+           break;
+         case 't':
            if (jcr) {
               str = job_type_to_str(jcr->JobType);
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
-        case 'v':
+         case 'v':
            if (jcr) {
               if (jcr->VolumeName && jcr->VolumeName[0]) {
                  str = jcr->VolumeName;
               } else {
-                 str = "";
+                  str = "";
               }
            } else {
-              str = "*none*";
+               str = "*none*";
            }
            break;
         default:
-           add[0] = '%';
+            add[0] = '%';
            add[1] = *p;
            add[2] = 0;
            str = add;
index e0543f3e91160e3803588467292d43d6c5de0b72..0fc975be3a36fd6c6e11d20fe79282865825d9b9 100644 (file)
@@ -64,6 +64,7 @@ DCR *new_dcr(JCR *jcr, DEVICE *dev)
  *  as it should be, then remove it. Also zap the jcr pointer
  *  to the dcr if it is the same one.
  */
+#ifdef needed
 static void remove_dcr_from_dcrs(DCR *dcr)
 {
    JCR *jcr = dcr->jcr;
@@ -82,6 +83,7 @@ static void remove_dcr_from_dcrs(DCR *dcr)
       }
    }
 }
+#endif
 
 /*
  * Free up all aspects of the given dcr -- i.e. dechain it,
@@ -149,7 +151,7 @@ bool reserve_device_for_read(JCR *jcr, DEVICE *dev)
 
    if (dev->is_busy()) {
       Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
-           dev_name(dev), jcr->JobId);
+           dev->name(), jcr->JobId);
       goto get_out;
    }
    if (!dcr) {
@@ -353,11 +355,16 @@ get_out:
  *  the DIR to reserve multiple devices before *really* 
  *  starting the job. It also permits the SD to refuse 
  *  certain devices (not up, ...).
+ *
+ * Note, in reserving a device, if the device is for the
+ *  same pool and the same pool type, then it is acceptable.
+ *  The Media Type has already been checked. If we are
+ *  the first tor reserve the device, we put the pool
+ *  name and pool type in the device record.
  */
 bool reserve_device_for_append(JCR *jcr, DEVICE *dev)
 {
    DCR *dcr = jcr->dcr;
-   bool recycle;
    bool ok = false;
 
    ASSERT(dcr);
@@ -365,60 +372,65 @@ bool reserve_device_for_append(JCR *jcr, DEVICE *dev)
    lock_device(dev);
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
+   if (dev->can_read()) {
+      Jmsg(jcr, M_WARNING, 0, _("Device %s is busy reading.\n"), dev->name());
+      goto bail_out;
+   }
    if (device_is_unmounted(dev)) {
       Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
         dev_name(dev));
-      goto get_out;
+      goto bail_out;
    }
    Dmsg1(190, "reserve_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
-   if (dev->can_append() || dev->num_writers > 0 || dev->reserved_device) {
-      Dmsg0(190, "device already in append.\n");
-      /*
-       * Device already in append mode or reserved for write
-       *
-       * Check if we have the right Volume mounted
-       *   OK if current volume info OK
-       *   OK if next volume matches current volume
-       */
-      bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
-      if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
-         !(dir_find_next_appendable_volume(dcr) &&
-           strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
-         Dmsg0(190, "Wrong tape mounted.\n");
-        if (dev->num_writers != 0 || dev->reserved_device) {
-            Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
-           goto get_out;
+   /*
+    * First handle the case that the drive is not yet in append mode
+    */
+   if (!dev->can_append() && dev->num_writers == 0) {
+      /* Now check if there are any reservations on the drive */
+      if (dev->reserved_device) {          
+        /* Yes, now check if we want the same Pool and pool type */
+        if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
+            strcmp(dev->pool_type, dcr->pool_type) == 0) {
+           /* OK, compatible device */
+        } else {
+           /* Drive not suitable for us */
+            Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->name());
+           goto bail_out;
         }
       } else {
-        /*
-         * At this point, the correct tape is already mounted, so
-         *   we do not need to do mount_next_write_volume(), unless
-         *   we need to recycle the tape.
-         */
-          recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
-          Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
-         if (recycle && dev->num_writers != 0) {
-             Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
-                  " because it is in use by another job.\n"));
-            goto get_out;
-         }
-         if (dev->num_writers == 0) {
-            memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
-         }
-       }
-   } else {
-      if (dev->can_read()) {
-         Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
-        goto get_out;
+        /* Device is available but not yet reserved, reserve it for us */
+        bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
+        bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
+        dev->PoolId = dcr->PoolId;
       }
-      ASSERT(dev->num_writers == 0);
+      goto do_reserve;
    }
 
+   /*
+    * Now check if the device is in append mode 
+    */
+   if (dev->can_append() || dev->num_writers > 0) {
+      Dmsg0(190, "device already in append.\n");
+      /* Yes, now check if we want the same Pool and pool type */
+      if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
+         strcmp(dev->pool_type, dcr->pool_type) == 0) {
+        /* OK, compatible device */
+      } else {
+        /* Drive not suitable for us */
+         Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->name());
+        goto bail_out;
+      }
+   } else {
+      Pmsg0(000, "Logic error!!!! Should not get here.\n");
+      goto bail_out;                 /* should not get here */
+   }
+
+do_reserve:
    dev->reserved_device++;
    dcr->reserved_device = true;
    ok = true;
 
-get_out:
+bail_out:
    P(dev->mutex);
    unblock_device(dev);
    V(dev->mutex);
@@ -453,6 +465,15 @@ DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev)
       dev->reserved_device--;
       dcr->reserved_device = false;
    }
+
+   /*
+    * With the reservation system, this should not happen
+    */
+   if (dev->can_read()) {
+      Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
+      goto get_out;
+   }
+
    if (dev->can_append()) {
       Dmsg0(190, "device already in append.\n");
       /*
@@ -497,10 +518,6 @@ DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev)
    } else {
       /* Not already in append mode, so mount the device */
       Dmsg0(190, "Not in append mode, try mount.\n");
-      if (dev->can_read()) {
-         Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
-        goto get_out;
-      }
       ASSERT(dev->num_writers == 0);
       do_mount = true;
    }
index 7671daa1a6fae486e43d440568af0691e5bd69f9..461b60b96ab8aa6571ff31e0d2432c95a73b1671 100644 (file)
@@ -30,7 +30,7 @@
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
 /* Requests sent to the Director */
-static char Find_media[]   = "CatReq Job=%s FindMedia=%d\n";
+static char Find_media[]   = "CatReq Job=%s FindMedia=%d PoolId=%s\n";
 static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n";
 static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s"
    " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u"
@@ -90,7 +90,7 @@ static bool do_get_volume_info(DCR *dcr)
        return false;
     }
     memset(&vol, 0, sizeof(vol));
-    Dmsg1(300, "Get vol info=%s", dir->msg);
+    Dmsg1(100, "<dird %s", dir->msg);
     n = sscanf(dir->msg, OK_media, vol.VolCatName,
               &vol.VolCatJobs, &vol.VolCatFiles,
               &vol.VolCatBlocks, &vol.VolCatBytes,
@@ -133,10 +133,10 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
     BSOCK *dir = jcr->dir_bsock;
 
     bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
-    Dmsg1(300, "dir_get_volume_info=%s\n", dcr->VolCatInfo.VolCatName);
     bash_spaces(dcr->VolCatInfo.VolCatName);
     bnet_fsend(dir, Get_Vol_Info, jcr->Job, dcr->VolCatInfo.VolCatName,
        writing==GET_VOL_INFO_FOR_WRITE?1:0);
+    Dmsg1(100, ">dird: %s", dir->msg);
     return do_get_volume_info(dcr);
 }
 
@@ -154,6 +154,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
 {
     JCR *jcr = dcr->jcr;
     BSOCK *dir = jcr->dir_bsock;
+    char ed1[50];
     JCR *njcr;
 
     Dmsg0(200, "dir_find_next_appendable_volume\n");
@@ -163,7 +164,8 @@ bool dir_find_next_appendable_volume(DCR *dcr)
      *  drive, so we continue looking for a not in use Volume.
      */
     for (int vol_index=1;  vol_index < 3; vol_index++) {
-       bnet_fsend(dir, Find_media, jcr->Job, vol_index);
+       bnet_fsend(dir, Find_media, jcr->Job, vol_index, edit_int64(dcr->PoolId, ed1));
+       Dmsg1(100, ">dird: %s", dir->msg);
        if (do_get_volume_info(dcr)) {
           Dmsg2(300, "JobId=%d got possible Vol=%s\n", jcr->JobId, dcr->VolumeName);
          bool found = false;
@@ -249,8 +251,7 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       edit_uint64(vol->VolReadTime, ed3),
       edit_uint64(vol->VolWriteTime, ed4),
       vol->VolCatParts);
-
-   Dmsg1(300, "update_volume_info(): %s", dir->msg);
+    Dmsg1(100, ">dird: %s", dir->msg);
 
    if (!do_get_volume_info(dcr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
@@ -281,14 +282,14 @@ bool dir_create_jobmedia_record(DCR *dcr)
       dcr->VolFirstIndex, dcr->VolLastIndex,
       dcr->StartFile, dcr->EndFile,
       dcr->StartBlock, dcr->EndBlock);
-   Dmsg1(400, "create_jobmedia(): %s", dir->msg);
+    Dmsg1(100, ">dird: %s", dir->msg);
    if (bnet_recv(dir) <= 0) {
       Dmsg0(190, "create_jobmedia error bnet_recv\n");
       Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"),
           bnet_strerror(dir));
       return false;
    }
-   Dmsg1(400, "Create_jobmedia: %s", dir->msg);
+   Dmsg1(100, "<dir: %s", dir->msg);
    if (strcmp(dir->msg, OK_create) != 0) {
       Dmsg1(130, "Bad response from Dir: %s\n", dir->msg);
       Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg);
@@ -322,6 +323,7 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec)
    ser_uint32(rec->data_len);
    ser_bytes(rec->data, rec->data_len);
    dir->msglen = ser_length(dir->msg);
+   Dmsg1(100, ">dird: %s", dir->msg);
    return bnet_send(dir);
 }
 
index e244dc621aa05717d8e186cc5617b4dc79501e58..e34856ec894596cfbc24a18dca1df5056eb959fc 100644 (file)
@@ -2,18 +2,18 @@
  *
  *   dev.c  -- low level operations on device (storage device)
  *
- *              Kern Sibbald, MM
+ *             Kern Sibbald, MM
  *
  *     NOTE!!!! None of these routines are reentrant. You must
- *        use lock_device() and unlock_device() at a higher level,
- *        or use the xxx_device() equivalents.  By moving the
- *        thread synchronization to a higher level, we permit
+ *       use lock_device() and unlock_device() at a higher level,
+ *       or use the xxx_device() equivalents.  By moving the
+ *       thread synchronization to a higher level, we permit
  *        the higher level routines to "seize" the device and
- *        to carry out operations without worrying about who
- *        set what lock (i.e. race conditions).
+ *       to carry out operations without worrying about who
+ *       set what lock (i.e. race conditions).
  *
  *     Note, this is the device dependent code, and my have
- *           to be modified for each system, but is meant to
+ *          to be modified for each system, but is meant to
  *           be as "generic" as possible.
  *
  *     The purpose of this code is to develop a SIMPLE Storage
@@ -114,10 +114,10 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
    if (stat(device->device_name, &statp) < 0) {
       berrno be;
       if (dev) {
-         dev->dev_errno = errno;
+        dev->dev_errno = errno;
       }
       Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"), 
-         device->device_name, be.strerror());
+        device->device_name, be.strerror());
       return NULL;
    }
    
@@ -132,10 +132,10 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
       fifo = true;
    } else {
       if (dev) {
-         dev->dev_errno = ENODEV;
+        dev->dev_errno = ENODEV;
       }
       Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory. st_mode=%x\n"),
-         device->device_name, statp.st_mode);
+        device->device_name, statp.st_mode);
       return NULL;
    }
    if (!dev) {
@@ -189,11 +189,11 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
     */
    if (dev->is_file() && device->cap_bits & CAP_REQMOUNT) {
       if (stat(device->mount_point, &statp) < 0) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to stat mount point %s: ERR=%s\n"), 
-            device->mount_point, be.strerror());
-         return NULL;
+           device->mount_point, be.strerror());
+        return NULL;
       }
       if (!device->mount_command || !device->unmount_command) {
          Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
@@ -206,12 +206,12 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
 
    if (dev->max_block_size > 1000000) {
       Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
-         dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
+        dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
       dev->max_block_size = 0;
    }
    if (dev->max_block_size % TAPE_BSIZE != 0) {
       Jmsg2(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size.\n"),
-         dev->max_block_size, dev->dev_name);
+        dev->max_block_size, dev->dev_name);
    }
 
    dev->errmsg = get_pool_memory(PM_EMSG);
@@ -260,7 +260,7 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
  * initialize buffer pointers.
  *
  * Returns:  -1  on error
- *           fd  on success
+ *          fd  on success
  *
  * Note, for a tape, the VolName is the name we give to the
  *    volume (not really used here), but for a file, the
@@ -279,11 +279,11 @@ open_dev(DEVICE *dev, char *VolName, int mode)
        *  starts and snatches up the device.
        */
       if (VolName && strcmp(dev->VolCatInfo.VolCatName, VolName) != 0) {
-         return -1;
+        return -1;
       }
       dev->use_count++;
       Mmsg2(&dev->errmsg, _("WARNING!!!! device %s opened %d times!!!\n"),
-            dev->dev_name, dev->use_count);
+           dev->dev_name, dev->use_count);
       Emsg1(M_WARNING, 0, "%s", dev->errmsg);
       return dev->fd;
    }
@@ -292,7 +292,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
    }
 
    Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev_is_tape(dev),
-         dev->dev_name, dev->VolCatInfo.VolCatName);
+        dev->dev_name, dev->VolCatInfo.VolCatName);
    dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
    dev->label_type = B_BACULA_LABEL;
    if (dev->is_tape() || dev->is_fifo()) {
@@ -300,53 +300,53 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       int timeout;
       Dmsg0(29, "open_dev: device is tape\n");
       if (mode == OPEN_READ_WRITE) {
-         dev->mode = O_RDWR | O_BINARY;
+        dev->mode = O_RDWR | O_BINARY;
       } else if (mode == OPEN_READ_ONLY) {
-         dev->mode = O_RDONLY | O_BINARY;
+        dev->mode = O_RDONLY | O_BINARY;
       } else if (mode == OPEN_WRITE_ONLY) {
-         dev->mode = O_WRONLY | O_BINARY;
+        dev->mode = O_WRONLY | O_BINARY;
       } else {
          Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n"));
       }
       timeout = dev->max_open_wait;
       errno = 0;
       if (dev->is_fifo() && timeout) {
-         /* Set open timer */
-         dev->tid = start_thread_timer(pthread_self(), timeout);
+        /* Set open timer */
+        dev->tid = start_thread_timer(pthread_self(), timeout);
       }
       /* If busy retry each second for max_open_wait seconds */
       while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) {
-         berrno be;
-         if (errno == EINTR || errno == EAGAIN) {
-            continue;
-         }
-         if (errno == EBUSY && timeout-- > 0) {
+        berrno be;
+        if (errno == EINTR || errno == EAGAIN) {
+           continue;
+        }
+        if (errno == EBUSY && timeout-- > 0) {
             Dmsg2(100, "Device %s busy. ERR=%s\n", dev->dev_name, be.strerror());
-            bmicrosleep(1, 0);
-            continue;
-         }
-         dev->dev_errno = errno;
+           bmicrosleep(1, 0);
+           continue;
+        }
+        dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"),
-               dev->dev_name, be.strerror());
-         /* Stop any open timer we set */
-         if (dev->tid) {
-            stop_thread_timer(dev->tid);
-            dev->tid = 0;
-         }
-         Emsg0(M_FATAL, 0, dev->errmsg);
-         break;
+              dev->dev_name, be.strerror());
+        /* Stop any open timer we set */
+        if (dev->tid) {
+           stop_thread_timer(dev->tid);
+           dev->tid = 0;
+        }
+        Emsg0(M_FATAL, 0, dev->errmsg);
+        break;
       }
       if (dev->fd >= 0) {
-         dev->dev_errno = 0;
-         dev->state |= ST_OPENED;
-         dev->use_count = 1;
-         update_pos_dev(dev);             /* update position */
-         set_os_device_parameters(dev);      /* do system dependent stuff */
+        dev->dev_errno = 0;
+        dev->state |= ST_OPENED;
+        dev->use_count = 1;
+        update_pos_dev(dev);             /* update position */
+        set_os_device_parameters(dev);      /* do system dependent stuff */
       }
       /* Stop any open() timer we started */
       if (dev->tid) {
-         stop_thread_timer(dev->tid);
-         dev->tid = 0;
+        stop_thread_timer(dev->tid);
+        dev->tid = 0;
       }
       Dmsg1(29, "open_dev: tape %d opened\n", dev->fd);
    } else {
@@ -356,31 +356,31 @@ open_dev(DEVICE *dev, char *VolName, int mode)
        * Handle opening of File Archive (not a tape)
        */     
       if (dev->part == 0) {
-         dev->file_size = 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;
+        dev->num_parts = dev->VolCatInfo.VolCatParts;
       }
       
       if (VolName == NULL || *VolName == 0) {
          Mmsg(dev->errmsg, _("Could not open file device %s. No Volume name given.\n"),
-            dev->dev_name);
-         return -1;
+           dev->dev_name);
+        return -1;
       }
       get_filename(dev, VolName, archive_name);
 
       if (mount_dev(dev, 1) < 0) {
          Mmsg(dev->errmsg, _("Could not mount archive device %s.\n"),
-              dev->dev_name);
-         Emsg0(M_FATAL, 0, dev->errmsg);
-         dev->fd = -1;
-         return dev->fd;
+             dev->dev_name);
+        Emsg0(M_FATAL, 0, dev->errmsg);
+        dev->fd = -1;
+        return dev->fd;
       }
-            
+           
       Dmsg2(29, "open_dev: device is disk %s (mode:%d)\n", archive_name.c_str(), mode);
       dev->openmode = mode;
       
@@ -389,42 +389,42 @@ open_dev(DEVICE *dev, char *VolName, int mode)
        *   OPEN_READ_ONLY as writing would be an error.
        */
       if (dev->part < dev->num_parts) {
-         mode = OPEN_READ_ONLY;
+        mode = OPEN_READ_ONLY;
       }
       
       if (mode == OPEN_READ_WRITE) {
-         dev->mode = O_CREAT | O_RDWR | O_BINARY;
+        dev->mode = O_CREAT | O_RDWR | O_BINARY;
       } else if (mode == OPEN_READ_ONLY) {
-         dev->mode = O_RDONLY | O_BINARY;
+        dev->mode = O_RDONLY | O_BINARY;
       } else if (mode == OPEN_WRITE_ONLY) {
-         dev->mode = O_WRONLY | O_BINARY;
+        dev->mode = O_WRONLY | O_BINARY;
       } else {
          Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n"));
       }
       /* If creating file, give 0640 permissions */
       if ((dev->fd = open(archive_name.c_str(), dev->mode, 0640)) < 0) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
-         Emsg0(M_FATAL, 0, dev->errmsg);
+        Emsg0(M_FATAL, 0, dev->errmsg);
       } else {
-         dev->dev_errno = 0;
-         dev->state |= ST_OPENED;
-         dev->use_count = 1;
-         update_pos_dev(dev);                /* update position */
-         if (fstat(dev->fd, &filestat) < 0) {
-            berrno be;
-            dev->dev_errno = errno;
+        dev->dev_errno = 0;
+        dev->state |= ST_OPENED;
+        dev->use_count = 1;
+        update_pos_dev(dev);                /* update position */
+        if (fstat(dev->fd, &filestat) < 0) {
+           berrno be;
+           dev->dev_errno = errno;
             Mmsg2(&dev->errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
-            Emsg0(M_FATAL, 0, dev->errmsg);
-         } else {
-            dev->part_size = filestat.st_size;
-         }
+           Emsg0(M_FATAL, 0, dev->errmsg);
+        } else {
+           dev->part_size = filestat.st_size;
+        }
       }
       Dmsg4(29, "open_dev: disk fd=%d opened, part=%d/%d, part_size=%u\n", dev->fd, dev->part, dev->num_parts, dev->part_size);
       if (dev->is_dvd() && (dev->mode != OPEN_READ_ONLY) && 
-          (dev->free_space_errno == 0 || dev->num_parts == dev->part)) {
-         update_free_space_dev(dev);
+         (dev->free_space_errno == 0 || dev->num_parts == dev->part)) {
+        update_free_space_dev(dev);
       }
    }
    return dev->fd;
@@ -442,7 +442,7 @@ bool _rewind_dev(char *file, int line, DEVICE *dev)
 /*
  * Rewind the device.
  *  Returns: true  on success
- *           false on failure
+ *          false on failure
  */
 bool rewind_dev(DEVICE *dev)
 {
@@ -453,7 +453,7 @@ bool rewind_dev(DEVICE *dev)
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
       Mmsg1(&dev->errmsg, _("Bad call to rewind_dev. Device %s not open\n"),
-            dev->dev_name);
+           dev->dev_name);
       Emsg0(M_ABORT, 0, dev->errmsg);
       return false;
    }
@@ -469,30 +469,30 @@ bool rewind_dev(DEVICE *dev)
        * retrying every 5 seconds.
        */
       for (i=dev->max_rewind_wait; ; i -= 5) {
-         if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-            berrno be;
-            clrerror_dev(dev, MTREW);
-            if (i == dev->max_rewind_wait) {
+        if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+           berrno be;
+           clrerror_dev(dev, MTREW);
+           if (i == dev->max_rewind_wait) {
                Dmsg1(200, "Rewind error, %s. retrying ...\n", be.strerror());
-            }
-            if (dev->dev_errno == EIO && i > 0) {
+           }
+           if (dev->dev_errno == EIO && i > 0) {
                Dmsg0(200, "Sleeping 5 seconds.\n");
-               bmicrosleep(5, 0);
-               continue;
-            }
+              bmicrosleep(5, 0);
+              continue;
+           }
             Mmsg2(&dev->errmsg, _("Rewind error on %s. ERR=%s.\n"),
-               dev->dev_name, be.strerror());
-            return false;
-         }
-         break;
+              dev->dev_name, be.strerror());
+           return false;
+        }
+        break;
       }
    } else if (dev->is_file()) {      
       if (lseek_dev(dev, (off_t)0, SEEK_SET) < 0) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         return false;
+           dev->dev_name, be.strerror());
+        return false;
       }
    }
    return true;
@@ -518,13 +518,13 @@ void DEVICE::set_eof()
 void DEVICE::set_eot() 
 {
    state |= (ST_EOF|ST_EOT|ST_WEOT);
-   state &= ~ST_APPEND;          /* make tape read-only */
+   state &= ~ST_APPEND;         /* make tape read-only */
 }
 
 /*
  * Position device to end of medium (end of data)
  *  Returns: 1 on succes
- *           0 on error
+ *          0 on error
  */
 int
 eod_dev(DEVICE *dev)
@@ -549,14 +549,14 @@ eod_dev(DEVICE *dev)
       pos = lseek_dev(dev, (off_t)0, SEEK_END);
 //    Dmsg1(100, "====== Seek to %lld\n", pos);
       if (pos >= 0) {
-         update_pos_dev(dev);
-         dev->state |= ST_EOT;
-         return 1;
+        update_pos_dev(dev);
+        dev->state |= ST_EOT;
+        return 1;
       }
       dev->dev_errno = errno;
       berrno be;
       Mmsg2(&dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
-             dev->dev_name, be.strerror());
+            dev->dev_name, be.strerror());
       return 0;
    }
 #ifdef MTEOM
@@ -564,9 +564,9 @@ eod_dev(DEVICE *dev)
       Dmsg0(100,"Using FAST FSF for EOM\n");
       /* If unknown position, rewind */
       if (!dev_get_os_pos(dev, &mt_stat)) {
-        if (!rewind_dev(dev)) {
-          return 0;
-        }
+       if (!rewind_dev(dev)) {
+         return 0;
+       }
       }
       mt_com.mt_op = MTFSF;
       /*
@@ -575,33 +575,33 @@ eod_dev(DEVICE *dev)
        */
       mt_com.mt_count = INT16_MAX;    /* use big positive number */
       if (mt_com.mt_count < 0) {
-         mt_com.mt_count = INT16_MAX; /* brain damaged system */
+        mt_com.mt_count = INT16_MAX; /* brain damaged system */
       }
    }
 
    if (dev_cap(dev, CAP_MTIOCGET) && (dev_cap(dev, CAP_FASTFSF) || dev_cap(dev, CAP_EOM))) {
       if (dev_cap(dev, CAP_EOM)) {
          Dmsg0(100,"Using EOM for EOM\n");
-         mt_com.mt_op = MTEOM;
-         mt_com.mt_count = 1;
+        mt_com.mt_op = MTEOM;
+        mt_com.mt_count = 1;
       }
 
       if ((stat=ioctl(dev->fd, MTIOCTOP, (char *)&mt_com)) < 0) {
-         berrno be;
-         clrerror_dev(dev, mt_com.mt_op);
+        berrno be;
+        clrerror_dev(dev, mt_com.mt_op);
          Dmsg1(50, "ioctl error: %s\n", be.strerror());
-         update_pos_dev(dev);
+        update_pos_dev(dev);
          Mmsg2(&dev->errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         return 0;
+           dev->dev_name, be.strerror());
+        return 0;
       }
 
       if (!dev_get_os_pos(dev, &mt_stat)) {
-         berrno be;
-         clrerror_dev(dev, -1);
+        berrno be;
+        clrerror_dev(dev, -1);
          Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         return 0;
+           dev->dev_name, be.strerror());
+        return 0;
       }
       Dmsg2(100, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
       dev->set_eof();
@@ -615,7 +615,7 @@ eod_dev(DEVICE *dev)
        * Rewind then use FSF until EOT reached
        */
       if (!rewind_dev(dev)) {
-         return 0;
+        return 0;
       }
       /*
        * Move file by file to the end of the tape
@@ -623,25 +623,25 @@ eod_dev(DEVICE *dev)
       int file_num;
       for (file_num=dev->file; !dev->at_eot(); file_num++) {
          Dmsg0(200, "eod_dev: doing fsf 1\n");
-         if (!fsf_dev(dev, 1)) {
+        if (!fsf_dev(dev, 1)) {
             Dmsg0(200, "fsf_dev error.\n");
-            return 0;
-         }
-         /*
-          * Avoid infinite loop. ***FIXME*** possibly add code
-          *   to set EOD or to turn off CAP_FASTFSF if on.
-          */
-         if (file_num == (int)dev->file) {
-            struct mtget mt_stat;
+           return 0;
+        }
+        /*
+         * Avoid infinite loop. ***FIXME*** possibly add code
+         *   to set EOD or to turn off CAP_FASTFSF if on.
+         */
+        if (file_num == (int)dev->file) {
+           struct mtget mt_stat;
             Dmsg1(100, "fsf_dev did not advance from file %d\n", file_num);
-            if (dev_get_os_pos(dev, &mt_stat)) {
+           if (dev_get_os_pos(dev, &mt_stat)) {
                Dmsg2(100, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno);
-               dev->set_eof();
-               dev->file = mt_stat.mt_fileno;
-            }
-            stat = 0;
-            break;                    /* we are not progressing, bail out */
-         }
+              dev->set_eof();
+              dev->file = mt_stat.mt_fileno;
+           }
+           stat = 0;
+           break;                    /* we are not progressing, bail out */
+        }
       }
    }
    /*
@@ -656,12 +656,12 @@ eod_dev(DEVICE *dev)
       /* If BSF worked and fileno is known (not -1), set file */
       if (dev_get_os_pos(dev, &mt_stat)) {
          Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno);
-         dev->file = mt_stat.mt_fileno;
+        dev->file = mt_stat.mt_fileno;
       } else {
-         dev->file++;                 /* wing it -- not correct on all OSes */
+        dev->file++;                 /* wing it -- not correct on all OSes */
       }
    } else {
-      update_pos_dev(dev);                   /* update position */
+      update_pos_dev(dev);                  /* update position */
       stat = 1;
    }
    Dmsg1(200, "EOD dev->file=%d\n", dev->file);
@@ -672,7 +672,7 @@ eod_dev(DEVICE *dev)
  * Set the position of the device -- only for files
  *   For other devices, there is no generic way to do it.
  *  Returns: true  on succes
- *           false on error
+ *          false on error
  */
 bool update_pos_dev(DEVICE *dev)
 {
@@ -692,14 +692,14 @@ bool update_pos_dev(DEVICE *dev)
       dev->file_addr = 0;
       pos = lseek_dev(dev, (off_t)0, SEEK_CUR);
       if (pos < 0) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Pmsg1(000, "Seek error: ERR=%s\n", be.strerror());
          Mmsg2(&dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         ok = false;
+           dev->dev_name, be.strerror());
+        ok = false;
       } else {
-         dev->file_addr = pos;
+        dev->file_addr = pos;
       }
    }
    return ok;
@@ -733,49 +733,49 @@ uint32_t status_dev(DEVICE *dev)
       Dmsg0(-20," Bacula status:");
       Dmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num);
       if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         return 0;
+           dev->dev_name, be.strerror());
+        return 0;
       }
       Dmsg0(-20, " Device status:");
 
 #if defined(HAVE_LINUX_OS)
       if (GMT_EOF(mt_stat.mt_gstat)) {
-         stat |= BMT_EOF;
+        stat |= BMT_EOF;
          Dmsg0(-20, " EOF");
       }
       if (GMT_BOT(mt_stat.mt_gstat)) {
-         stat |= BMT_BOT;
+        stat |= BMT_BOT;
          Dmsg0(-20, " BOT");
       }
       if (GMT_EOT(mt_stat.mt_gstat)) {
-         stat |= BMT_EOT;
+        stat |= BMT_EOT;
          Dmsg0(-20, " EOT");
       }
       if (GMT_SM(mt_stat.mt_gstat)) {
-         stat |= BMT_SM;
+        stat |= BMT_SM;
          Dmsg0(-20, " SM");
       }
       if (GMT_EOD(mt_stat.mt_gstat)) {
-         stat |= BMT_EOD;
+        stat |= BMT_EOD;
          Dmsg0(-20, " EOD");
       }
       if (GMT_WR_PROT(mt_stat.mt_gstat)) {
-         stat |= BMT_WR_PROT;
+        stat |= BMT_WR_PROT;
          Dmsg0(-20, " WR_PROT");
       }
       if (GMT_ONLINE(mt_stat.mt_gstat)) {
-         stat |= BMT_ONLINE;
+        stat |= BMT_ONLINE;
          Dmsg0(-20, " ONLINE");
       }
       if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
-         stat |= BMT_DR_OPEN;
+        stat |= BMT_DR_OPEN;
          Dmsg0(-20, " DR_OPEN");
       }
       if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
-         stat |= BMT_IM_REP_EN;
+        stat |= BMT_IM_REP_EN;
          Dmsg0(-20, " IM_REP_EN");
       }
 #endif /* !SunOS && !OSF */
@@ -794,7 +794,7 @@ uint32_t status_dev(DEVICE *dev)
 /*
  * Load medium in device
  *  Returns: true  on success
- *           false on failure
+ *          false on failure
  */
 bool load_dev(DEVICE *dev)
 {
@@ -814,9 +814,9 @@ bool load_dev(DEVICE *dev)
 #ifndef MTLOAD
    Dmsg0(200, "stored: MTLOAD command not available\n");
    berrno be;
-   dev->dev_errno = ENOTTY;           /* function not available */
+   dev->dev_errno = ENOTTY;          /* function not available */
    Mmsg2(&dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
    return false;
 #else
 
@@ -829,7 +829,7 @@ bool load_dev(DEVICE *dev)
       berrno be;
       dev->dev_errno = errno;
       Mmsg2(&dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
       return false;
    }
    return true;
@@ -839,7 +839,7 @@ bool load_dev(DEVICE *dev)
 /*
  * Rewind device and put it offline
  *  Returns: true  on success
- *           false on failure
+ *          false on failure
  */
 bool offline_dev(DEVICE *dev)
 {
@@ -871,7 +871,7 @@ bool offline_dev(DEVICE *dev)
       berrno be;
       dev->dev_errno = errno;
       Mmsg2(&dev->errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
       return false;
    }
    Dmsg1(100, "Offlined device %s\n", dev->dev_name);
@@ -901,7 +901,7 @@ bool offline_or_rewind_dev(DEVICE *dev)
 /*
  * Foward space a file
  *   Returns: true  on success
- *            false on failure
+ *           false on failure
  */
 bool
 fsf_dev(DEVICE *dev, int num)
@@ -943,14 +943,14 @@ fsf_dev(DEVICE *dev, int num)
       mt_com.mt_count = num;
       stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
       if (stat < 0 || !dev_get_os_pos(dev, &mt_stat)) {
-         berrno be;
-         dev->state |= ST_EOT;
+        berrno be;
+        dev->state |= ST_EOT;
          Dmsg0(200, "Set ST_EOT\n");
-         clrerror_dev(dev, MTFSF);
+        clrerror_dev(dev, MTFSF);
          Mmsg2(dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
+           dev->dev_name, be.strerror());
          Dmsg1(200, "%s", dev->errmsg);
-         return false;
+        return false;
       }
       Dmsg2(200, "fsf file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
       dev->set_eof();
@@ -969,60 +969,60 @@ fsf_dev(DEVICE *dev, int num)
       int rbuf_len;
       Dmsg0(200, "FSF has cap_fsf\n");
       if (dev->max_block_size == 0) {
-         rbuf_len = DEFAULT_BLOCK_SIZE;
+        rbuf_len = DEFAULT_BLOCK_SIZE;
       } else {
-         rbuf_len = dev->max_block_size;
+        rbuf_len = dev->max_block_size;
       }
       rbuf = get_memory(rbuf_len);
       mt_com.mt_op = MTFSF;
       mt_com.mt_count = 1;
       while (num-- && !(dev->state & ST_EOT)) {
          Dmsg0(100, "Doing read before fsf\n");
-         if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) {
-            if (errno == ENOMEM) {     /* tape record exceeds buf len */
-               stat = rbuf_len;        /* This is OK */
-            } else {
-               berrno be;
-               dev->state |= ST_EOT;
-               clrerror_dev(dev, -1);
+        if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) {
+           if (errno == ENOMEM) {     /* tape record exceeds buf len */
+              stat = rbuf_len;        /* This is OK */
+           } else {
+              berrno be;
+              dev->state |= ST_EOT;
+              clrerror_dev(dev, -1);
                Dmsg2(100, "Set ST_EOT read errno=%d. ERR=%s\n", dev->dev_errno,
-                  be.strerror());
+                 be.strerror());
                Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
-                  dev->dev_name, be.strerror());
+                 dev->dev_name, be.strerror());
                Dmsg1(100, "%s", dev->errmsg);
-               break;
-            }
-         }
-         if (stat == 0) {                /* EOF */
-            update_pos_dev(dev);
+              break;
+           }
+        }
+        if (stat == 0) {                /* EOF */
+           update_pos_dev(dev);
             Dmsg1(100, "End of File mark from read. File=%d\n", dev->file+1);
-            /* Two reads of zero means end of tape */
-            if (dev->state & ST_EOF) {
-               dev->state |= ST_EOT;
+           /* Two reads of zero means end of tape */
+           if (dev->state & ST_EOF) {
+              dev->state |= ST_EOT;
                Dmsg0(100, "Set ST_EOT\n");
-               break;
-            } else {
-               dev->set_eof();
-               continue;
-            }
-         } else {                        /* Got data */
-            dev->state &= ~(ST_EOF|ST_EOT);
-         }
+              break;
+           } else {
+              dev->set_eof();
+              continue;
+           }
+        } else {                        /* Got data */
+           dev->state &= ~(ST_EOF|ST_EOT);
+        }
 
          Dmsg0(100, "Doing MTFSF\n");
-         stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
-         if (stat < 0) {                 /* error => EOT */
-            berrno be;
-            dev->state |= ST_EOT;
+        stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
+        if (stat < 0) {                 /* error => EOT */
+           berrno be;
+           dev->state |= ST_EOT;
             Dmsg0(100, "Set ST_EOT\n");
-            clrerror_dev(dev, MTFSF);
+           clrerror_dev(dev, MTFSF);
             Mmsg2(&dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
-               dev->dev_name, be.strerror());
+              dev->dev_name, be.strerror());
             Dmsg0(100, "Got < 0 for MTFSF\n");
             Dmsg1(100, "%s", dev->errmsg);
-         } else {
-            dev->set_eof();
-         }
+        } else {
+           dev->set_eof();
+        }
       }
       free_memory(rbuf);
 
@@ -1032,14 +1032,14 @@ fsf_dev(DEVICE *dev, int num)
    } else {
       Dmsg0(200, "Doing FSR for FSF\n");
       while (num-- && !(dev->state & ST_EOT)) {
-         fsr_dev(dev, INT32_MAX);    /* returns -1 on EOF or EOT */
+        fsr_dev(dev, INT32_MAX);    /* returns -1 on EOF or EOT */
       }
       if (dev->state & ST_EOT) {
-         dev->dev_errno = 0;
+        dev->dev_errno = 0;
          Mmsg1(dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
-         stat = -1;
+        stat = -1;
       } else {
-         stat = 0;
+        stat = 0;
       }
    }
    update_pos_dev(dev);
@@ -1055,7 +1055,7 @@ fsf_dev(DEVICE *dev, int num)
 /*
  * Backward space a file
  *  Returns: false on failure
- *           true  on success
+ *          true  on success
  */
 bool
 bsf_dev(DEVICE *dev, int num)
@@ -1072,7 +1072,7 @@ bsf_dev(DEVICE *dev, int num)
 
    if (!dev->is_tape()) {
       Mmsg1(dev->errmsg, _("Device %s cannot BSF because it is not a tape.\n"),
-         dev->dev_name);
+        dev->dev_name);
       return false;
    }
    Dmsg0(29, "bsf_dev\n");
@@ -1087,7 +1087,7 @@ bsf_dev(DEVICE *dev, int num)
       berrno be;
       clrerror_dev(dev, MTBSF);
       Mmsg2(dev->errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
    }
    update_pos_dev(dev);
    return stat == 0;
@@ -1097,7 +1097,7 @@ bsf_dev(DEVICE *dev, int num)
 /*
  * Foward space a record
  *  Returns: false on failure
- *           true  on success
+ *          true  on success
  */
 bool
 fsr_dev(DEVICE *dev, int num)
@@ -1134,18 +1134,18 @@ fsr_dev(DEVICE *dev, int num)
       Dmsg1(100, "FSF fail: ERR=%s\n", be.strerror());
       if (dev_get_os_pos(dev, &mt_stat)) {
          Dmsg4(100, "Adjust from %d:%d to %d:%d\n", dev->file,
-            dev->block_num, mt_stat.mt_fileno, mt_stat.mt_blkno);
-         dev->file = mt_stat.mt_fileno;
-         dev->block_num = mt_stat.mt_blkno;
+           dev->block_num, mt_stat.mt_fileno, mt_stat.mt_blkno);
+        dev->file = mt_stat.mt_fileno;
+        dev->block_num = mt_stat.mt_blkno;
       } else {
-         if (dev->state & ST_EOF) {
-            dev->state |= ST_EOT;
-         } else {
-            dev->set_eof();
-         }
+        if (dev->state & ST_EOF) {
+           dev->state |= ST_EOT;
+        } else {
+           dev->set_eof();
+        }
       }
       Mmsg2(dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
    }
    update_pos_dev(dev);
    return stat == 0;
@@ -1154,7 +1154,7 @@ fsr_dev(DEVICE *dev, int num)
 /*
  * Backward space a record
  *   Returns:  false on failure
- *             true  on success
+ *            true  on success
  */
 bool
 bsr_dev(DEVICE *dev, int num)
@@ -1188,7 +1188,7 @@ bsr_dev(DEVICE *dev, int num)
       berrno be;
       clrerror_dev(dev, MTBSR);
       Mmsg2(dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
-         dev->dev_name, be.strerror());
+        dev->dev_name, be.strerror());
    }
    update_pos_dev(dev);
    return stat == 0;
@@ -1197,7 +1197,7 @@ bsr_dev(DEVICE *dev, int num)
 /*
  * Reposition the device to file, block
  * Returns: false on failure
- *          true  on success
+ *         true  on success
  */
 bool
 reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
@@ -1213,11 +1213,11 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
       off_t pos = (((off_t)file)<<32) + block;
       Dmsg1(100, "===== lseek_dev to %d\n", (int)pos);
       if (lseek_dev(dev, pos, SEEK_SET) == (off_t)-1) {
-         berrno be;
-         dev->dev_errno = errno;
+        berrno be;
+        dev->dev_errno = errno;
          Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
-         return false;
+           dev->dev_name, be.strerror());
+        return false;
       }
       dev->file = file;
       dev->block_num = block;
@@ -1229,14 +1229,14 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
    if (file < dev->file) {
       Dmsg0(100, "Rewind_dev\n");
       if (!rewind_dev(dev)) {
-         return false;
+        return false;
       }
    }
    if (file > dev->file) {
       Dmsg1(100, "fsf %d\n", file-dev->file);
       if (!fsf_dev(dev, file-dev->file)) {
          Dmsg1(100, "fsf failed! ERR=%s\n", strerror_dev(dev));
-         return false;
+        return false;
       }
       Dmsg2(100, "wanted_file=%d at_file=%d\n", file, dev->file);
    }
@@ -1261,7 +1261,7 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
 /*
  * Write an end of file on the device
  *   Returns: 0 on success
- *            non-zero on failure
+ *           non-zero on failure
  */
 int
 weof_dev(DEVICE *dev, int num)
@@ -1300,7 +1300,7 @@ weof_dev(DEVICE *dev, int num)
       clrerror_dev(dev, MTWEOF);
       if (stat == -1) {
          Mmsg2(dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
-            dev->dev_name, be.strerror());
+           dev->dev_name, be.strerror());
        }
    }
    return stat;
@@ -1330,7 +1330,7 @@ clrerror_dev(DEVICE *dev, int func)
    struct mtget mt_stat;
    char buf[100];
 
-   dev->dev_errno = errno;         /* save errno */
+   dev->dev_errno = errno;        /* save errno */
    if (errno == EIO) {
       dev->VolCatInfo.VolCatErrors++;
    }
@@ -1342,60 +1342,60 @@ clrerror_dev(DEVICE *dev, int func)
       switch (func) {
       case -1:
          Emsg0(M_ABORT, 0, "Got ENOTTY on read/write!\n");
-         break;
+        break;
       case MTWEOF:
          msg = "WTWEOF";
-         dev->capabilities &= ~CAP_EOF; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_EOF; /* turn off feature */
+        break;
 #ifdef MTEOM
       case MTEOM:
          msg = "WTEOM";
-         dev->capabilities &= ~CAP_EOM; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_EOM; /* turn off feature */
+        break;
 #endif
       case MTFSF:
          msg = "MTFSF";
-         dev->capabilities &= ~CAP_FSF; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_FSF; /* turn off feature */
+        break;
       case MTBSF:
          msg = "MTBSF";
-         dev->capabilities &= ~CAP_BSF; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_BSF; /* turn off feature */
+        break;
       case MTFSR:
          msg = "MTFSR";
-         dev->capabilities &= ~CAP_FSR; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_FSR; /* turn off feature */
+        break;
       case MTBSR:
          msg = "MTBSR";
-         dev->capabilities &= ~CAP_BSR; /* turn off feature */
-         break;
+        dev->capabilities &= ~CAP_BSR; /* turn off feature */
+        break;
       case MTREW:
          msg = "MTREW";
-         break;
+        break;
 #ifdef MTSETBLK
       case MTSETBLK:
          msg = "MTSETBLK";
-         break;
+        break;
 #endif
 #ifdef MTSETBSIZ 
       case MTSETBSIZ:
          msg = "MTSETBSIZ";
-         break;
+        break;
 #endif
 #ifdef MTSRSZ
       case MTSRSZ:
          msg = "MTSRSZ";
-         break;
+        break;
 #endif
       default:
          bsnprintf(buf, sizeof(buf), "unknown func code %d", func);
-         msg = buf;
-         break;
+        msg = buf;
+        break;
       }
       if (msg != NULL) {
-         dev->dev_errno = ENOSYS;
+        dev->dev_errno = ENOSYS;
          Mmsg1(dev->errmsg, _("I/O function \"%s\" not supported on this device.\n"), msg);
-         Emsg0(M_ERROR, 0, dev->errmsg);
+        Emsg0(M_ERROR, 0, dev->errmsg);
       }
    }
    /* On some systems such as NetBSD, this clears all errors */
@@ -1466,7 +1466,7 @@ static void do_close(DEVICE *dev)
       get_filename(dev, dev->VolCatInfo.VolCatName, archive_name);
       /* Check that the part file is empty */
       if ((stat(archive_name.c_str(), &statp) == 0) && (statp.st_size == 0)) {
-         unlink(archive_name.c_str());
+        unlink(archive_name.c_str());
       }
    }
    
@@ -1547,7 +1547,7 @@ bool truncate_dev(DEVICE *dev)
       dev->num_parts = 0;
       dev->VolCatInfo.VolCatParts = 0;
       if (open_first_part(dev) < 0) {
-         berrno be;
+        berrno be;
          Mmsg1(&dev->errmsg, "Unable to truncate device, because I'm unable to open the first part. ERR=%s\n", be.strerror());
       }
    }
@@ -1584,12 +1584,19 @@ dev_can_write(DEVICE *dev)
    }
 }
 
+/* This returns the physical device name */
 char *
 dev_name(DEVICE *dev)
 {
    return dev->dev_name;
 }
 
+/* Return the resource name for the device */
+const char *DEVICE::name() const
+{
+   return device->hdr.name;
+}
+
 char *
 dev_vol_name(DEVICE *dev)
 {
@@ -1652,7 +1659,7 @@ void init_dev_wait_timers(DEVICE *dev)
    /* ******FIXME******* put these on config variables */
    dev->min_wait = 60 * 60;
    dev->max_wait = 24 * 60 * 60;
-   dev->max_num_wait = 9;              /* 5 waits =~ 1 day, then 1 day at a time */
+   dev->max_num_wait = 9;             /* 5 waits =~ 1 day, then 1 day at a time */
    dev->wait_sec = dev->min_wait;
    dev->rem_wait_sec = dev->wait_sec;
    dev->num_wait = 0;
@@ -1662,11 +1669,11 @@ void init_dev_wait_timers(DEVICE *dev)
 
 /*
  * Returns: true if time doubled
- *          false if max time expired
+ *         false if max time expired
  */
 bool double_dev_wait_time(DEVICE *dev)
 {
-   dev->wait_sec *= 2;               /* double wait time */
+   dev->wait_sec *= 2;              /* double wait time */
    if (dev->wait_sec > dev->max_wait) {   /* but not longer than maxtime */
       dev->wait_sec = dev->max_wait;
    }
@@ -1687,18 +1694,18 @@ void set_os_device_parameters(DEVICE *dev)
       mt_com.mt_op = MTSETBLK;
       mt_com.mt_count = 0;
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTSETBLK);
+        clrerror_dev(dev, MTSETBLK);
       }
       mt_com.mt_op = MTSETDRVBUFFER;
       mt_com.mt_count = MT_ST_CLEARBOOLEANS;
       if (!dev_cap(dev, CAP_TWOEOF)) {
-         mt_com.mt_count |= MT_ST_TWO_FM;
+        mt_com.mt_count |= MT_ST_TWO_FM;
       }
       if (dev_cap(dev, CAP_EOM)) {
-         mt_com.mt_count |= MT_ST_FAST_MTEOM;
+        mt_com.mt_count |= MT_ST_FAST_MTEOM;
       }
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTSETBLK);
+        clrerror_dev(dev, MTSETBLK);
       }
    }
    return;
@@ -1711,13 +1718,13 @@ void set_os_device_parameters(DEVICE *dev)
       mt_com.mt_op = MTSETBSIZ;
       mt_com.mt_count = 0;
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTSETBSIZ);
+        clrerror_dev(dev, MTSETBSIZ);
       }
       /* Get notified at logical end of tape */
       mt_com.mt_op = MTEWARN;
       mt_com.mt_count = 1;
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTEWARN);
+        clrerror_dev(dev, MTEWARN);
       }
    }
    return;
@@ -1730,7 +1737,7 @@ void set_os_device_parameters(DEVICE *dev)
       mt_com.mt_op = MTSETBSIZ;
       mt_com.mt_count = 0;
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTSETBSIZ);
+        clrerror_dev(dev, MTSETBSIZ);
       }
    }
    return;
@@ -1743,7 +1750,7 @@ void set_os_device_parameters(DEVICE *dev)
       mt_com.mt_op = MTSRSZ;
       mt_com.mt_count = 0;
       if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
-         clrerror_dev(dev, MTSRSZ);
+        clrerror_dev(dev, MTSRSZ);
       }
    }
    return;
@@ -1753,6 +1760,6 @@ void set_os_device_parameters(DEVICE *dev)
 static bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat)
 {
    return dev_cap(dev, CAP_MTIOCGET) && 
-          ioctl(dev->fd, MTIOCGET, (char *)mt_stat) == 0 &&
-          mt_stat->mt_fileno >= 0;
+         ioctl(dev->fd, MTIOCGET, (char *)mt_stat) == 0 &&
+         mt_stat->mt_fileno >= 0;
 }
index a88f14291f84c0d5e48bc1f53f36c80dfc3a2f85..4f562e753913cdace1c4086b1488d242d8b756b5 100644 (file)
@@ -233,6 +233,9 @@ public:
 
    VOLUME_CAT_INFO VolCatInfo;        /* Volume Catalog Information */
    VOLUME_LABEL VolHdr;               /* Actual volume label */
+   uint64_t PoolId;                   /* DB PoolId */
+   char pool_name[MAX_NAME_LENGTH];   /* pool name */
+   char pool_type[MAX_NAME_LENGTH];   /* pool type */
 
    /* Device wait times ***FIXME*** look at durations */
    char BadVolName[MAX_NAME_LENGTH];  /* Last wrong Volume mounted */
@@ -260,6 +263,7 @@ public:
    int can_read() const;
    const char *strerror() const;
    const char *archive_name() const;
+   const char *name() const;
    void set_eof();
    void set_eot();
    void set_append();
@@ -279,7 +283,7 @@ inline int DEVICE::is_dvd()  const { return state & ST_DVD; }
 inline int DEVICE::is_open() const { return state & ST_OPENED; }
 inline int DEVICE::is_offline() const { return state & ST_OFFLINE; }
 inline int DEVICE::is_labeled() const { return state & ST_LABEL; }
-inline int DEVICE::is_busy() const { return state & ST_READ || num_writers; }
+inline int DEVICE::is_busy() const { return state & ST_READ || num_writers || reserved_device; }
 inline int DEVICE::at_eof() const { return state & ST_EOF; }
 inline int DEVICE::at_eot() const { return state & ST_EOT; }
 inline int DEVICE::can_append() const { return state & ST_APPEND; }
@@ -326,6 +330,7 @@ public:
    uint32_t EndBlock;                 /* Ending block written */
    int64_t spool_size;                /* Current spool size */
    int64_t max_spool_size;            /* Max job spool size */
+   uint64_t PoolId;                   /* PoolId from DB */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char pool_name[MAX_NAME_LENGTH];   /* pool name */
    char pool_type[MAX_NAME_LENGTH];   /* pool type */
index 560c98b2ed1d9d7dc19180097da4c7bbe7654ecd..a99dbb7b4073e1917982cc1151c8a817e593ecae 100644 (file)
@@ -43,7 +43,7 @@ static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
       "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
       "SpoolData=%d  WritePartAfterJob=%d";
 static char use_device[]  = "use device=%127s media_type=%127s "
-   "pool_name=%127s pool_type=%127s append=%d";
+   "pool_name=%127s pool_type=%127s PoolId=%lld append=%d";
 static char query_device[] = "query device=%127s";
 
 
@@ -54,9 +54,12 @@ static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
 static char NOT_open[]  = "3925 Device \"%s\" could not be opened or does not exist.\n";
 static char BAD_use[]   = "3913 Bad use command: %s\n";
 static char BAD_job[]   = "3915 Bad Job command: %s\n";
-static char OK_query[]  = "3001 OK query append=%d read=%d num_writers=%d "
-   "num_waiting=%d open=%d use_count=%d labeled=%d offline=%d "
+static char OK_query[]  = "3001 OK query "
+   "append=%d read=%d num_writers=%d "
+   "open=%d labeled=%d offline=%d "
+   "reserved=%d max_writers=%d "
    "autoselect=%d autochanger=%d "
+   "poolid=%s "
    "changer_name=%s media_type=%s volume_name=%s";
 static char BAD_query[]   = "3917 Bad query command: %s\n";
 
@@ -82,13 +85,14 @@ bool job_cmd(JCR *jcr)
    /*
     * Get JobId and permissions from Director
     */
-   Dmsg1(100, "Job_cmd: %s\n", dir->msg);
+   Dmsg1(100, "<dird: %s\n", dir->msg);
    if (sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(),
              client_name.c_str(),
              &JobType, &level, fileset_name.c_str(), &no_attributes,
              &spool_attributes, fileset_md5.c_str(), &spool_data, &write_part_after_job) != 12) {
       pm_strcpy(jcr->errmsg, dir->msg);
       bnet_fsend(dir, BAD_job, jcr->errmsg);
+      Dmsg1(100, ">dird: %s\n", dir->msg);
       Emsg1(M_FATAL, 0, _("Bad Job Command from Director: %s\n"), jcr->errmsg);
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       return false;
@@ -132,7 +136,7 @@ bool job_cmd(JCR *jcr)
     */
    make_session_key(auth_key, NULL, 1);
    bnet_fsend(dir, OKjob, jcr->VolSessionId, jcr->VolSessionTime, auth_key);
-   Dmsg1(110, ">dird: %s", dir->msg);
+   Dmsg1(100, ">dird: %s", dir->msg);
    jcr->sd_auth_key = bstrdup(auth_key);
    memset(auth_key, 0, sizeof(auth_key));
    return true;
@@ -143,7 +147,6 @@ bool use_cmd(JCR *jcr)
    /*
     * Wait for the device, media, and pool information
     */
-   Dmsg1(100, "Use_cmd: %s\n", jcr->dir_bsock->msg);
    if (!use_device_cmd(jcr)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
@@ -263,17 +266,18 @@ static bool use_device_cmd(JCR *jcr)
    POOL_MEM dev_name, media_type, pool_name, pool_type;
    BSOCK *dir = jcr->dir_bsock;
    DEVRES *device;
+   uint64_t PoolId;
    AUTOCHANGER *changer;
    int append;
    bool ok;
 
-   Dmsg1(100, "Use_device_cmd: %s", jcr->dir_bsock->msg);
    /*
     * If there are multiple devices, the director sends us
     *  use_device for each device that it wants to use.
     */
+   Dmsg1(100, "<dird: %s", dir->msg);
    ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(),
-              pool_name.c_str(), pool_type.c_str(), &append) == 5;
+              pool_name.c_str(), pool_type.c_str(), &PoolId, &append) == 6;
    if (ok) {
       unbash_spaces(dev_name);
       unbash_spaces(media_type);
@@ -295,11 +299,13 @@ static bool use_device_cmd(JCR *jcr)
                   "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
                    dev_name.c_str());
               bnet_fsend(dir, NOT_open, dev_name.c_str());
+               Dmsg1(100, ">dird: %s\n", dir->msg);
               return false;
            }  
            dcr = new_dcr(jcr, device->dev);
            if (!dcr) {
                bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
+               Dmsg1(100, ">dird: %s\n", dir->msg);
               return false;
            }
             Dmsg1(100, "Found device %s\n", device->hdr.name);
@@ -307,6 +313,7 @@ static bool use_device_cmd(JCR *jcr)
            bstrncpy(dcr->pool_type, pool_type, name_len);
            bstrncpy(dcr->media_type, media_type, name_len);
            bstrncpy(dcr->dev_name, dev_name, name_len);
+           dcr->PoolId = PoolId;
            jcr->dcr = dcr;
            if (append == SD_APPEND) {
               ok = reserve_device_for_append(jcr, device->dev);
@@ -315,12 +322,15 @@ static bool use_device_cmd(JCR *jcr)
            }
            if (!ok) {
                bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str());
+               Dmsg1(100, ">dird: %s\n", dir->msg);
               free_dcr(jcr->dcr);
               return false;
            }
             Dmsg1(220, "Got: %s", dir->msg);
            bash_spaces(dev_name);
-           return bnet_fsend(dir, OK_device, dev_name.c_str());
+           ok = bnet_fsend(dir, OK_device, dev_name.c_str());
+            Dmsg1(100, ">dird: %s\n", dir->msg);
+           return ok;
         }
       }
 
@@ -348,6 +358,7 @@ static bool use_device_cmd(JCR *jcr)
               dcr = new_dcr(jcr, device->dev);
               if (!dcr) {
                   bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
+                  Dmsg1(100, ">dird: %s\n", dir->msg);
                  UnlockRes();
                  return false;
               }
@@ -371,7 +382,9 @@ static bool use_device_cmd(JCR *jcr)
               UnlockRes();
               pm_strcpy(dev_name, device->hdr.name);
               bash_spaces(dev_name);
-              return bnet_fsend(dir, OK_device, dev_name.c_str());
+              ok = bnet_fsend(dir, OK_device, dev_name.c_str());
+               Dmsg1(100, ">dird: %s\n", dir->msg);
+              return ok;
            }
            break;                    /* we found it but could not open a device */
         }
@@ -387,6 +400,7 @@ static bool use_device_cmd(JCR *jcr)
          "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
           dev_name.c_str(), media_type.c_str());
       bnet_fsend(dir, NO_device, dev_name.c_str());
+      Dmsg1(100, ">dird: %s\n", dir->msg);
    } else {
       unbash_spaces(dir->msg);
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -395,6 +409,7 @@ static bool use_device_cmd(JCR *jcr)
       }
       Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
       bnet_fsend(dir, BAD_use, jcr->errmsg);
+      Dmsg1(100, ">dird: %s\n", dir->msg);
    }
 
    return false;                     /* ERROR return */
@@ -415,10 +430,11 @@ bool query_cmd(JCR *jcr)
    DEVRES *device;
    AUTOCHANGER *changer;
    bool ok;
+   char ed1[50];
 
    Dmsg1(100, "Query_cmd: %s", dir->msg);
-
    ok = sscanf(dir->msg, query_device, dev_name.c_str()) == 1;
+   Dmsg1(100, "<dird: %s\n", dir->msg);
    if (ok) {
       unbash_spaces(dev_name);
       LockRes();
@@ -437,7 +453,7 @@ bool query_cmd(JCR *jcr)
            if (dev->is_labeled()) {
               pm_strcpy(VolumeName, dev->VolHdr.VolName);
            } else {
-               pm_strcpy(VolumeName, "");
+               pm_strcpy(VolumeName, "*");
            }
            bash_spaces(VolumeName);
            pm_strcpy(MediaType, device->media_type);
@@ -446,13 +462,19 @@ bool query_cmd(JCR *jcr)
               pm_strcpy(ChangerName, device->changer_res->hdr.name);
               bash_spaces(ChangerName);
            } else {
-               pm_strcpy(ChangerName, "");
+               pm_strcpy(ChangerName, "*");
            }
-           return bnet_fsend(dir, OK_query, dev->can_append()!=0,
-              dev->can_read()!=0, dev->num_writers, dev->num_waiting,
-              dev->is_open()!=0, dev->use_count, dev->is_labeled()!=0,
-              dev->is_offline()!=0, 0, dev->autoselect,
+           ok =bnet_fsend(dir, OK_query, 
+              dev->can_append()!=0,
+              dev->can_read()!=0, dev->num_writers, 
+              dev->is_open()!=0, dev->is_labeled()!=0,
+              dev->is_offline()!=0, dev->reserved_device, 
+              dev->is_tape()?100000:1,
+              dev->autoselect, 0, 
+              edit_uint64(dev->PoolId, ed1),
               ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str());
+            Dmsg1(100, ">dird: %s\n", dir->msg);
+           return ok;
         }
       }
       foreach_res(changer, R_AUTOCHANGER) {
@@ -460,11 +482,15 @@ bool query_cmd(JCR *jcr)
         if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
            UnlockRes();
            /* This is mostly to indicate that we are here */
-           return bnet_fsend(dir, OK_query, 0,
-              0, 0, 0, 
-              0, 0, 0, 
-               0, 1, "*",                /* Set AutoChanger = 1 */   
-               "*", "*");
+           ok = bnet_fsend(dir, OK_query, 
+              0, 0, 0,                  /* append, read, num_writers */
+              0, 0, 0,                  /* is_open, is_labeled, offline */
+              0, 0,                     /* reserved, max_writers */
+              0, 1,                     /* autoselect, AutoChanger = 1 */   
+               "0",                      /* PoolId */
+               "*", "*", "*");           /* ChangerName, MediaType, VolName */
+            Dmsg1(100, ">dird: %s\n", dir->msg);
+           return ok;
         }
       }
       /* If we get here, the device/autochanger was not found */
@@ -472,10 +498,12 @@ bool query_cmd(JCR *jcr)
       unbash_spaces(dir->msg);
       pm_strcpy(jcr->errmsg, dir->msg);
       bnet_fsend(dir, NO_device, dev_name.c_str());
+      Dmsg1(100, ">dird: %s\n", dir->msg);
    } else {
       unbash_spaces(dir->msg);
       pm_strcpy(jcr->errmsg, dir->msg);
       bnet_fsend(dir, BAD_query, jcr->errmsg);
+      Dmsg1(100, ">dird: %s\n", dir->msg);
    }
 
    return true;
index eb3e1f6eda818c5fd59d71bf1a6cdc5f97550284..c1c4f7f1179109063e83474722e98cd203acc486 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.5"
-#define BDATE   "04 March 2005"
-#define LSMDATE "04Mar05"
+#define VERSION "1.37.6"
+#define BDATE   "06 March 2005"
+#define LSMDATE "06Mar05"
 
 /* Debug flags */
 #undef  DEBUG