X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device-src%2Fs3-device.c;fp=device-src%2Fs3-device.c;h=fe95ccc103f85b4eab567845836b3686f4b7f34a;hb=d28952249e392eb31bc8eecc53f6c477f30c617b;hp=8c545c33f5ddb22d6bf216a1d08008af61a37d08;hpb=949b8910a5e23c4285d0b1aedacfc82a14dc97a5;p=debian%2Famanda diff --git a/device-src/s3-device.c b/device-src/s3-device.c index 8c545c3..fe95ccc 100644 --- a/device-src/s3-device.c +++ b/device-src/s3-device.c @@ -1,9 +1,10 @@ /* * Copyright (c) 2008-2012 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 - * by the Free Software Foundation. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -165,6 +166,10 @@ struct _S3Device { char *project_id; gboolean reuse_connection; + + /* CAStor */ + char *reps; + char *reps_bucket; }; /* @@ -311,6 +316,14 @@ static DevicePropertyBase device_property_project_id; static DevicePropertyBase device_property_create_bucket; #define PROPERTY_CREATE_BUCKET (device_property_create_bucket.ID) +/* CAStor replication values for objects and buckets */ +static DevicePropertyBase device_property_s3_reps; +#define PROPERTY_S3_REPS (device_property_s3_reps.ID) +#define S3_DEVICE_REPS_DEFAULT "2" +static DevicePropertyBase device_property_s3_reps_bucket; +#define PROPERTY_S3_REPS_BUCKET (device_property_s3_reps_bucket.ID) +#define S3_DEVICE_REPS_BUCKET_DEFAULT "4" + /* * prototypes */ @@ -559,6 +572,14 @@ static gboolean s3_device_set_project_id_fn(Device *p_self, DevicePropertyBase *base, GValue *val, PropertySurety surety, PropertySource source); +static gboolean s3_device_set_reps_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + +static gboolean s3_device_set_reps_bucket_fn(Device *self, + DevicePropertyBase *base, GValue *val, + PropertySurety surety, PropertySource source); + static void s3_thread_read_block(gpointer thread_data, gpointer data); static void s3_thread_write_block(gpointer thread_data, @@ -1135,6 +1156,12 @@ s3_device_register(void) device_property_fill_and_register(&device_property_s3_multi_delete, G_TYPE_BOOLEAN, "s3_multi_delete", "Whether to use multi-delete"); + device_property_fill_and_register(&device_property_s3_reps, + G_TYPE_STRING, "reps", + "Number of replicas for data objects in CAStor"); + device_property_fill_and_register(&device_property_s3_reps_bucket, + G_TYPE_STRING, "reps_bucket", + "Number of replicas for automatically created buckets in CAStor"); /* register the device itself */ register_device(s3_device_factory, device_prefix_list); @@ -1187,6 +1214,8 @@ s3_device_init(S3Device * self) self->thread_idle_cond = NULL; self->thread_idle_mutex = NULL; self->use_s3_multi_delete = 1; + self->reps = NULL; + self->reps_bucket = NULL; /* Register property values * Note: Some aren't added until s3_device_open_device() @@ -1464,6 +1493,16 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED) PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, device_simple_property_get_fn, s3_device_set_project_id_fn); + + device_class_register_property(device_class, PROPERTY_S3_REPS, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_reps_fn); + + device_class_register_property(device_class, PROPERTY_S3_REPS_BUCKET, + PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START, + device_simple_property_get_fn, + s3_device_set_reps_bucket_fn); } static gboolean @@ -1755,6 +1794,27 @@ s3_device_set_storage_api(Device *p_self, DevicePropertyBase *base, self->s3_api = S3_API_SWIFT_2; } else if (g_str_equal(storage_api, "OAUTH2")) { self->s3_api = S3_API_OAUTH2; + } else if (g_str_equal(storage_api, "CASTOR")) { +#if LIBCURL_VERSION_NUM >= 0x071301 + curl_version_info_data *info; + /* check the runtime version too */ + info = curl_version_info(CURLVERSION_NOW); + if (info->version_num >= 0x071301) { + self->s3_api = S3_API_CASTOR; + } else { + device_set_error(p_self, g_strdup_printf(_( + "Error setting STORAGE-API to castor " + "(You must install libcurl 7.19.1 or newer)")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; + } +#else + device_set_error(p_self, g_strdup_printf(_( + "Error setting STORAGE-API to castor " + "This amanda is compiled with a too old libcurl, you must compile with libcurl 7.19.1 or newer")), + DEVICE_STATUS_DEVICE_ERROR); + return FALSE; +#endif } else { g_debug("Invalid STORAGE_API, using \"S3\"."); self->s3_api = S3_API_S3; @@ -2016,6 +2076,32 @@ s3_device_set_project_id_fn(Device *p_self, return device_simple_property_set_fn(p_self, base, val, surety, source); } +static gboolean +s3_device_set_reps_fn(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->reps); + self->reps = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + +static gboolean +s3_device_set_reps_bucket_fn(Device *p_self, DevicePropertyBase *base, + GValue *val, PropertySurety surety, PropertySource source) +{ + S3Device *self = S3_DEVICE(p_self); + + amfree(self->reps_bucket); + self->reps_bucket = g_value_dup_string(val); + device_clear_volume_details(p_self); + + return device_simple_property_set_fn(p_self, base, val, surety, source); +} + static Device* s3_device_factory(char * device_name, char * device_type, char * device_node) { @@ -2063,6 +2149,14 @@ s3_device_open_device(Device *pself, char *device_name, return; } + if (self->reps == NULL) { + self->reps = g_strdup(S3_DEVICE_REPS_DEFAULT); + } + + if (self->reps_bucket == NULL) { + self->reps_bucket = g_strdup(S3_DEVICE_REPS_BUCKET_DEFAULT); + } + g_debug(_("S3 driver using bucket '%s', prefix '%s'"), self->bucket, self->prefix); /* default values */ @@ -2151,6 +2245,8 @@ static void s3_device_finalize(GObject * obj_self) { if(self->server_side_encryption) g_free(self->server_side_encryption); if(self->proxy) g_free(self->proxy); if(self->ca_info) g_free(self->ca_info); + if(self->reps) g_free(self->reps); + if(self->reps_bucket) g_free(self->reps_bucket); } static gboolean setup_handle(S3Device * self) { @@ -2229,7 +2325,14 @@ static gboolean setup_handle(S3Device * self) { DEVICE_STATUS_DEVICE_ERROR); return FALSE; } - } + } else if (self->s3_api == S3_API_CASTOR) { + self->use_s3_multi_delete = 0; + self->use_subdomain = FALSE; + if(self->service_path) { + g_free(self->service_path); + self->service_path = NULL; + } + } self->s3t = g_new0(S3_by_thread, self->nb_threads); if (self->s3t == NULL) { @@ -2269,7 +2372,8 @@ static gboolean setup_handle(S3Device * self) { self->client_id, self->client_secret, self->refresh_token, - self->reuse_connection); + self->reuse_connection, + self->reps, self->reps_bucket); if (self->s3t[thread].s3 == NULL) { device_set_error(d_self, stralloc(_("Internal error creating S3 handle")),