]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Allows to "clone" a device for special purpose like vacuum & aligned
authorAlain Spineux <alain@baculasystems.com>
Wed, 30 Sep 2020 13:43:57 +0000 (15:43 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:02:57 +0000 (09:02 +0100)
bacula/src/stored/init_dev.c
bacula/src/stored/protos.h

index b48280eb30ddebae68158a6b08f43576210055ac..34c14c1e7c97ffa5ba6bb3c8443f4e4b4d97ad39 100644 (file)
@@ -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;
 }
 
index 714a3145ded14ae96dd1ac021cb319eb24615c69..0d747a599f02e17f872597fcef4ca5bf496361ef 100644 (file)
@@ -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);