]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement multiple drive autochanger support
authorKern Sibbald <kern@sibbald.com>
Fri, 12 Mar 2004 12:26:34 +0000 (12:26 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 12 Mar 2004 12:26:34 +0000 (12:26 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1127 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/scripts/mtx-changer.in
bacula/src/stored/acquire.c
bacula/src/stored/autochanger.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/mount.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/version.h

index 9d046ddbd2d4ca4add1208a46510c68ade4a31ee..eaa0eefd6fbd1c22c99f61ab6783deb000b5ffa8 100644 (file)
@@ -6,17 +6,17 @@
 #
 #  If you set in your Device resource
 #
-#  Changer Command = "path-to-this-script/mtx-changer" %c %o %S %a
+#  Changer Command = "path-to-this-script/mtx-changer" %c %o %S %a %d
 #    you will have the following input to this script:
 #
-#  mtx-changer "changer-device" "command" "slot" "archive-device"
+#  mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index"
 #
 #  for example:
 #
-#  mtx-changer /dev/sg0 load 1 /dev/nst0 (on a Linux system)
+#  mtx-changer /dev/sg0 load 1 /dev/nst0 (on a Linux system)
 #
-#  If you need to to an offline, refer to the drive as $4
-#    e.g.   mt -f $f offline
+#  If you need to an offline, refer to the drive as $4
+#    e.g.   mt -f $4 offline
 #
 #  Many changers need an offline after the unload. Also many
 #   changers need a sleep 60 after the mtx load.
@@ -30,16 +30,16 @@ MTX=@MTX@
 
 case "$2" in 
    unload)
-#     echo "Doing mtx -f $1 unload"
+#     echo "Doing mtx -f $1 unload $3 $5"
 #
 # enable the following line if you need to eject the cartridge
 #     mt -f $4 offline
-      ${MTX} -f $1 unload
+      ${MTX} -f $1 unload $3 $5
       ;;
 
    load)
-#     echo "Doing mtx -f $1 load $3"
-      ${MTX} -f $1 load $3
+#     echo "Doing mtx -f $1 load $3 $5"
+      ${MTX} -f $1 load $3 $5
       rtn=$?
 #
 # Increase the sleep time if you have a slow device
@@ -53,11 +53,10 @@ case "$2" in
       ;;
 
    loaded)
-#     echo "Request loaded"
       ${MTX} -f $1 status >/tmp/mtx.$$
       rtn=$?
-      cat /tmp/mtx.$$ | grep "^Data Transfer Element 0:Full" | awk "{print \$7}"
-      cat /tmp/mtx.$$ | grep "^Data Transfer Element 0:Empty" | awk "{print 0}"
+      cat /tmp/mtx.$$ | grep "^Data Transfer Element $5:Full" | awk "{print \$7}"
+      cat /tmp/mtx.$$ | grep "^Data Transfer Element $5:Empty" | awk "{print 0}"
       rm -f /tmp/mtx.$$
       exit $rtn
       ;;
index 8cafa06f253040359bde8feef5cb4d114fb37405..92434f2c3de8f8c99622b960139fb4d50fbae13d 100644 (file)
@@ -173,9 +173,12 @@ default_path:
         }
         /* Call autochanger only once unless ask_sysop called */
         if (!autochanger) {
+           int stat;
             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
               jcr->VolumeName, jcr->VolCatInfo.Slot);                         
-           if ((autochanger=autoload_device(jcr, dev, 0, NULL))) {
+           stat = autoload_device(jcr, dev, 0, NULL);
+           if (stat > 0) {
+              autochanger = 1;
               continue;
            }
         }
index 401f5c09f8bab386dd974e6dfb85526d770abfad..e464c8435388c9ed067170816848ff08e2822254 100644 (file)
@@ -31,6 +31,7 @@
 
 /* Forward referenced functions */
 static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd);
+static int get_autochanger_loaded_slot(JCR *jcr);
 
 
 /*
@@ -44,12 +45,14 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd);
  *   dir bsock.
  *
  *  Returns: 1 on success
- *          0 on failure
+ *          0 on failure (no changer available) 
+ *         -1 on error on autochanger
  */
 int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir)
 {
    int slot = jcr->VolCatInfo.Slot;
-   int rtn_stat = 0;
+   int drive = jcr->device->drive_index;
+   int rtn_stat = -1;                /* error status */
      
    /*
     * Handle autoloaders here. If we cannot autoload it, we
@@ -68,39 +71,26 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir)
    if (slot > 0 && jcr->device->changer_name && jcr->device->changer_command) {
       uint32_t timeout = jcr->device->max_changer_wait;
       POOLMEM *changer, *results;
-      int status, loaded;
+      int loaded, status;     
 
       results = get_pool_memory(PM_MESSAGE);
       changer = get_pool_memory(PM_FNAME);
 
-      /* Find out what is loaded, zero means device is unloaded */
-      Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded\" command.\n"));
-      changer = edit_device_codes(jcr, changer, jcr->device->changer_command, 
-                   "loaded");
-      status = run_program(changer, timeout, results);
-      Dmsg3(100, "run_prog: %s stat=%d result=%s\n", changer, status, results);
-      if (status == 0) {
-        loaded = atoi(results);
-        if (loaded > 0) {
-            Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded\", result is Slot %d.\n"),
-             loaded);
-        } else {
-            Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded\", result is not loaded.\n"));
-        }
-      } else {
-         Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded\" command, status=%d.\n"), status);
-        loaded = -1;              /* force unload */
-      }
+      loaded = get_autochanger_loaded_slot(jcr);
+
       Dmsg1(400, "loaded=%s\n", results);
 
-      /* If bad status or tape we want is not loaded, load it. */
-      if (status != 0 || loaded != slot) { 
+      /* If tape we want is not loaded, load it. */
+      if (loaded != slot) { 
         offline_or_rewind_dev(dev);
         /* We are going to load a new tape, so close the device */
         force_close_dev(dev);
         if (loaded != 0) {        /* must unload drive */
             Dmsg0(400, "Doing changer unload.\n");
-            Jmsg(jcr, M_INFO, 0, _("3303 Issuing autochanger \"unload\" command.\n"));
+           Jmsg(jcr, M_INFO, 0, 
+                 _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
+                loaded, drive);
+           jcr->VolCatInfo.Slot = loaded;   /* slot to be unloaded */
            changer = edit_device_codes(jcr, changer, 
                         jcr->device->changer_command, "unload");
            status = run_program(changer, timeout, NULL);
@@ -110,30 +100,72 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir)
          * Load the desired cassette    
          */
          Dmsg1(400, "Doing changer load slot %d\n", slot);
-         Jmsg(jcr, M_INFO, 0, _("3304 Issuing autochanger \"load slot %d\" command.\n"), 
-             slot);
+        Jmsg(jcr, M_INFO, 0, 
+              _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"), 
+             slot, drive);
+        jcr->VolCatInfo.Slot = slot;    /* slot to be loaded */
         changer = edit_device_codes(jcr, changer, 
                       jcr->device->changer_command, "load");
         status = run_program(changer, timeout, NULL);
         if (status == 0) {
-            Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d\", status is OK.\n"),
-                   slot);
+            Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
+                   slot, drive);
         } else {
-            Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d\", status=%d.\n"),
-                   slot, status);
+            Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\", status=%d.\n"),
+                   slot, drive, status);
         }
          Dmsg2(400, "load slot %d status=%d\n", slot, status);
+      } else { 
+        status = 0;                  /* we got what we want */
       }
       free_pool_memory(changer);
       free_pool_memory(results);
       Dmsg1(400, "After changer, status=%d\n", status);
-      if (status == 0) {          /* did we succeed? */
-        rtn_stat = 1;             /* tape loaded by changer */
+      if (status == 0) {             /* did we succeed? */
+        rtn_stat = 1;                /* tape loaded by changer */
       }
+   } else {
+      rtn_stat = 0;                  /* no changer found */
    }
    return rtn_stat;
 }
 
+static int get_autochanger_loaded_slot(JCR *jcr)
+{
+   POOLMEM *changer, *results;
+   int status, loaded;
+   uint32_t timeout = jcr->device->max_changer_wait;
+   int drive = jcr->device->drive_index;
+
+   results = get_pool_memory(PM_MESSAGE);
+   changer = get_pool_memory(PM_FNAME);
+
+   /* Find out what is loaded, zero means device is unloaded */
+   Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"),
+       drive);
+   changer = edit_device_codes(jcr, changer, jcr->device->changer_command, 
+                "loaded");
+   status = run_program(changer, timeout, results);
+   Dmsg3(000, "run_prog: %s stat=%d result=%s\n", changer, status, results);
+   if (status == 0) {
+      loaded = atoi(results);
+      if (loaded > 0) {
+         Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result is Slot %d.\n"),
+             drive, loaded);
+      } else {
+         Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result: nothing loaded.\n"),
+             drive);
+      }
+   } else {
+      Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded drive %d\" command, status=%d.\n"), 
+          drive, status);
+      loaded = -1;             /* force unload */
+   }
+   free_pool_memory(changer);
+   free_pool_memory(results);
+   return loaded;
+}
+
 /*
  * The Volume is not in the correct slot, so mark this 
  *   Volume as not being in the Changer.
@@ -159,6 +191,7 @@ int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir)
    uint32_t timeout = jcr->device->max_changer_wait;
    POOLMEM *changer;
    BPIPE *bpipe;
+   int slot, loaded;
    int len = sizeof_pool_memory(dir->msg) - 1;
 
    if (!dev_cap(dev, CAP_AUTOCHANGER) || !jcr->device->changer_name ||
@@ -173,9 +206,15 @@ int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir)
    force_close_dev(dev);
 
    /* First unload any tape */
-   bnet_fsend(dir, _("3305 Issuing autochanger \"unload\" command.\n"));
-   changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload");
-   run_program(changer, timeout, NULL);
+   loaded = get_autochanger_loaded_slot(jcr);
+   if (loaded > 0) {
+      bnet_fsend(dir, _("3305 Issuing autochanger \"unload slot %d\" command.\n"), loaded);
+      slot = jcr->VolCatInfo.Slot; 
+      jcr->VolCatInfo.Slot = loaded;
+      changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload");
+      run_program(changer, timeout, NULL);
+      jcr->VolCatInfo.Slot = slot;
+   }
 
    /* Now list slots occupied */
    changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "list");
@@ -205,6 +244,7 @@ bail_out:
  *  %% = %
  *  %a = archive device name
  *  %c = changer device name
+ *  %d = changer drive index       
  *  %f = Client's name
  *  %j = Job name
  *  %o = command
@@ -238,6 +278,10 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd)
          case 'c':
            str = NPRT(jcr->device->changer_name);
            break;
+         case 'd':
+            sprintf(add, "%d", jcr->device->dev->drive_index);
+           str = add;
+           break;
          case 'o':
            str = NPRT(cmd);
            break;
index 2a208dd709d47ec89d3e3aa682af6c0d41f45287..5ce70d864e977c8f4df19c13ddb1024762f80555 100644 (file)
@@ -148,6 +148,7 @@ init_dev(DEVICE *dev, DEVRES *device)
    dev->max_open_vols = device->max_open_vols;
    dev->vol_poll_interval = device->vol_poll_interval;
    dev->max_spool_size = device->max_spool_size;
+   dev->drive_index = device->drive_index;
    /* Sanity check */
    if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
       dev->vol_poll_interval = 60;
index f43a5bc1bbd0abd17d91f6cb326d50ccecebd1cb..580c3f6aa02d188ffdb8b13b026a1d716a4169c2 100644 (file)
@@ -176,6 +176,7 @@ public:
    int state;                         /* state mask */
    int dev_errno;                     /* Our own errno */
    int mode;                          /* read/write modes */
+   uint32_t drive_index;              /* Autochanger drive index */
    POOLMEM *dev_name;                 /* device name */
    char *errmsg;                      /* nicely edited error message */
    uint32_t block_num;                /* current block number base 0 */
index 1ec7d09b19f8cb864255d9d9861dbbd5f5d813d3..4bcc4d329cf6b81ff4fb1bb38a88a2a77245e076 100644 (file)
@@ -354,11 +354,13 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
    bsteal_lock_t hold;
    
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
+   block = new_block(dev);
    
    pm_strcpy(&jcr->VolumeName, newname);
    jcr->VolCatInfo.Slot = slot;
-   autoload_device(jcr, dev, 0, dir);     /* autoload if possible */
-   block = new_block(dev);
+   if (autoload_device(jcr, dev, 0, dir) < 0) {    /* autoload if possible */
+      goto bail_out;
+   }
 
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !(dev->state & ST_OPENED); ) {
@@ -830,11 +832,13 @@ static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
    bsteal_lock_t hold;
    
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
+   block = new_block(dev);
    
    jcr->VolumeName[0] = 0;
    jcr->VolCatInfo.Slot = Slot;
-   autoload_device(jcr, dev, 0, dir);     /* autoload if possible */
-   block = new_block(dev);
+   if (autoload_device(jcr, dev, 0, dir) < 0) {    /* autoload if possible */
+      goto bail_out;
+   }
 
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !dev_state(dev, ST_OPENED); ) {
index ad97db1dc1785cc7e523c9892e569b646d3d4931..4effbc20d170a677a260692dcbd91e75f2c6ec40 100644 (file)
@@ -109,7 +109,9 @@ mount_next_vol:
     */
    dev->state &= ~(ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
 
-   autochanger = autoload_device(jcr, dev, 1, NULL);
+   if (autoload_device(jcr, dev, 1, NULL) > 0) {
+      autochanger = true;
+   }
    Dmsg1(100, "autoload_dev returns %d\n", autochanger);
    /*
     * If we autochanged to correct Volume or (we have not just
index f29bd0a0279b1e8aee15c7c3f0104677360aacfa..ebdc1a6f63485cb37842b1ae6b6de151138e86dd 100644 (file)
@@ -117,6 +117,7 @@ static RES_ITEM dev_items[] = {
    {"spooldirectory",        store_dir,    ITEM(res_dev.spool_directory), 0, 0, 0},
    {"maximumspoolsize",      store_size,   ITEM(res_dev.max_spool_size), 0, 0, 0},
    {"maximumjobspoolsize",   store_size,   ITEM(res_dev.max_job_spool_size), 0, 0, 0},
+   {"driveindex",            store_pint,   ITEM(res_dev.drive_index), 0, 0, 0},
    {NULL, NULL, 0, 0, 0, 0} 
 };
 
@@ -133,7 +134,7 @@ RES_TABLE resources[] = {
    {"storage",       store_items, R_STORAGE,   NULL},
    {"device",        dev_items,   R_DEVICE,    NULL},
    {"messages",      msgs_items,  R_MSGS,      NULL},
-   {NULL,            NULL,        0,           NULL}
+   {NULL,           NULL,        0,           NULL}
 };
 
 
@@ -149,7 +150,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       return;
    }
    sendit(sock, "dump_resource type=%d\n", type);
-   if (type < 0) {                    /* no recursion */
+   if (type < 0) {                   /* no recursion */
       type = - type;
       recurse = 0;
    }
@@ -159,25 +160,25 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       break;
    case R_STORAGE:
       sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
-         res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
-         res->res_store.SDport, res->res_store.SDDport,
-         edit_utime(res->res_store.heartbeat_interval, buf));
+        res->res_store.hdr.name, NPRT(res->res_store.SDaddr),
+        res->res_store.SDport, res->res_store.SDDport,
+        edit_utime(res->res_store.heartbeat_interval, buf));
       break;
    case R_DEVICE:
       sendit(sock, "Device: name=%s MediaType=%s Device=%s\n",
-         res->res_dev.hdr.name,
-         res->res_dev.media_type, res->res_dev.device_name);
+        res->res_dev.hdr.name,
+        res->res_dev.media_type, res->res_dev.device_name);
       sendit(sock, "        rew_wait=%d min_bs=%d max_bs=%d\n",
-         res->res_dev.max_rewind_wait, res->res_dev.min_block_size, 
-         res->res_dev.max_block_size);
+        res->res_dev.max_rewind_wait, res->res_dev.min_block_size, 
+        res->res_dev.max_block_size);
       sendit(sock, "        max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-         res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-         res->res_dev.max_volume_size);
+        res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
+        res->res_dev.max_volume_size);
       sendit(sock, "        max_file_size=%" lld " capacity=%" lld "\n",
-         res->res_dev.max_file_size, res->res_dev.volume_capacity);
+        res->res_dev.max_file_size, res->res_dev.volume_capacity);
       sendit(sock, "         spool_directory=%s\n", res->res_dev.spool_directory);
       sendit(sock, "         max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-         res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
+        res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
       strcpy(buf, "        ");
       if (res->res_dev.cap_bits & CAP_EOF) {
          bstrncat(buf, "CAP_EOF ", sizeof(buf));
@@ -260,60 +261,60 @@ void free_resource(RES *sres, int type)
 
    switch (type) {
       case R_DIRECTOR:
-         if (res->res_dir.password) {
-            free(res->res_dir.password);
-         }
-         if (res->res_dir.address) {
-            free(res->res_dir.address);
-         }
-         break;
+        if (res->res_dir.password) {
+           free(res->res_dir.password);
+        }
+        if (res->res_dir.address) {
+           free(res->res_dir.address);
+        }
+        break;
       case R_STORAGE:
-         if (res->res_store.address) {  /* ***FIXME*** deprecated */
-            free(res->res_store.address);
-         }
-         if (res->res_store.SDaddr) {
-            free(res->res_store.SDaddr);
-         }
-         if (res->res_store.working_directory) {
-            free(res->res_store.working_directory);
-         }
-         if (res->res_store.pid_directory) {
-            free(res->res_store.pid_directory);
-         }
-         if (res->res_store.subsys_directory) {
-            free(res->res_store.subsys_directory);
-         }
-         break;
+        if (res->res_store.address) {  /* ***FIXME*** deprecated */
+           free(res->res_store.address);
+        }
+        if (res->res_store.SDaddr) {
+           free(res->res_store.SDaddr);
+        }
+        if (res->res_store.working_directory) {
+           free(res->res_store.working_directory);
+        }
+        if (res->res_store.pid_directory) {
+           free(res->res_store.pid_directory);
+        }
+        if (res->res_store.subsys_directory) {
+           free(res->res_store.subsys_directory);
+        }
+        break;
       case R_DEVICE:
-         if (res->res_dev.media_type) {
-            free(res->res_dev.media_type);
-         }
-         if (res->res_dev.device_name) {
-            free(res->res_dev.device_name);
-         }
-         if (res->res_dev.changer_name) {
-            free(res->res_dev.changer_name);
-         }
-         if (res->res_dev.changer_command) {
-            free(res->res_dev.changer_command);
-         }
-         if (res->res_dev.spool_directory) {
-            free(res->res_dev.spool_directory);
-         }
-         break;
+        if (res->res_dev.media_type) {
+           free(res->res_dev.media_type);
+        }
+        if (res->res_dev.device_name) {
+           free(res->res_dev.device_name);
+        }
+        if (res->res_dev.changer_name) {
+           free(res->res_dev.changer_name);
+        }
+        if (res->res_dev.changer_command) {
+           free(res->res_dev.changer_command);
+        }
+        if (res->res_dev.spool_directory) {
+           free(res->res_dev.spool_directory);
+        }
+        break;
       case R_MSGS:
-         if (res->res_msgs.mail_cmd) {
-            free(res->res_msgs.mail_cmd);
-         }
-         if (res->res_msgs.operator_cmd) {
-            free(res->res_msgs.operator_cmd);
-         }
-         free_msgs_res((MSGS *)res);  /* free message resource */
-         res = NULL;
-         break;
+        if (res->res_msgs.mail_cmd) {
+           free(res->res_msgs.mail_cmd);
+        }
+        if (res->res_msgs.operator_cmd) {
+           free(res->res_msgs.operator_cmd);
+        }
+        free_msgs_res((MSGS *)res);  /* free message resource */
+        res = NULL;
+        break;
       default:
          Dmsg1(0, "Unknown resource type %d\n", type);
-         break;
+        break;
    }
    /* Common stuff again -- free the resource, recurse to next one */
    if (res) {
@@ -340,10 +341,10 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-         if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
+        if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
             Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
-              items[i].name, resources[rindex]);
-          }
+             items[i].name, resources[rindex]);
+         }
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
@@ -358,33 +359,33 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    if (pass == 2) {
       switch (type) {
-         /* Resources not containing a resource */
-         case R_DIRECTOR:
-         case R_DEVICE:
-         case R_MSGS:
-            break;
-
-         /* Resources containing a resource */
-         case R_STORAGE:
-            if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+        /* Resources not containing a resource */
+        case R_DIRECTOR:
+        case R_DEVICE:
+        case R_MSGS:
+           break;
+
+        /* Resources containing a resource */
+        case R_STORAGE:
+           if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
                Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name);
-            }
-            res->res_store.messages = res_all.res_store.messages;
-            break;
-         default:
+           }
+           res->res_store.messages = res_all.res_store.messages;
+           break;
+        default:
             printf("Unknown resource type %d\n", type);
-            error = 1;
-            break;
+           error = 1;
+           break;
       }
 
 
       if (res_all.res_dir.hdr.name) {
-         free(res_all.res_dir.hdr.name);
-         res_all.res_dir.hdr.name = NULL;
+        free(res_all.res_dir.hdr.name);
+        res_all.res_dir.hdr.name = NULL;
       }
       if (res_all.res_dir.hdr.desc) {
-         free(res_all.res_dir.hdr.desc);
-         res_all.res_dir.hdr.desc = NULL;
+        free(res_all.res_dir.hdr.desc);
+        res_all.res_dir.hdr.desc = NULL;
       }
       return;
    }
@@ -392,42 +393,42 @@ void save_resource(int type, RES_ITEM *items, int pass)
    /* The following code is only executed on pass 1 */
    switch (type) {
       case R_DIRECTOR:
-         size = sizeof(DIRRES);
-         break;
+        size = sizeof(DIRRES);
+        break;
       case R_STORAGE:
-         size = sizeof(STORES);
-         break;
+        size = sizeof(STORES);
+        break;
       case R_DEVICE:
-         size = sizeof(DEVRES);
-         break;
+        size = sizeof(DEVRES);
+        break;
       case R_MSGS:
-         size = sizeof(MSGS);   
-         break;
+        size = sizeof(MSGS);   
+        break;
       default:
          printf("Unknown resource type %d\n", type);
-         error = 1;
-         size = 1;
-         break;
+        error = 1;
+        size = 1;
+        break;
    }
    /* Common */
    if (!error) {
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!resources[rindex].res_head) {
-         resources[rindex].res_head = (RES *)res; /* store first entry */
+        resources[rindex].res_head = (RES *)res; /* store first entry */
       } else {
-         RES *next;
-         /* Add new res to end of chain */
-         for (next=resources[rindex].res_head; next->next; next=next->next) {
-            if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
-               Emsg2(M_ERROR_TERM, 0,
+        RES *next;
+        /* Add new res to end of chain */
+        for (next=resources[rindex].res_head; next->next; next=next->next) {
+           if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+              Emsg2(M_ERROR_TERM, 0,
                   _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
-                  resources[rindex].name, res->res_dir.hdr.name);
-            }
-         }
-         next->next = (RES *)res;
+                 resources[rindex].name, res->res_dir.hdr.name);
+           }
+        }
+        next->next = (RES *)res;
          Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
-               res->res_dir.hdr.name);
+              res->res_dir.hdr.name);
       }
    }
 }
index 56e3aa60f39a472fb54725c016ac6bf51dd20842..16f793e97a053ca159904276a2166f43d01af231 100644 (file)
@@ -29,7 +29,7 @@ enum {
    R_DEVICE,
    R_MSGS,
    R_FIRST = R_DIRECTOR,
-   R_LAST  = R_MSGS                   /* keep this updated */
+   R_LAST  = R_MSGS                  /* keep this updated */
 };
 
 enum {
@@ -42,58 +42,59 @@ enum {
 
 /* Definition of the contents of each Resource */
 struct DIRRES {
-   RES   hdr;
+   RES  hdr;
 
-   char *password;                    /* Director password */
-   char *address;                     /* Director IP address or zero */
-   int enable_ssl;                    /* Use SSL with this Director */
+   char *password;                   /* Director password */
+   char *address;                    /* Director IP address or zero */
+   int enable_ssl;                   /* Use SSL with this Director */
 };
 
 
 /* Storage daemon "global" definitions */
 struct s_res_store {
-   RES   hdr;
+   RES  hdr;
 
-   char *address;                     /* deprecated */
-   char *SDaddr;                      /* bind address */
-   int   SDport;                      /* Where we listen for Directors */
+   char *address;                    /* deprecated */
+   char *SDaddr;                     /* bind address */
+   int  SDport;                      /* Where we listen for Directors */
    int   SDDport;                     /* "Data" port where we listen for File daemons */
-   char *working_directory;           /* working directory for checkpoints */
+   char *working_directory;          /* working directory for checkpoints */
    char *pid_directory;
    char *subsys_directory;
-   int require_ssl;                   /* Require SSL on all connections */
+   int require_ssl;                  /* Require SSL on all connections */
    uint32_t max_concurrent_jobs;      /* maximum concurrent jobs to run */
-   MSGS *messages;                    /* Daemon message handler */
-   utime_t heartbeat_interval;        /* Interval to send hb to FD */
+   MSGS *messages;                   /* Daemon message handler */
+   utime_t heartbeat_interval;       /* Interval to send hb to FD */
 };
 typedef struct s_res_store STORES;
 
 /* Device specific definitions */
 struct DEVRES {
-   RES   hdr;
+   RES  hdr;
 
-   char *media_type;                  /* User assigned media type */
-   char *device_name;                 /* Archive device name */
-   char *changer_name;                /* Changer device name */
-   char *changer_command;             /* Changer command  -- external program */
-   char *spool_directory;             /* Spool file directory */
-   uint32_t cap_bits;                 /* Capabilities of this device */
-   uint32_t max_changer_wait;         /* Changer timeout */
-   uint32_t max_rewind_wait;          /* maximum secs to wait for rewind */
-   uint32_t max_open_wait;            /* maximum secs to wait for open */
-   uint32_t max_open_vols;            /* maximum simultaneous open volumes */
-   uint32_t min_block_size;           /* min block size */
-   uint32_t max_block_size;           /* max block size */
-   uint32_t max_volume_jobs;          /* max jobs to put on one volume */
+   char *media_type;                 /* User assigned media type */
+   char *device_name;                /* Archive device name */
+   char *changer_name;               /* Changer device name */
+   char *changer_command;            /* Changer command  -- external program */
+   char *spool_directory;            /* Spool file directory */
+   uint32_t drive_index;             /* Autochanger drive index */
+   uint32_t cap_bits;                /* Capabilities of this device */
+   uint32_t max_changer_wait;        /* Changer timeout */
+   uint32_t max_rewind_wait;         /* maximum secs to wait for rewind */
+   uint32_t max_open_wait;           /* maximum secs to wait for open */
+   uint32_t max_open_vols;           /* maximum simultaneous open volumes */
+   uint32_t min_block_size;          /* min block size */
+   uint32_t max_block_size;          /* max block size */
+   uint32_t max_volume_jobs;         /* max jobs to put on one volume */
    uint32_t max_network_buffer_size;  /* max network buf size */
-   utime_t  vol_poll_interval;        /* interval between polling volume during mount */
-   int64_t max_volume_files;          /* max files to put on one volume */
-   int64_t max_volume_size;           /* max bytes to put on one volume */
-   int64_t max_file_size;             /* max file size in bytes */
-   int64_t volume_capacity;           /* advisory capacity */
-   int64_t max_spool_size;            /* Max spool size for all jobs */
-   int64_t max_job_spool_size;        /* Max spool size for any single job */
-   DEVICE *dev;                       /* Pointer to phyical dev -- set at runtime */
+   utime_t  vol_poll_interval;       /* interval between polling volume during mount */
+   int64_t max_volume_files;         /* max files to put on one volume */
+   int64_t max_volume_size;          /* max bytes to put on one volume */
+   int64_t max_file_size;            /* max file size in bytes */
+   int64_t volume_capacity;          /* advisory capacity */
+   int64_t max_spool_size;           /* Max spool size for all jobs */
+   int64_t max_job_spool_size;       /* Max spool size for any single job */
+   DEVICE *dev;                      /* Pointer to phyical dev -- set at runtime */
 };
 
 union URES {
@@ -101,5 +102,5 @@ union URES {
    STORES res_store;
    DEVRES res_dev;
    MSGS   res_msgs;
-   RES    hdr;
+   RES   hdr;
 };
index 8a57e22b5a12670a7a9ec4a8d3e53f692d731d56..9011df864823e191017d670b0c99ccc53d10cc6c 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33.4"
 #define VSTRING "1"
-#define BDATE   "10 Mar 2004"
-#define LSMDATE "10Mar04"
+#define BDATE   "12 Mar 2004"
+#define LSMDATE "12Mar04"
 
 /* Debug flags */
 #undef  DEBUG