]> git.sur5r.net Git - bacula/bacula/commitdiff
- Implement autochanger drives protocol so that Dir knows
authorKern Sibbald <kern@sibbald.com>
Sat, 12 Nov 2005 17:31:19 +0000 (17:31 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 12 Nov 2005 17:31:19 +0000 (17:31 +0000)
  how many drives an autochanger has.
- Do not request drive number in label, ... if only one drive.
- Turn off debug code.
- Fix update slots to clear slot number of every slot before
  setting it.  This fixes (I believe) bug #471
- Make unmount unload the autochanger slot.
- Modify open() on mount to be read-only and non-blocking,
  otherwise the mount can block for a long time.
- Make a few error message numbers unique.
- Make a few error messages more correct.
- Apply patch from Thorsten to fix Win98 stat() command.

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

13 files changed:
bacula/kes-1.38
bacula/src/dird/dird_conf.h
bacula/src/dird/protos.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/filed/backup.c
bacula/src/lib/smartall.c
bacula/src/lib/smartall.h
bacula/src/stored/autochanger.c
bacula/src/stored/dircmd.c
bacula/src/stored/reserve.c
bacula/src/win32/compat/compat.cpp

index 7569459631cb28965dd524648a7477532b455d75..9ef3e1b1b48e0292086feaa6d7a2179b56aba977 100644 (file)
@@ -4,6 +4,20 @@
 General:
 
 Changes to 1.38.1:
+12Oct05
+- Implement "autochanger drives" protocol so that Dir knows
+  how many drives an autochanger has.
+- Do not request drive number in label, ... if only one drive.
+- Turn off debug code.
+- Fix update slots to clear slot number of every slot before
+  setting it.  This fixes (I believe) bug #471
+- Make unmount unload the autochanger slot.
+- Modify open() on mount to be read-only and non-blocking,      
+  otherwise the mount can block for a long time.
+- Make a few error message numbers unique.
+- Make a few error messages more correct.
+- Apply patch from Thorsten to fix Win98 stat() command.
+10Oct05
 - Remove delete of CVS from all makefiles.
 - Fix seg fault when clicking on Add button in wx-console
   restore panel.  Bug #470.
index a9291f982befd9468f52896b20139e26d38df3d3..5d2ef5befcaf8d1c8d8e7c7b3ef1bb10db55d324 100644 (file)
@@ -240,6 +240,7 @@ public:
    char *media_type;
    alist *device;                     /* Alternate devices for this Storage */
    int  autochanger;                  /* set if autochanger */
+   int  drives;                       /* number of drives in autochanger */
    uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
    uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
    int tls_enable;                    /* Enable TLS */
index 5938e0e14bc690e73088fd287994b51f06d0238f..a7aabf4ec2af5c3da24cd6672067d00e99edbdc1 100644 (file)
@@ -159,6 +159,7 @@ void parse_ua_args(UAContext *ua);
 
 /* ua_label.c */
 bool is_volume_name_legal(UAContext *ua, const char *name);
+int get_num_drives_from_SD(UAContext *ua);
 
 /* ua_output.c */
 void prtit(void *ctx, const char *msg);
index 2c90337aacc89088d51548a06875c03af0893692..127f5a52994ba524dec6ee665f0b0e774ade2e14 100644 (file)
@@ -1262,12 +1262,13 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    if (!store) {
       return;
    }
+   set_storage(jcr, store);
+
    drive = get_storage_drive(ua, store);
 
    Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
       store->media_type, store->dev_name(), drive);
 
-   set_storage(jcr, store);
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
       bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
       return;
index 00889c90acdae2044ee615f388325cbed92dcab9..88f2794a5b134674c82ec4e5af1953b980a635aa 100644 (file)
@@ -135,7 +135,7 @@ static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
    Dmsg0(100, "Slots turned on:\n");
    for (i=1; i <= num_slots; i++) {
       if (slot_list[i]) {
-         Dmsg1(000, "%d\n", i);
+         Dmsg1(100, "%d\n", i);
       }
    }
    return true;
@@ -191,7 +191,7 @@ int update_slots(UAContext *ua)
    /* Walk through the list updating the media records */
    for (vl=vol_list; vl; vl=vl->next) {
       if (vl->Slot > max_slots) {
-         bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"),
+         bsendmsg(ua, _("Slot %d greater than max %d ignored.\n"),
             vl->Slot, max_slots);
          continue;
       }
@@ -210,16 +210,16 @@ int update_slots(UAContext *ua)
          Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
       }
       slot_list[vl->Slot] = 0;        /* clear Slot */
+      memset(&mr, 0, sizeof(mr));
+      mr.Slot = vl->Slot;
+      mr.InChanger = 1;
+      mr.StorageId = store->StorageId;
+      /* Set InChanger to zero for this Slot */
+      db_lock(ua->db);
+      db_make_inchanger_unique(ua->jcr, ua->db, &mr);
+      db_unlock(ua->db);
       if (!vl->VolName) {
-         Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
-         memset(&mr, 0, sizeof(mr));
-         mr.Slot = vl->Slot;
-         mr.InChanger = 1;
-         mr.StorageId = store->StorageId;
-         /* Set InChanger to zero for this Slot */
-         db_lock(ua->db);
-         db_make_inchanger_unique(ua->jcr, ua->db, &mr);
-         db_unlock(ua->db);
+         Dmsg1(000, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
          bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
          continue;
       }
@@ -245,8 +245,8 @@ int update_slots(UAContext *ua)
          db_unlock(ua->db);
          continue;
       } else {
-         bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
-             mr.VolumeName);
+         bsendmsg(ua, _("Volume \"%s\" not found in catalog. Slot=%d set InChanger to zero.\n"),
+             mr.VolumeName, vl->Slot);
       }
       db_unlock(ua->db);
    }
@@ -878,8 +878,8 @@ static int get_num_slots_from_SD(UAContext *ua)
 
    bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
-   /* Ask for autochanger list of volumes */
-   bnet_fsend(sd, _("autochanger slots %s \n"), dev_name);
+   /* Ask for autochanger number of slots */
+   bnet_fsend(sd, _("autochanger slots %s\n"), dev_name);
 
    while (bnet_recv(sd) >= 0) {
       if (sscanf(sd->msg, "slots=%d\n", &slots) == 1) {
@@ -893,6 +893,39 @@ static int get_num_slots_from_SD(UAContext *ua)
    return slots;
 }
 
+/*
+ * We get the number of drives in the changer from the SD
+ */
+int get_num_drives_from_SD(UAContext *ua)
+{
+   STORE *store = ua->jcr->store;
+   char dev_name[MAX_NAME_LENGTH];
+   BSOCK *sd;
+   int drives = 0;
+
+
+   if (!(sd=open_sd_bsock(ua))) {
+      return 0;
+   }
+
+   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
+   bash_spaces(dev_name);
+   /* Ask for autochanger number of slots */
+   bnet_fsend(sd, _("autochanger drives %s\n"), dev_name);
+
+   while (bnet_recv(sd) >= 0) {
+      if (sscanf(sd->msg, "drives=%d\n", &drives) == 1) {
+         break;
+      } else {
+         bsendmsg(ua, "%s", sd->msg);
+      }
+   }
+   close_sd_bsock(ua);
+//   bsendmsg(ua, _("Device \"%s\" has %d drives.\n"), store->dev_name(), drives);
+   return drives;
+}
+
+
 
 
 /*
index 0e860bd68e692b718f5023926c38dc11bab8ba21..dd529eac4b3384b0b4057d9f1588f9292275b836 100644 (file)
@@ -839,6 +839,7 @@ STORE *get_storage_resource(UAContext *ua, bool use_default)
    return store;
 }
 
+/* Get drive that we are working with for this storage */
 int get_storage_drive(UAContext *ua, STORE *store)
 {
    int i, drive = -1;
@@ -847,12 +848,22 @@ int get_storage_drive(UAContext *ua, STORE *store)
    if (i >=0) {
       drive = atoi(ua->argv[i]);
    } else if (store && store->autochanger) {
-      ua->cmd[0] = 0;
-      if (!get_cmd(ua, _("Enter autochanger drive[0]: "))) {
-         drive = -1;  /* None */
-      } else {
-         drive = atoi(ua->cmd);
+      /* If our structure is not set ask SD for # drives */
+      if (store->drives == 0) {
+         store->drives = get_num_drives_from_SD(ua);
       }
+      /* If only one drive, default = 0 */
+      if (store->drives == 1) {
+         drive = 0;
+      } else {
+         /* Ask user to enter drive number */
+         ua->cmd[0] = 0;
+         if (!get_cmd(ua, _("Enter autochanger drive[0]: "))) {
+            drive = -1;  /* None */
+         } else {
+            drive = atoi(ua->cmd);
+         }
+     }
    }
    return drive;
 }
index 175634d217749d11e1001b32fd8104a0fa4c834e..cb489d6114bae9e9cd0a952a371d7d7fb409b13d 100644 (file)
@@ -96,10 +96,10 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
 
    free_pool_memory(jcr->acl_text);
 
-   bnet_sig(sd, BNET_EOD);            /* end of sending data */
-
    stop_heartbeat_monitor(jcr);
 
+   bnet_sig(sd, BNET_EOD);            /* end of sending data */
+
    if (jcr->big_buf) {
       free(jcr->big_buf);
       jcr->big_buf = NULL;
index 0f7c00fd5dfe1ba8b3de74361978398af5ac4794..32f5fac221423e3dad278754fe04edccb570118a 100644 (file)
@@ -1,40 +1,35 @@
 /*
 
-                        S M A R T A L L O C
-                       Smart Memory Allocator
+                         S M A R T A L L O C
+                        Smart Memory Allocator
 
-       Evolved   over   several  years,  starting  with  the  initial
-       SMARTALLOC code for AutoSketch in 1986, guided  by  the  Blind
-       Watchbreaker,  John  Walker.  Isolated in this general-purpose
-       form in  September  of  1989.   Updated  with  be  more  POSIX
-       compliant  and  to  include Web-friendly HTML documentation in
-       October  of  1998  by  the  same  culprit.    For   additional
-       information and the current version visit the Web page:
+        Evolved   over   several  years,  starting  with  the  initial
+        SMARTALLOC code for AutoSketch in 1986, guided  by  the  Blind
+        Watchbreaker,  John  Walker.  Isolated in this general-purpose
+        form in  September  of  1989.   Updated  with  be  more  POSIX
+        compliant  and  to  include Web-friendly HTML documentation in
+        October  of  1998  by  the  same  culprit.    For   additional
+        information and the current version visit the Web page:
 
-                 http://www.fourmilab.ch/smartall/
+                  http://www.fourmilab.ch/smartall/
 
 
-        Version $Id$
+         Version $Id$
 
 */
 
 /*
-   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
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -68,7 +63,7 @@ uint32_t sm_buffers = 0;
 
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
-extern char my_name[];               /* daemon name */
+extern char my_name[];                /* daemon name */
 
 typedef unsigned short sm_ushort;
 
@@ -80,10 +75,10 @@ typedef unsigned short sm_ushort;
 /*  Memory allocation control structures and storage.  */
 
 struct abufhead {
-   struct b_queue abq;        /* Links on allocated queue */
-   unsigned ablen;            /* Buffer length in bytes */
+   struct b_queue abq;         /* Links on allocated queue */
+   unsigned ablen;             /* Buffer length in bytes */
    const char *abfname;        /* File name pointer */
-   sm_ushort ablineno;        /* Line number of allocation */
+   sm_ushort ablineno;         /* Line number of allocation */
 };
 
 static struct b_queue abqueue = {    /* Allocated buffer queue */
@@ -91,13 +86,13 @@ static struct b_queue abqueue = {    /* Allocated buffer queue */
 };
 
 
-static bool bufimode = false;  /* Buffers not tracked when True */
+static bool bufimode = false;   /* Buffers not tracked when True */
 
 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
 
 
 /*  SMALLOC  --  Allocate buffer, enqueing on the orphaned buffer
-                tracking list.  */
+                 tracking list.  */
 
 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
 {
@@ -126,11 +121,11 @@ static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
       buf[nbytes - 1] = (((long) buf) & 0xFF) ^ 0xC5;
       buf += HEAD_SIZE;  /* Increment to user data start */
       if (++sm_buffers > sm_max_buffers) {
-        sm_max_buffers = sm_buffers;
+         sm_max_buffers = sm_buffers;
       }
       sm_bytes += nbytes;
       if (sm_bytes > sm_max_bytes) {
-        sm_max_bytes = sm_bytes;
+         sm_max_bytes = sm_bytes;
       }
       V(mutex);
    } else {
@@ -141,7 +136,7 @@ static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
 }
 
 /*  SM_NEW_OWNER -- Update the File and line number for a buffer
-                   This is to accomodate mem_pool. */
+                    This is to accomodate mem_pool. */
 
 void sm_new_owner(const char *fname, int lineno, char *buf)
 {
@@ -152,9 +147,9 @@ void sm_new_owner(const char *fname, int lineno, char *buf)
 }
 
 /*  SM_FREE  --  Update free pool availability.  FREE is never called
-                except  through  this interface or by actuallyfree().
-                free(x)  is  defined  to  generate  a  call  to  this
-                routine.  */
+                 except  through  this interface or by actuallyfree().
+                 free(x)  is  defined  to  generate  a  call  to  this
+                 routine.  */
 
 void sm_free(const char *file, int line, void *fp)
 {
@@ -171,8 +166,8 @@ void sm_free(const char *file, int line, void *fp)
 
    P(mutex);
    Dmsg4(1150, "sm_free %d at %x from %s:%d\n",
-        head->ablen, fp,
-        head->abfname, head->ablineno);
+         head->ablen, fp,
+         head->abfname, head->ablineno);
 
    /* The following assertions will catch virtually every release
       of an address which isn't an allocated buffer. */
@@ -185,9 +180,9 @@ void sm_free(const char *file, int line, void *fp)
       Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
    }
 
-   /* The following assertion detects storing off the  end  of the
+   /* The following assertion detects storing off the  end  of  the
       allocated  space in the buffer by comparing the end of buffer
-      checksum with the address of the buffer. */
+      checksum with the address of the buffer.  */
 
    if (((unsigned char *)cp)[head->ablen - 1] != ((((long) cp) & 0xFF) ^ 0xC5)) {
       V(mutex);
@@ -199,7 +194,7 @@ void sm_free(const char *file, int line, void *fp)
    qdchain(qp);
    V(mutex);
 
-   /* Now we wipe the contents of  the just-released  buffer  with
+   /* Now we wipe the contents of  the  just-released  buffer  with
       "designer  garbage"  (Duff  Kurland's  phrase) of alternating
       bits.  This is intended to ruin the day for any miscreant who
       attempts to access data through a pointer into storage that's
@@ -211,7 +206,7 @@ void sm_free(const char *file, int line, void *fp)
 }
 
 /*  SM_MALLOC  --  Allocate buffer.  NULL is returned if no memory
-                  was available.  */
+                   was available.  */
 
 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
 {
@@ -220,8 +215,8 @@ void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
    if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
 
       /* To catch sloppy code that assumes  buffers  obtained  from
-        malloc()  are  zeroed,  we  preset  the buffer contents to
-        "designer garbage" consisting of alternating bits.  */
+         malloc()  are  zeroed,  we  preset  the buffer contents to
+         "designer garbage" consisting of alternating bits.  */
 
       memset(buf, 0x55, (int) nbytes);
    } else {
@@ -233,7 +228,7 @@ void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
 /*  SM_CALLOC  --  Allocate an array and clear it to zero.  */
 
 void *sm_calloc(const char *fname, int lineno,
-               unsigned int nelem, unsigned int elsize)
+                unsigned int nelem, unsigned int elsize)
 {
    void *buf;
 
@@ -245,14 +240,14 @@ void *sm_calloc(const char *fname, int lineno,
    return buf;
 }
 
-/*  SM_REALLOC --  Adjust the size of a  previously  allocated  buffer.
-                   Note  that  the trick of "resurrecting" a previously
-                   freed buffer with realloc() is NOT supported by this
-                   function.   Further, because of the need to maintain
-                   our control storage, SM_REALLOC must always allocate
-                   a  new  block  and  copy  the data in the old block.
-                   This may result in programs which make heavy use  of
-                   realloc() running much slower than normally.  */
+/*  SM_REALLOC  --  Adjust the size of a  previously  allocated  buffer.
+                    Note  that  the trick of "resurrecting" a previously
+                    freed buffer with realloc() is NOT supported by this
+                    function.   Further, because of the need to maintain
+                    our control storage, SM_REALLOC must always allocate
+                    a  new  block  and  copy  the data in the old block.
+                    This may result in programs which make heavy use  of
+                    realloc() running much slower than normally.  */
 
 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
 {
@@ -265,7 +260,7 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
       e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
    }
 
-   /*  If  the old  block  pointer  is  NULL, treat realloc() as a
+   /*  If  the  old  block  pointer  is  NULL, treat realloc() as a
       malloc().  SVID is silent  on  this,  but  many  C  libraries
       permit this.  */
 
@@ -285,7 +280,7 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
 
    /* Sizes differ.  Allocate a new buffer of the  requested  size.
       If  we  can't  obtain  such a buffer, act as defined in SVID:
-      return NULL from realloc()  and  leave  the  buffer  in  PTR
+      return NULL from  realloc()  and  leave  the  buffer  in  PTR
       intact.  */
 
    sm_buffers--;
@@ -294,9 +289,9 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
    if ((buf = smalloc(fname, lineno, size)) != NULL) {
       memcpy(buf, ptr, (int) sm_min(size, osize));
       /* If the new buffer is larger than the old, fill the balance
-        of it with "designer garbage". */
+         of it with "designer garbage". */
       if (size > osize) {
-        memset(((char *) buf) + osize, 0x55, (int) (size - osize));
+         memset(((char *) buf) + osize, 0x55, (int) (size - osize));
       }
 
       /* All done.  Free and dechain the original buffer. */
@@ -307,20 +302,20 @@ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
    return buf;
 }
 
-/*  ACTUALLYMALLOC  -- Call the system malloc() function to obtain
-                       storage which will eventually be released
-                       by system or library routines not compiled
-                       using SMARTALLOC.  */
+/*  ACTUALLYMALLOC  --  Call the system malloc() function to obtain
+                        storage which will eventually be released
+                        by system or library routines not compiled
+                        using SMARTALLOC.  */
 
 void *actuallymalloc(unsigned int size)
 {
    return malloc(size);
 }
 
-/*  ACTUALLYCALLOC  -- Call the system calloc() function to obtain
-                       storage which will eventually be released
-                       by system or library routines not compiled
-                       using SMARTALLOC.  */
+/*  ACTUALLYCALLOC  --  Call the system calloc() function to obtain
+                        storage which will eventually be released
+                        by system or library routines not compiled
+                        using SMARTALLOC.  */
 
 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
 {
@@ -328,9 +323,9 @@ void *actuallycalloc(unsigned int nelem, unsigned int elsize)
 }
 
 /*  ACTUALLYREALLOC  --  Call the system realloc() function to obtain
-                        storage which will eventually be released
-                        by system or library routines not compiled
-                        using SMARTALLOC.  */
+                         storage which will eventually be released
+                         by system or library routines not compiled
+                         using SMARTALLOC.  */
 
 void *actuallyrealloc(void *ptr, unsigned int size)
 {
@@ -339,7 +334,7 @@ void *actuallyrealloc(void *ptr, unsigned int size)
 }
 
 /*  ACTUALLYFREE  --  Interface to system free() function to release
-                     buffers allocated by low-level routines. */
+                      buffers allocated by low-level routines. */
 
 void actuallyfree(void *cp)
 {
@@ -347,7 +342,7 @@ void actuallyfree(void *cp)
 }
 
 /*  SM_DUMP  --  Print orphaned buffers (and dump them if BUFDUMP is
- *              True).
+ *               True).
  *  N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...)
  *    as they have all been shut down at this point.
  */
@@ -362,45 +357,45 @@ void sm_dump(bool bufdump)
    while (ap != (struct abufhead *) &abqueue) {
 
       if ((ap == NULL) ||
-         (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
-         (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
-        fprintf(stderr, _(
-           "\nOrphaned buffers exist.  Dump terminated following\n"
-           "  discovery of bad links in chain of orphaned buffers.\n"
-           "  Buffer address with bad links: %lx\n"), (long) ap);
-        break;
+          (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
+          (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
+         fprintf(stderr, _(
+            "\nOrphaned buffers exist.  Dump terminated following\n"
+            "  discovery of bad links in chain of orphaned buffers.\n"
+            "  Buffer address with bad links: %lx\n"), (long) ap);
+         break;
       }
 
       if (ap->abfname != NULL) {
-        unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
-        char errmsg[500];
-
-        bsnprintf(errmsg, sizeof(errmsg),
-          _("Orphaned buffer:  %6u bytes allocated at line %d of %s %s\n"),
-           memsize, ap->ablineno, my_name, ap->abfname
-        );
-        fprintf(stderr, "%s", errmsg);
-        if (bufdump) {
-           char buf[20];
-           unsigned llen = 0;
-           char *cp = ((char *) ap) + HEAD_SIZE;
-
-           errmsg[0] = EOS;
-           while (memsize) {
-              if (llen >= 16) {
-                 bstrncat(errmsg, "\n", sizeof(errmsg));
-                 llen = 0;
-                 fprintf(stderr, "%s", errmsg);
-                 errmsg[0] = EOS;
-              }
-              bsnprintf(buf, sizeof(buf), " %02X",
-                 (*cp++) & 0xFF);
-              bstrncat(errmsg, buf, sizeof(errmsg));
-              llen++;
-              memsize--;
-           }
-           fprintf(stderr, "%s\n", errmsg);
-        }
+         unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
+         char errmsg[500];
+
+         bsnprintf(errmsg, sizeof(errmsg),
+           _("Orphaned buffer:  %6u bytes allocated at line %d of %s %s\n"),
+            memsize, ap->ablineno, my_name, ap->abfname
+         );
+         fprintf(stderr, "%s", errmsg);
+         if (bufdump) {
+            char buf[20];
+            unsigned llen = 0;
+            char *cp = ((char *) ap) + HEAD_SIZE;
+
+            errmsg[0] = EOS;
+            while (memsize) {
+               if (llen >= 16) {
+                  bstrncat(errmsg, "\n", sizeof(errmsg));
+                  llen = 0;
+                  fprintf(stderr, "%s", errmsg);
+                  errmsg[0] = EOS;
+               }
+               bsnprintf(buf, sizeof(buf), " %02X",
+                  (*cp++) & 0xFF);
+               bstrncat(errmsg, buf, sizeof(errmsg));
+               llen++;
+               memsize--;
+            }
+            fprintf(stderr, "%s\n", errmsg);
+         }
       }
       ap = (struct abufhead *) ap->abq.qnext;
    }
@@ -411,10 +406,10 @@ void sm_dump(bool bufdump)
 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
 void sm_check(const char *fname, int lineno, bool bufdump)
 {
-       if (!sm_check_rtn(fname, lineno, bufdump)) {
-          Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
-             fname, lineno);
-       }
+        if (!sm_check_rtn(fname, lineno, bufdump)) {
+           Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
+              fname, lineno);
+        }
 }
 
 #undef sm_check_rtn
@@ -429,66 +424,66 @@ int sm_check_rtn(const char *fname, int lineno, bool bufdump)
    while (ap != (struct abufhead *) &abqueue) {
       bad = 0;
       if ((ap == NULL) ||
-         (ap->abq.qnext->qprev != (struct b_queue *) ap)) {
-        bad = 0x1;
+          (ap->abq.qnext->qprev != (struct b_queue *) ap)) {
+         bad = 0x1;
       }
       if (ap->abq.qprev->qnext != (struct b_queue *) ap) {
-        bad |= 0x2;
+         bad |= 0x2;
       }
       if (((unsigned char *) ap)[((struct abufhead *) ap)->ablen - 1] !=
-          ((((long) ap) & 0xFF) ^ 0xC5)) {
-        bad |= 0x4;
+           ((((long) ap) & 0xFF) ^ 0xC5)) {
+         bad |= 0x4;
       }
       badbuf |= bad;
       if (bad) {
-        fprintf(stderr,
-           _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
-
-        if (bad & 0x1) {
-           fprintf(stderr, _("  discovery of bad prev link.\n"));
-        }
-        if (bad & 0x2) {
-           fprintf(stderr, _("  discovery of bad next link.\n"));
-        }
-        if (bad & 0x4) {
-           fprintf(stderr, _("  discovery of data overrun.\n"));
-        }
-
-        fprintf(stderr, _("  Buffer address: %lx\n"), (long) ap);
-
-        if (ap->abfname != NULL) {
-           unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
-           char errmsg[80];
-
-           fprintf(stderr,
-             _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
-              memsize, ap->ablineno, my_name, ap->abfname
-           );
-           if (bufdump) {
-              unsigned llen = 0;
-              char *cp = ((char *) ap) + HEAD_SIZE;
-
-              errmsg[0] = EOS;
-              while (memsize) {
-                 if (llen >= 16) {
-                    strcat(errmsg, "\n");
-                    llen = 0;
-                    fprintf(stderr, "%s", errmsg);
-                    errmsg[0] = EOS;
-                 }
-                 if (*cp < 0x20) {
-                    sprintf(errmsg + strlen(errmsg), " %02X",
-                       (*cp++) & 0xFF);
-                 } else {
-                    sprintf(errmsg + strlen(errmsg), " %c ",
-                       (*cp++) & 0xFF);
-                 }
-                 llen++;
-                 memsize--;
-              }
-              fprintf(stderr, "%s\n", errmsg);
-           }
-        }
+         fprintf(stderr,
+            _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
+
+         if (bad & 0x1) {
+            fprintf(stderr, _("  discovery of bad prev link.\n"));
+         }
+         if (bad & 0x2) {
+            fprintf(stderr, _("  discovery of bad next link.\n"));
+         }
+         if (bad & 0x4) {
+            fprintf(stderr, _("  discovery of data overrun.\n"));
+         }
+
+         fprintf(stderr, _("  Buffer address: %lx\n"), (long) ap);
+
+         if (ap->abfname != NULL) {
+            unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
+            char errmsg[80];
+
+            fprintf(stderr,
+              _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
+               memsize, ap->ablineno, my_name, ap->abfname
+            );
+            if (bufdump) {
+               unsigned llen = 0;
+               char *cp = ((char *) ap) + HEAD_SIZE;
+
+               errmsg[0] = EOS;
+               while (memsize) {
+                  if (llen >= 16) {
+                     strcat(errmsg, "\n");
+                     llen = 0;
+                     fprintf(stderr, "%s", errmsg);
+                     errmsg[0] = EOS;
+                  }
+                  if (*cp < 0x20) {
+                     sprintf(errmsg + strlen(errmsg), " %02X",
+                        (*cp++) & 0xFF);
+                  } else {
+                     sprintf(errmsg + strlen(errmsg), " %c ",
+                        (*cp++) & 0xFF);
+                  }
+                  llen++;
+                  memsize--;
+               }
+               fprintf(stderr, "%s\n", errmsg);
+            }
+         }
       }
       ap = (struct abufhead *) ap->abq.qnext;
    }
@@ -498,11 +493,11 @@ int sm_check_rtn(const char *fname, int lineno, bool bufdump)
 
 
 /*  SM_STATIC  --  Orphaned buffer detection can be disabled  (for  such
-                  items  as buffers allocated during initialisation) by
-                  calling   sm_static(1).    Normal   orphaned   buffer
-                  detection  can be re-enabled with sm_static(0).  Note
-                  that all the other safeguards still apply to  buffers
-                  allocated  when  sm_static(1)  mode is in effect.  */
+                   items  as buffers allocated during initialisation) by
+                   calling   sm_static(1).    Normal   orphaned   buffer
+                   detection  can be re-enabled with sm_static(0).  Note
+                   that all the other safeguards still apply to  buffers
+                   allocated  when  sm_static(1)  mode is in effect.  */
 
 void sm_static(int mode)
 {
index c646888abea80449455e91808dcef5faf4ea6e1b..429549b9d1cfac67a673e99f217c1a3decdc2ea9 100644 (file)
@@ -1,28 +1,23 @@
 /*
 
-       Definitions for the smart memory allocator
+        Definitions for the smart memory allocator
 
      Version $Id$
 
 */
 
 /*
-   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
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -37,15 +32,15 @@ extern uint32_t sm_buffers;
 
 
 extern void *sm_malloc(const char *fname, int lineno, unsigned int nbytes),
-           *sm_calloc(const char *fname, int lineno,
-               unsigned int nelem, unsigned int elsize),
-           *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size),
-           *actuallymalloc(unsigned int size),
-           *actuallycalloc(unsigned int nelem, unsigned int elsize),
-           *actuallyrealloc(void *ptr, unsigned int size);
+            *sm_calloc(const char *fname, int lineno,
+                unsigned int nelem, unsigned int elsize),
+            *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size),
+            *actuallymalloc(unsigned int size),
+            *actuallycalloc(unsigned int nelem, unsigned int elsize),
+            *actuallyrealloc(void *ptr, unsigned int size);
 extern void sm_free(const char *fname, int lineno, void *fp);
 extern void actuallyfree(void *cp),
-           sm_dump(bool bufdump), sm_static(int mode);
+            sm_dump(bool bufdump), sm_static(int mode);
 extern void sm_new_owner(const char *fname, int lineno, char *buf);
 
 #ifdef SMCHECK
@@ -142,19 +137,19 @@ class SMARTALLOC
    public:
       void *operator new(size_t s)
       {
-         return malloc(s);
+          return malloc(s);
       }
       void *operator new[](size_t s)
       {
-         return malloc(s);
+          return malloc(s);
       }
       void  operator delete(void *ptr)
       {
-         free(ptr);
+          free(ptr);
       }
       void  operator delete[](void *ptr, size_t i)
       {
-         free(ptr);
+          free(ptr);
       }
 };
 #endif
index 5da5ce5c254ab25f25784ca33e510a18f6f4a171..008cc228aa2c86ca2f122772e627f293389ba017 100644 (file)
@@ -421,12 +421,18 @@ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd)
       return false;
    }
 
-   changer = get_pool_memory(PM_FNAME);
    /* List command? */
    if (strcmp(cmd, "list") == 0) {
       unload_autochanger(dcr, -1);
    }
+   if (strcmp(cmd, "drives") == 0) {
+      AUTOCHANGER *changer_res = dcr->device->changer_res;
+      bnet_fsend(dir, "drives=%d\n", changer_res->device->size());
+      Dmsg1(100, "drives=%d\n", changer_res->device->size());
+      return true;
+   }
 
+   changer = get_pool_memory(PM_FNAME);
    lock_changer(dcr);
    /* Now issue the command */
    changer = edit_device_codes(dcr, changer, 
@@ -444,14 +450,14 @@ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd)
          Dmsg1(100, "<stored: %s\n", dir->msg);
          bnet_send(dir);
       }
-   } else {
+   } else if (strcmp(cmd, "slots") == 0 ) {
       /* For slots command, read a single line */
       bstrncpy(dir->msg, "slots=", len);
       fgets(dir->msg+6, len-6, bpipe->rfd);
       dir->msglen = strlen(dir->msg);
       Dmsg1(100, "<stored: %s", dir->msg);
       bnet_send(dir);
-   }
+   } 
                  
    stat = close_bpipe(bpipe);
    if (stat != 0) {
index 398607c3a7fe1f1d50d8a9431f5fa1b646fd2b0c..f3fa17f209227b10cf27721fdaf6fd1c1709f46f 100644 (file)
@@ -71,7 +71,7 @@ static bool setdebug_cmd(JCR *jcr);
 static bool cancel_cmd(JCR *cjcr);
 static bool mount_cmd(JCR *jcr);
 static bool unmount_cmd(JCR *jcr);
-static bool autochanger_cmd(JCR *sjcr);
+static bool changer_cmd(JCR *sjcr);
 static bool do_label(JCR *jcr, int relabel);
 static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
@@ -92,7 +92,7 @@ struct s_cmds {
  */
 static struct s_cmds cmds[] = {
    {"JobId=",      job_cmd,         0},     /* start Job */
-   {"autochanger", autochanger_cmd, 0},
+   {"autochanger", changer_cmd,     0},
    {"bootstrap",   bootstrap_cmd,   0},
    {"cancel",      cancel_cmd,      0},
    {"label",       label_cmd,       0},     /* label a tape */
@@ -353,7 +353,7 @@ static bool do_label(JCR *jcr, int relabel)
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), dev_name.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
       }
    } else {
       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
@@ -520,6 +520,7 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &devname, int drive)
                continue;
             }
             if (!device->dev->autoselect) {
+               Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
                continue;              /* device is not available */
             }
             if (drive < 0 || drive == (int)device->dev->drive_index) {
@@ -527,12 +528,15 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &devname, int drive)
                found = true;
                break;
             }
+            Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
+               devname.c_str(), drive, (int)device->dev->drive_index);
          }
          break;                    /* we found it but could not open a device */
       }
    }
 
    if (found) {
+      Dmsg1(100, "Found changer device %s\n", device->hdr.name);
       jcr->dcr = new_dcr(jcr, device->dev);
       jcr->dcr->device = device;
       return jcr->dcr->dev;
@@ -555,7 +559,7 @@ static bool mount_cmd(JCR *jcr)
    if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) {
       dev = find_device(jcr, devname, drive);
       dcr = jcr->dcr;
-      if (dev) {
+      if (dev) { 
          P(dev->mutex);               /* Use P to avoid indefinite block */
          switch (dev->dev_blocked) {         /* device blocked? */
          case BST_WAITING_FOR_SYSOP:
@@ -572,11 +576,14 @@ static bool mount_cmd(JCR *jcr)
          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
          case BST_UNMOUNTED:
             /* We freed the device, so reopen it and wake any waiting threads */
-            if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
+            dev->open_nowait = true;
+            if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
                   strerror_dev(dev));
+               dev->open_nowait = false;
                break;
             }
+            dev->open_nowait = false;
             read_dev_volume_label(dcr);
             if (dev->dev_blocked == BST_UNMOUNTED) {
                /* We blocked the device, so unblock it */
@@ -620,11 +627,14 @@ static bool mount_cmd(JCR *jcr)
                              dev->print_name());
                }
             } else if (dev->is_tape()) {
-               if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
+               dev->open_nowait = true;
+               if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
                      strerror_dev(dev));
+                  dev->open_nowait = false;
                   break;
                }
+               dev->open_nowait = false;
                read_label(dcr);
                if (dev->is_labeled()) {
                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
@@ -653,7 +663,7 @@ static bool mount_cmd(JCR *jcr)
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
    } else {
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -678,6 +688,9 @@ static bool unmount_cmd(JCR *jcr)
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
+            if (!dev->is_busy()) {
+               unload_autochanger(jcr->dcr, -1);          
+            }
             Dmsg0(90, "Device already unmounted\n");
             bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
                dev->print_name());
@@ -685,8 +698,10 @@ static bool unmount_cmd(JCR *jcr)
          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
                dev->dev_blocked);
-            offline_or_rewind_dev(dev);
-            force_close_device(dev);
+            if (!unload_autochanger(jcr->dcr, -1)) {
+               offline_or_rewind_dev(dev);
+               force_close_device(dev);
+            }
             dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
                dev->print_name());
@@ -711,14 +726,16 @@ static bool unmount_cmd(JCR *jcr)
             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
             dev->dev_blocked = BST_UNMOUNTED;
             dev->no_wait_id = 0;
-            offline_or_rewind_dev(dev);
-            force_close_device(dev);
+            if (!unload_autochanger(jcr->dcr, -1)) {
+               offline_or_rewind_dev(dev);
+               force_close_device(dev);
+            }
             bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
                dev->print_name());
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
    } else {
       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
@@ -749,18 +766,18 @@ static bool release_cmd(JCR *jcr)
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
             Dmsg0(90, "Device already released\n");
-            bnet_fsend(dir, _("3911 Device %s already released.\n"), 
+            bnet_fsend(dir, _("3921 Device %s already released.\n"), 
                dev->print_name());
 
          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
                dev->dev_blocked);
-            bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), 
+            bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"), 
                dev->print_name());
 
          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
-            bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"), 
+            bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"), 
                dev->print_name());
 
          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
@@ -772,17 +789,17 @@ static bool release_cmd(JCR *jcr)
          } else {                     /* device not being used */
             Dmsg0(90, "Device not in use, unmounting\n");
             release_volume(jcr->dcr);
-            bnet_fsend(dir, _("3012 Device %s released.\n"), 
+            bnet_fsend(dir, _("3022 Device %s released.\n"), 
                dev->print_name());
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
    } else {
       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
       pm_strcpy(jcr->errmsg, dir->msg);
-      bnet_fsend(dir, _("3917 Error scanning release command: %s\n"), jcr->errmsg);
+      bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg);
    }
    bnet_sig(dir, BNET_EOD);
    return true;
@@ -793,7 +810,7 @@ static bool release_cmd(JCR *jcr)
 /*
  * Autochanger command from Director
  */
-static bool autochanger_cmd(JCR *jcr)
+static bool changer_cmd(JCR *jcr)
 {
    POOL_MEM devname;
    BSOCK *dir = jcr->dir_bsock;
@@ -802,12 +819,15 @@ static bool autochanger_cmd(JCR *jcr)
    const char *cmd = NULL;
    bool ok = false;
 
-   if (sscanf(dir->msg, "autochanger list %127s ", devname.c_str()) == 1) {
+   if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
       cmd = "list";
       ok = true;
-   } else if (sscanf(dir->msg, "autochanger slots %127s ", devname.c_str()) == 1) {
+   } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
       cmd = "slots";
       ok = true;
+   } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
+      cmd = "drives";
+      ok = true;
    }
    if (ok) {
       dev = find_device(jcr, devname, -1);
@@ -827,11 +847,11 @@ static bool autochanger_cmd(JCR *jcr)
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
    } else {  /* error on scanf */
       pm_strcpy(jcr->errmsg, dir->msg);
-      bnet_fsend(dir, _("3908 Error scanning autocharger list/slots command: %s\n"),
+      bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
          jcr->errmsg);
    }
    bnet_sig(dir, BNET_EOD);
@@ -867,7 +887,7 @@ static bool readlabel_cmd(JCR *jcr)
          }
          V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
+         bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
       }
    } else {
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -937,11 +957,38 @@ static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
 
 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
 {
-   if (dev->can_read()) {
-       bnet_fsend(dir, _("3911 Device %s is busy reading.\n"),
+   if (dev->is_blocked()) {
+      switch (dev->dev_blocked) {
+      case BST_UNMOUNTED:
+         bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
+            dev->print_name());
+         break;
+      case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+         bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
+             dev->print_name());
+         break;
+      case BST_WAITING_FOR_SYSOP:
+         bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"),
+            dev->print_name());
+         break;
+      case BST_DOING_ACQUIRE:
+         bnet_fsend(dir, _("3934 Device %s is being initialized.\n"),
+            dev->print_name());
+         break;
+      case BST_WRITING_LABEL:
+         bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"),
+            dev->print_name());
+         break;
+      default:
+         bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"),
+            dev->print_name());
+         break;
+      }
+   } else if (dev->can_read()) {
+       bnet_fsend(dir, _("3936 Device %s is busy reading.\n"),
                    dev->print_name());;
    } else {
-       bnet_fsend(dir, _("3912 Device %s is busy with %d writer(s).\n"),
+       bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"),
           dev->print_name(), dev->num_writers);
    }
 }
index 50fef64521f2ab9a9544c34303771b6f893d70f3..ccd8527da65269ec1712d4f5b78ac8a7886c8b59 100644 (file)
@@ -788,7 +788,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
             return 1;
          } else {
             /* Changing pool, unload old tape if any in drive */
-            Dmsg0(200, "got dev: num_writers=0, reserved, pool change\n");
+            Dmsg0(200, "got dev: num_writers=0, not reserved, pool change, unload changer\n");
             unload_autochanger(dcr, 0);
          }
       }
index 14c72df9f869d860840c271c3e668421f4a5915b..4fc0e6b8743dae75b9d81ce5e132a302be49de87 100644 (file)
@@ -423,24 +423,12 @@ stat(const char *file, struct stat *sb)
 
    memset(sb, 0, sizeof(*sb));
 
-   if (g_platform_id == VER_PLATFORM_WIN32_WINDOWS) {
-      return stat2(file, sb);
-   }
-
-   // otherwise we're on NT
-#if 0
-   WCHAR buf[32767];
-   buf[0] = '\\';
-   buf[1] = '\\';
-   buf[2] = '?';
-   buf[3] = '\\';
-
-   wchar_win32_path(file, buf+4);
-
-   if (!GetFileAttributesExW((WCHAR *)buf, GetFileExInfoStandard, &data)) {
-      return stat2(file, sb);
-   }
-#else
+   /* why not allow win 95 to use p_GetFileAttributesExA ? 
+    * this function allows _some_ open files to be stat'ed 
+    * if (g_platform_id == VER_PLATFORM_WIN32_WINDOWS) {
+    *    return stat2(file, sb);
+    * }
+    */
 
    if (p_GetFileAttributesExW) {
       /* dynamically allocate enough space for UCS2 filename */
@@ -461,8 +449,6 @@ stat(const char *file, struct stat *sb)
       return stat2(file, sb);
    }
 
-#endif
-
    sb->st_mode = 0777;               /* start with everything */
    if (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
       sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);