From 83a15f9cedbcb8f9e00baa7f48fd3010a1355994 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 18 Jul 2002 09:22:03 +0000 Subject: [PATCH] Add MaximumOpenWait -- kes18Jul02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@63 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/dev.c | 14 +++- bacula/src/stored/dev.h | 1 + bacula/src/stored/device.c | 2 +- bacula/src/stored/stored.c | 141 ++++++++++++++++---------------- bacula/src/stored/stored_conf.c | 3 +- bacula/src/stored/stored_conf.h | 77 ++++++++--------- 6 files changed, 126 insertions(+), 112 deletions(-) diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 286de5a63e..50d460bdad 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -202,18 +202,25 @@ open_dev(DEVICE *dev, char *VolName, int mode) dev->dev_name, dev->VolCatInfo.VolCatName); dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); if (dev->state & ST_TAPE) { + int timeout; Dmsg0(29, "open_dev: device is tape\n"); if (mode == READ_WRITE) { dev->mode = O_RDWR | O_BINARY; } else { dev->mode = O_RDONLY | O_BINARY; } - if ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) { + timeout = dev->max_open_wait; + while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) { + if (errno == EBUSY && timeout-- > 0) { + sleep(1); + continue; + } dev->dev_errno = errno; Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"), dev->dev_name, strerror(dev->dev_errno)); Emsg0(M_FATAL, 0, dev->errmsg); - } else { + } + if (dev->fd < 0) { dev->dev_errno = 0; dev->state |= ST_OPENED; dev->use_count++; @@ -221,6 +228,9 @@ open_dev(DEVICE *dev, char *VolName, int mode) } Dmsg1(29, "open_dev: tape %d opened\n", dev->fd); } else { + /* + * Handle opening of file + */ archive_name = get_pool_memory(PM_FNAME); strcpy(archive_name, dev->dev_name); if (archive_name[strlen(archive_name)] != '/') { diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 53aa0f736b..fe8ff6d49f 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -134,6 +134,7 @@ typedef struct s_device { uint64_t max_file_size; /* max file size to put in one file on volume */ uint64_t volume_capacity; /* advisory capacity */ uint32_t max_rewind_wait; /* max secs to allow for rewind */ + uint32_t max_open_wait; /* max secs to allow for open */ void *device; /* pointer to Device Resource */ VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 22cd01ca1b..ef9163425c 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -314,7 +314,7 @@ mount_next_vol: Dmsg1(100, "Want changer slot=%d\n", slot); if (slot > 0 && jcr->device->changer_name && jcr->device->changer_command) { - uint32_t timeout = jcr->device->changer_timeout; + uint32_t timeout = jcr->device->max_changer_wait; POOLMEM *changer, *results; int status, loaded; diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 4259baa282..1d4279b804 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -46,8 +46,8 @@ static void *director_thread(void *arg); /* Global variables exported */ -struct s_shm *shm; /* memory shared with children */ -BSHM bshm; /* shared memory control packet */ +struct s_shm *shm; /* memory shared with children */ +BSHM bshm; /* shared memory control packet */ /* This is our own global resource */ @@ -60,8 +60,8 @@ uint32_t VolSessionTime; static char *configfile; static int foreground = 0; -static workq_t dird_workq; /* queue for processing connections */ -static workq_t filed_workq; /* queue for processing connections */ +static workq_t dird_workq; /* queue for processing connections */ +static workq_t filed_workq; /* queue for processing connections */ static void usage() @@ -102,7 +102,7 @@ int main (int argc, char *argv[]) /* Sanity checks */ if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) { Emsg2(M_ABORT, 0, "Tape block size (%d) not multiple of system size (%d)\n", - TAPE_BSIZE, DEV_BSIZE); + TAPE_BSIZE, DEV_BSIZE); } if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) { Emsg1(M_ABORT, 0, "Tape block size (%d) is not a power of 2\n", TAPE_BSIZE); @@ -111,34 +111,34 @@ int main (int argc, char *argv[]) while ((ch = getopt(argc, argv, "c:d:fst?")) != -1) { switch (ch) { case 'c': /* configuration file */ - if (configfile != NULL) { - free(configfile); - } - configfile = bstrdup(optarg); - break; + if (configfile != NULL) { + free(configfile); + } + configfile = bstrdup(optarg); + break; case 'd': /* debug level */ - debug_level = atoi(optarg); - if (debug_level <= 0) { - debug_level = 1; - } - break; + debug_level = atoi(optarg); + if (debug_level <= 0) { + debug_level = 1; + } + break; case 'f': /* run in foreground */ - foreground = TRUE; - break; + foreground = TRUE; + break; case 's': /* no signals */ - no_signals = TRUE; - break; + no_signals = TRUE; + break; case 't': - test_config = TRUE; - break; + test_config = TRUE; + break; case '?': - default: - usage(); + default: + usage(); } } @@ -147,7 +147,7 @@ int main (int argc, char *argv[]) if (argc) { if (configfile != NULL) { - free(configfile); + free(configfile); } configfile = bstrdup(*argv); argc--; @@ -174,8 +174,8 @@ int main (int argc, char *argv[]) } if (!foreground) { - daemon_start(); /* become daemon */ - init_stack_dump(); /* pick up new pid */ + daemon_start(); /* become daemon */ + init_stack_dump(); /* pick up new pid */ } create_pid_file(me->pid_directory, "bacula-sd", me->SDport); @@ -201,23 +201,24 @@ int main (int argc, char *argv[]) LockRes(); for (device=NULL,i=0; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); i++) { if (i >= MAX_DEVICES) { - UnlockRes(); + UnlockRes(); Emsg1(M_ABORT, 0, _("Too many Device Resources. Max=%d\n"), MAX_DEVICES); } Dmsg1(90, "calling init_dev %s\n", device->device_name); device->dev = init_dev(&shm->dev[i], device->device_name); /* Copy some attributes from the Device Resource to the DEV structure */ if (device->dev) { - device->dev->capabilities = device->cap_bits; - device->dev->min_block_size = device->min_block_size; - device->dev->max_block_size = device->max_block_size; - device->dev->max_volume_jobs = device->max_volume_jobs; - device->dev->max_volume_files = device->max_volume_files; - device->dev->max_volume_size = device->max_volume_size; - device->dev->max_file_size = device->max_file_size; - device->dev->volume_capacity = device->volume_capacity; - device->dev->max_rewind_wait = device->max_rewind_wait; - device->dev->device = device; + device->dev->capabilities = device->cap_bits; + device->dev->min_block_size = device->min_block_size; + device->dev->max_block_size = device->max_block_size; + device->dev->max_volume_jobs = device->max_volume_jobs; + device->dev->max_volume_files = device->max_volume_files; + device->dev->max_volume_size = device->max_volume_size; + device->dev->max_file_size = device->max_file_size; + device->dev->volume_capacity = device->volume_capacity; + device->dev->max_rewind_wait = device->max_rewind_wait; + device->dev->max_open_wait = device->max_open_wait; + device->dev->device = device; } Dmsg1(10, "Init done %s\n", device->device_name); if (!device->dev) { @@ -225,25 +226,25 @@ int main (int argc, char *argv[]) } if (device->cap_bits & CAP_ALWAYSOPEN) { Dmsg1(20, "calling open_device %s\n", device->device_name); - if (!open_device(device->dev)) { + if (!open_device(device->dev)) { Emsg1(M_ERROR, 0, _("Could not open device %s\n"), device->device_name); - } + } } if (device->cap_bits & CAP_AUTOMOUNT && device->dev && - device->dev->state & ST_OPENED) { - DEV_BLOCK *block; - JCR *jcr; - block = new_block(device->dev); - jcr = new_jcr(sizeof(JCR), stored_free_jcr); - switch (read_dev_volume_label(jcr, device->dev, block)) { - case VOL_OK: - break; - default: + device->dev->state & ST_OPENED) { + DEV_BLOCK *block; + JCR *jcr; + block = new_block(device->dev); + jcr = new_jcr(sizeof(JCR), stored_free_jcr); + switch (read_dev_volume_label(jcr, device->dev, block)) { + case VOL_OK: + break; + default: Emsg1(M_WARNING, 0, _("Could not mount device %s\n"), device->device_name); - break; - } - free_jcr(jcr); - free_block(block); + break; + } + free_jcr(jcr); + free_block(block); } } UnlockRes(); @@ -252,7 +253,7 @@ int main (int argc, char *argv[]) set_thread_concurrency(me->max_concurrent_jobs * 2 + 4 /* watch dog + servers + misc */); - start_watchdog(); /* start watchdog thread */ + start_watchdog(); /* start watchdog thread */ /* * Here we support either listening on one port or on two ports @@ -260,11 +261,11 @@ int main (int argc, char *argv[]) if (me->SDDport == 0 || me->SDDport == me->SDport) { /* Single server used for Director and File daemon */ bnet_thread_server(me->SDport, me->max_concurrent_jobs * 2, - &dird_workq, connection_request); + &dird_workq, connection_request); } else { /* Start the Director server */ - if ((status=pthread_create(&dirid, NULL, director_thread, - (void *)me->SDport)) != 0) { + if ((status=pthread_create(&dirid, NULL, director_thread, + (void *)me->SDport)) != 0) { Emsg1(M_ABORT, 0, _("Cannot create Director thread: %s\n"), strerror(status)); } /* Start File daemon server */ @@ -272,7 +273,7 @@ int main (int argc, char *argv[]) /* never returns */ } - exit(1); /* to keep compiler quiet */ + exit(1); /* to keep compiler quiet */ } static void *director_thread(void *arg) @@ -305,49 +306,49 @@ static void check_config() if (!me) { UnlockRes(); Emsg1(M_ABORT, 0, _("No Storage resource defined in %s. Cannot continue.\n"), - configfile); + configfile); } - my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */ + my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */ if (GetNextRes(R_STORAGE, (RES *)me) != NULL) { UnlockRes(); Emsg1(M_ABORT, 0, _("Only one Storage resource permitted in %s\n"), - configfile); + configfile); } if (GetNextRes(R_DIRECTOR, NULL) == NULL) { UnlockRes(); Emsg1(M_ABORT, 0, _("No Director resource defined in %s. Cannot continue.\n"), - configfile); + configfile); } if (GetNextRes(R_DEVICE, NULL) == NULL){ UnlockRes(); Emsg1(M_ABORT, 0, _("No Device resource defined in %s. Cannot continue.\n"), - configfile); + configfile); } if (!me->messages) { me->messages = (MSGS *)GetNextRes(R_MSGS, NULL); if (!me->messages) { Emsg1(M_ABORT, 0, _("No Messages resource defined in %s. Cannot continue.\n"), - configfile); + configfile); } } - close_msg(NULL); /* close temp message handler */ + close_msg(NULL); /* close temp message handler */ init_msg(NULL, me->messages); /* open daemon message handler */ UnlockRes(); if (!me->working_directory) { Emsg1(M_ABORT, 0, _("No Working Directory defined in %s. Cannot continue.\n"), - configfile); + configfile); } if (stat(me->working_directory, &stat_buf) != 0) { Emsg1(M_ABORT, 0, _("Working Directory: %s not found. Cannot continue.\n"), - me->working_directory); + me->working_directory); } if (!S_ISDIR(stat_buf.st_mode)) { Emsg1(M_ABORT, 0, _("Working Directory: %s is not a directory. Cannot continue.\n"), - me->working_directory); + me->working_directory); } working_directory = me->working_directory; } @@ -358,7 +359,7 @@ void terminate_stored(int sig) static int in_here = FALSE; DEVRES *device; - if (in_here) { /* prevent loops */ + if (in_here) { /* prevent loops */ exit(1); } in_here = TRUE; @@ -371,7 +372,7 @@ void terminate_stored(int sig) LockRes(); for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) { if (device->dev) { - term_dev(device->dev); + term_dev(device->dev); } } UnlockRes(); @@ -390,6 +391,6 @@ void terminate_stored(int sig) free(shm); } - sm_dump(False); /* dump orphaned buffers */ + sm_dump(False); /* dump orphaned buffers */ exit(1); } diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 1e2f58117f..9a59da8a32 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -96,7 +96,8 @@ static struct res_items dev_items[] = { {"autochanger", store_yesno, ITEM(res_dev.cap_bits), CAP_AUTOCHANGER, ITEM_DEFAULT, 0}, {"changerdevice", store_strname,ITEM(res_dev.changer_name), 0, 0, 0}, {"changercommand", store_strname,ITEM(res_dev.changer_command), 0, 0, 0}, - {"changertimeout", store_pint, ITEM(res_dev.changer_timeout), 0, ITEM_DEFAULT, 60}, + {"maximumchangerwait", store_pint, ITEM(res_dev.max_changer_wait), 0, ITEM_DEFAULT, 60}, + {"maximumopenwait", store_pint, ITEM(res_dev.max_open_wait), 0, ITEM_DEFAULT, 5 * 60}, {"offlineonunmount", store_yesno, ITEM(res_dev.cap_bits), CAP_OFFLINEUNMOUNT, ITEM_DEFAULT, 1}, {"maximumrewindwait", store_pint, ITEM(res_dev.max_rewind_wait), 0, ITEM_DEFAULT, 5 * 60}, {"minimumblocksize", store_pint, ITEM(res_dev.min_block_size), 0, 0, 0}, diff --git a/bacula/src/stored/stored_conf.h b/bacula/src/stored/stored_conf.h index 8e8c9cca54..585030e9da 100644 --- a/bacula/src/stored/stored_conf.h +++ b/bacula/src/stored/stored_conf.h @@ -23,42 +23,42 @@ */ -#define R_FIRST 3001 +#define R_FIRST 3001 -#define R_DIRECTOR 3001 -#define R_STORAGE 3002 -#define R_DEVICE 3003 -#define R_MSGS 3004 +#define R_DIRECTOR 3001 +#define R_STORAGE 3002 +#define R_DEVICE 3003 +#define R_MSGS 3004 -#define R_LAST R_MSGS +#define R_LAST R_MSGS -#define R_NAME 3020 -#define R_ADDRESS 3021 -#define R_PASSWORD 3022 -#define R_TYPE 3023 -#define R_BACKUP 3024 +#define R_NAME 3020 +#define R_ADDRESS 3021 +#define R_PASSWORD 3022 +#define R_TYPE 3023 +#define R_BACKUP 3024 #define STORAGE_DAEMON 1 /* Definition of the contents of each Resource */ struct s_res_dir { - RES hdr; + RES hdr; - char *password; /* Director password */ - char *address; /* Director IP address or zero */ + char *password; /* Director password */ + char *address; /* Director IP address or zero */ }; typedef struct s_res_dir DIRRES; /* Storage daemon "global" definitions */ struct s_res_store { - RES hdr; + RES hdr; char *address; - int SDport; /* Where we listen for Directors */ + 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; uint32_t max_concurrent_jobs; /* maximum concurrent jobs to run */ @@ -68,31 +68,32 @@ typedef struct s_res_store STORES; /* Device specific definitions */ struct s_res_dev { - 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 */ - int cap_bits; /* Capabilities of this device */ - uint32_t changer_timeout; /* Changer timeout */ - uint32_t max_rewind_wait; /* maximum secs to wait for rewind */ - 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 */ - 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 */ - DEVICE *dev; /* Pointer to phyical dev -- set at runtime */ + 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 */ + int 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 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 */ + 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 */ + DEVICE *dev; /* Pointer to phyical dev -- set at runtime */ }; typedef struct s_res_dev DEVRES; union u_res { - struct s_res_dir res_dir; - struct s_res_store res_store; - struct s_res_dev res_dev; - struct s_res_msgs res_msgs; + struct s_res_dir res_dir; + struct s_res_store res_store; + struct s_res_dev res_dev; + struct s_res_msgs res_msgs; RES hdr; }; typedef union u_res URES; -- 2.39.2