From: Alain Spineux Date: Wed, 30 Sep 2020 13:43:57 +0000 (+0200) Subject: Allows to "clone" a device for special purpose like vacuum & aligned X-Git-Tag: Release-11.3.2~1014 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce84c818e1ce7f12bc52a69dea7c67df1105d8b9;p=thirdparty%2Fbacula.git Allows to "clone" a device for special purpose like vacuum & aligned --- diff --git a/bacula/src/stored/init_dev.c b/bacula/src/stored/init_dev.c index b48280eb3..34c14c1e7 100644 --- a/bacula/src/stored/init_dev.c +++ b/bacula/src/stored/init_dev.c @@ -103,33 +103,39 @@ void sd_list_loaded_drivers(alist *list) * thus we neither allocate it nor free it. This allows * the caller to put the packet in shared memory. * + * clone = true allows to create a clone of an existing device for special + * purpose, like the vacuum * Note, for a tape, the device->device_name is the device name * (e.g. /dev/nst0), and for a file, the device name * is the directory in which the file will be placed. * */ -DEVICE *init_dev(JCR *jcr, DEVRES *device, bool adata, bstatcollect *statcollector) +DEVICE *init_dev(JCR *jcr, DEVRES *device, bool adata, bstatcollect *statcollector, bool clone) { struct stat statp; DEVICE *dev = NULL; uint32_t n_drivers; + bool cloning = clone; /* && device->init_state=='R' */ + /* Try to avoid concurrent initialization of the same device. * The initial initialization is sequential then no worry here, but if * it failed, any later use of the device trigger a new initialization attempt * that could be concurrent with each other */ - P(mutex_dev_init); - if (device->init_state != 0) { - /* It looks like the device is already initialized or being initialized */ + if (!cloning) { + P(mutex_dev_init); + if (device->init_state) { + /* It looks like the device is already initialized or being initialized */ + V(mutex_dev_init); + /* The initialization failed, return NULL, maybe device->dev != NULL now + * but let the caller check for that and call init_dev() again if needed + */ + return NULL; + } + device->init_state = 'B'; // busy initializing V(mutex_dev_init); - /* The initialization failed, return NULL, maybe device->dev != NULL now - * but let the caller check for that and call init_dev() again if needed - */ - return NULL; } - device->init_state = 'B'; // busy initializing - V(mutex_dev_init); generate_global_plugin_event(bsdGlobalEventDeviceInit, device); Dmsg1(150, "init_dev dev_type=%d\n", device->dev_type); @@ -250,9 +256,11 @@ DEVICE *init_dev(JCR *jcr, DEVRES *device, bool adata, bstatcollect *statcollect dev->register_metrics(statcollector); - P(mutex_dev_init); - device->init_state = 'R'; // The device is ready - V(mutex_dev_init); + if (!cloning) { + P(mutex_dev_init); + device->init_state = 'R'; // The device is ready + V(mutex_dev_init); + } return dev; bailout: @@ -265,9 +273,11 @@ never_try_again: // This should never happens, no need to make a special case, just report // the problem and let it try again anyway try_again_later: - P(mutex_dev_init); - device->init_state = 0; // The initialization failed, try again later - V(mutex_dev_init); + if (!cloning) { + P(mutex_dev_init); + device->init_state = 0; // The initialization failed, try again later + V(mutex_dev_init); + } return NULL; } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 714a3145d..0d747a599 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -145,7 +145,8 @@ void display_tape_error_status(JCR *jcr, DEVICE *dev); /* From dev.c */ void sd_list_loaded_drivers(alist *list); -DEVICE *init_dev(JCR *jcr, DEVRES *device, bool adata=false, bstatcollect *statcollector=NULL); +DEVICE *init_dev(JCR *jcr, DEVRES *device, bool adata=false, + bstatcollect *statcollector=NULL, bool clone=false); bool can_open_mounted_dev(DEVICE *dev); bool load_dev(DEVICE *dev); int write_block(DEVICE *dev);