Imported Upstream version 3.3.1
[debian/amanda] / device-src / rait-device.c
index daeb5c8855f09c7a1b33870df25e610f453e590d..dda81fb1c9b3d9c12c0f75a1037ddc76ac287afb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
 /* The RAIT device encapsulates some number of other devices into a single
  * redundant device. */
 
-#include <amanda.h>
+#include "amanda.h"
 #include "property.h"
 #include "util.h"
 #include <glib.h>
 #include "glib-util.h"
 #include "device.h"
 #include "fileheader.h"
-#include "semaphore.h"
+#include "amsemaphore.h"
 
 /* Just a note about the failure mode of different operations:
    - Recovers from a failure (enters degraded mode)
@@ -115,7 +115,7 @@ typedef struct RaitDevicePrivate_s {
 
     /* value of this semaphore is the number of threaded operations
      * in progress */
-    semaphore_t *threads_sem;
+    amsemaphore_t *threads_sem;
 #endif
 } RaitDevicePrivate;
 
@@ -199,10 +199,6 @@ static gboolean property_get_medium_access_type_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety *surety, PropertySource *source);
 
-static gboolean property_get_free_space_fn(Device *self,
-    DevicePropertyBase *base, GValue *val,
-    PropertySurety *surety, PropertySource *source);
-
 static gboolean property_get_max_volume_usage_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety *surety, PropertySource *source);
@@ -290,7 +286,7 @@ rait_device_finalize(GObject *obj_self)
     }
 
     if (PRIVATE(self)->threads_sem)
-       semaphore_free(PRIVATE(self)->threads_sem);
+       amsemaphore_free(PRIVATE(self)->threads_sem);
 #endif
     amfree(self->private);
 }
@@ -383,16 +379,16 @@ rait_device_base_init (RaitDeviceClass * c)
            PROPERTY_ACCESS_GET_MASK,
            property_get_boolean_and_fn, NULL);
 
-    device_class_register_property(device_class, PROPERTY_MEDIUM_ACCESS_TYPE,
+    device_class_register_property(device_class, PROPERTY_LEOM,
            PROPERTY_ACCESS_GET_MASK,
-           property_get_medium_access_type_fn, NULL);
+           property_get_boolean_and_fn, NULL);
 
-    device_class_register_property(device_class, PROPERTY_FREE_SPACE,
+    device_class_register_property(device_class, PROPERTY_MEDIUM_ACCESS_TYPE,
            PROPERTY_ACCESS_GET_MASK,
-           property_get_free_space_fn, NULL);
+           property_get_medium_access_type_fn, NULL);
 
     device_class_register_property(device_class, PROPERTY_MAX_VOLUME_USAGE,
-           PROPERTY_ACCESS_GET_MASK,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            property_get_max_volume_usage_fn,
            property_set_max_volume_usage_fn);
 }
@@ -430,7 +426,7 @@ static gpointer rait_thread_pool_func(gpointer data) {
            inf->data = NULL;
 
             /* indicate that we're finished; will not block */
-           semaphore_down(inf->private->threads_sem);
+           amsemaphore_down(inf->private->threads_sem);
        }
     }
     g_mutex_unlock(inf->mutex);
@@ -441,7 +437,7 @@ static void do_thread_pool_op(RaitDevice *self, GFunc func, GPtrArray * ops) {
     guint i;
 
     if (PRIVATE(self)->threads_sem == NULL)
-       PRIVATE(self)->threads_sem = semaphore_new_with_value(0);
+       PRIVATE(self)->threads_sem = amsemaphore_new_with_value(0);
 
     if (PRIVATE(self)->threads == NULL)
        PRIVATE(self)->threads = g_array_sized_new(FALSE, TRUE,
@@ -453,7 +449,7 @@ static void do_thread_pool_op(RaitDevice *self, GFunc func, GPtrArray * ops) {
        g_array_set_size(PRIVATE(self)->threads, ops->len);
 
     /* the semaphore will hit zero when each thread has decremented it */
-    semaphore_force_set(PRIVATE(self)->threads_sem, ops->len);
+    amsemaphore_force_set(PRIVATE(self)->threads_sem, ops->len);
 
     for (i = 0; i < ops->len; i++) {
        ThreadInfo *inf = &g_array_index(PRIVATE(self)->threads, ThreadInfo, i);
@@ -473,7 +469,7 @@ static void do_thread_pool_op(RaitDevice *self, GFunc func, GPtrArray * ops) {
     }
 
     /* wait until semaphore hits zero */
-    semaphore_wait_empty(PRIVATE(self)->threads_sem);
+    amsemaphore_wait_empty(PRIVATE(self)->threads_sem);
 }
 
 #else /* USE_INTERNAL_THREADPOOL */
@@ -1138,6 +1134,7 @@ static DeviceStatusFlags rait_device_read_label(Device * dself) {
         if (first_success->volume_header != NULL) {
             dself->volume_header = dumpfile_copy(first_success->volume_header);
         }
+       dself->header_block_size = first_success->header_block_size;
     }
 
     g_ptr_array_free_full(ops);
@@ -1304,6 +1301,12 @@ rait_device_start (Device * dself, DeviceAccessMode mode, char * label,
        }
     }
 
+    if (total_status == DEVICE_STATUS_SUCCESS) {
+       StartOp * op = g_ptr_array_index(ops, 0);
+       Device *child = op->base.child;
+       dself->header_block_size = child->header_block_size;
+    }
+
     amfree(label_from_device);
     g_ptr_array_free_full(ops);
 
@@ -1313,7 +1316,6 @@ rait_device_start (Device * dself, DeviceAccessMode mode, char * label,
        device_set_error(dself, failure_errmsgs, total_status);
         return FALSE;
     }
-
     amfree(failure_errmsgs);
     return TRUE;
 }
@@ -2410,76 +2412,6 @@ property_get_medium_access_type_fn(Device *dself,
     return success;
 }
 
-static gboolean
-property_get_free_space_fn(Device *dself,
-    DevicePropertyBase *base G_GNUC_UNUSED, GValue *val,
-    PropertySurety *surety, PropertySource *source)
-{
-    RaitDevice *self = RAIT_DEVICE(dself);
-    QualifiedSize result;
-    guint i;
-    GPtrArray * ops;
-    guint data_children;
-
-    ops = make_property_op_array(self, PROPERTY_MEDIUM_ACCESS_TYPE, NULL, 0, 0);
-    do_rait_child_ops(self, property_get_do_op, ops);
-
-    /* Find the minimal available space of any child, with some funny business
-     * to deal with varying degrees of accuracy. */
-    result.accuracy = SIZE_ACCURACY_UNKNOWN;
-    result.bytes = 0;
-    for (i = 0; i < ops->len; i ++) {
-        QualifiedSize cur;
-        PropertyOp * op = g_ptr_array_index(ops, i);
-
-        if (!op->base.result || G_VALUE_TYPE(&(op->value)) != QUALIFIED_SIZE_TYPE) {
-           /* maybe this child can't tell us .. so this is just an estimate */
-           if (result.accuracy == SIZE_ACCURACY_REAL)
-               result.accuracy = SIZE_ACCURACY_ESTIMATE;
-
-           continue;
-       }
-
-        cur = *(QualifiedSize*)(g_value_get_boxed(&(op->value)));
-
-        if (result.accuracy != cur.accuracy) {
-            result.accuracy = SIZE_ACCURACY_ESTIMATE;
-        }
-
-        if (result.accuracy == SIZE_ACCURACY_UNKNOWN &&
-            cur.accuracy != SIZE_ACCURACY_UNKNOWN) {
-            result.bytes = cur.bytes;
-        } else if (result.accuracy != SIZE_ACCURACY_UNKNOWN &&
-                   cur.accuracy == SIZE_ACCURACY_UNKNOWN) {
-            /* result.bytes unchanged. */
-        } else {
-            result.bytes = MIN(result.bytes, cur.bytes);
-        }
-    }
-
-    g_ptr_array_free_full(ops);
-
-    /* result contains the minimum size available on any child.  We
-     * can use that space on each of our data children, so the total
-     * is larger */
-    find_simple_params(self, NULL, &data_children);
-    result.bytes *= data_children;
-
-    if (val) {
-       g_value_unset_init(val, QUALIFIED_SIZE_TYPE);
-       g_value_set_boxed(val, &result);
-    }
-
-    if (surety)
-       *surety = (result.accuracy == SIZE_ACCURACY_UNKNOWN)?
-                   PROPERTY_SURETY_BAD : PROPERTY_SURETY_GOOD;
-
-    if (source)
-       *source = PROPERTY_SOURCE_DETECTED;
-
-    return TRUE;
-}
-
 static gboolean
 property_get_max_volume_usage_fn(Device *dself,
     DevicePropertyBase *base G_GNUC_UNUSED, GValue *val,
@@ -2506,7 +2438,9 @@ property_get_max_volume_usage_fn(Device *dself,
 
         cur = g_value_get_uint64(&(op->value));
 
-       result = MIN(cur, result);
+       if (!result || (cur && cur < result)) {
+           result = cur;
+       }
     }
 
     g_ptr_array_free_full(ops);
@@ -2636,23 +2570,23 @@ static gboolean
 rait_device_finish (Device * self) {
     GPtrArray * ops;
     gboolean success;
+    gboolean rval = TRUE;
 
-    if (rait_device_in_error(self)) return FALSE;
+    rval = !rait_device_in_error(self);
 
     ops = make_generic_boolean_op_array(RAIT_DEVICE(self));
 
     do_rait_child_ops(RAIT_DEVICE(self), finish_do_op, ops);
 
     success = g_ptr_array_and(ops, extract_boolean_generic_op);
+    if (!success)
+       rval = FALSE;
 
     g_ptr_array_free_full(ops);
 
     self->access_mode = ACCESS_NULL;
 
-    if (!success)
-        return FALSE;
-
-    return TRUE;
+    return rval;
 }
 
 static Device *