From 204efde98bb6673ebcaee513bfda09d9f0dd1e01 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 12 Mar 2004 12:26:34 +0000 Subject: [PATCH] Implement multiple drive autochanger support git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1127 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/scripts/mtx-changer.in | 23 ++-- bacula/src/stored/acquire.c | 5 +- bacula/src/stored/autochanger.c | 114 +++++++++++------ bacula/src/stored/dev.c | 1 + bacula/src/stored/dev.h | 1 + bacula/src/stored/dircmd.c | 12 +- bacula/src/stored/mount.c | 4 +- bacula/src/stored/stored_conf.c | 213 ++++++++++++++++---------------- bacula/src/stored/stored_conf.h | 73 +++++------ bacula/src/version.h | 4 +- 10 files changed, 253 insertions(+), 197 deletions(-) diff --git a/bacula/scripts/mtx-changer.in b/bacula/scripts/mtx-changer.in index 9d046ddbd2..eaa0eefd6f 100644 --- a/bacula/scripts/mtx-changer.in +++ b/bacula/scripts/mtx-changer.in @@ -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 0 (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 ;; diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 8cafa06f25..92434f2c3d 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -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; } } diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 401f5c09f8..e464c84353 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -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; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 2a208dd709..5ce70d864e 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -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; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index f43a5bc1bb..580c3f6aa0 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -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 */ diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 1ec7d09b19..4bcc4d329c 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -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); ) { diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index ad97db1dc1..4effbc20d1 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -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 diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index f29bd0a027..ebdc1a6f63 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -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); } } } diff --git a/bacula/src/stored/stored_conf.h b/bacula/src/stored/stored_conf.h index 56e3aa60f3..16f793e97a 100644 --- a/bacula/src/stored/stored_conf.h +++ b/bacula/src/stored/stored_conf.h @@ -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; }; diff --git a/bacula/src/version.h b/bacula/src/version.h index 8a57e22b5a..9011df8648 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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 -- 2.39.5