X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=perl%2FAmanda%2FDevice.swg;h=ea46300c9e3bc310df71bb46e402bcbe873c81bf;hb=949b8910a5e23c4285d0b1aedacfc82a14dc97a5;hp=f044bfdcb84cc49db3dc6ca6b43f07c84eb0dad7;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/perl/Amanda/Device.swg b/perl/Amanda/Device.swg index f044bfd..ea46300 100644 --- a/perl/Amanda/Device.swg +++ b/perl/Amanda/Device.swg @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved. + * Copyright (c) 2007-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 @@ -30,6 +30,9 @@ #include "property.h" #include "fileheader.h" #include "glib-util.h" +#include "simpleprng.h" +#include "amanda.h" +#include "sockaddr-util.h" %} %init %{ @@ -65,30 +68,6 @@ set_sv_from_gvalue(GValue *value) case G_TYPE_UINT64: return sv_2mortal(amglue_newSVu64(g_value_get_uint64(value))); - - case G_TYPE_BOXED: { - GType boxed_type = G_VALUE_TYPE(value); - QualifiedSize qs; - HV *hv; - - if (boxed_type == QUALIFIED_SIZE_TYPE) { - qs = *(QualifiedSize*)(g_value_get_boxed(value)); - - /* build a hash */ - hv = (HV *)sv_2mortal((SV *)newHV()); - hv_store(hv, "accuracy", 8, newSViv(qs.accuracy), 0); - hv_store(hv, "bytes", 5, amglue_newSVi64(qs.bytes), 0); - - sv = newRV((SV *)hv); - return newRV((SV *)hv); - } else { - warn("Unsupported boxed property type #%d", (int)boxed_type); - - sv = sv_newmortal(); - sv_setsv(sv, &PL_sv_undef); - return sv; - } - } } /* simple types that can be constructed with sv_set*v */ @@ -255,29 +234,6 @@ typedef struct DirectTCPConnection { * Device struct, %extend-ed into a Perl class */ -typedef struct queue_fd_t { - /* Instance variables -- all readonly */ - %immutable; - int fd; - char *errmsg; - - %mutable; - - /* methods */ - %extend { - /* constructor */ - queue_fd_t(int fd) { - return queue_fd_new(fd, NULL); - } - - /* destructor */ - ~queue_fd_t() { - amfree(self->errmsg); - g_free(self); - } - } -} queue_fd_t; - %name(unaliased_name) extern char *device_unaliased_name(char *); typedef struct Device { @@ -328,6 +284,16 @@ typedef struct Device { return device_finish(self); } + guint64 + get_bytes_read() { + return device_get_bytes_read(self); + } + + guint64 + get_bytes_written() { + return device_get_bytes_written(self); + } + gboolean start_file(dumpfile_t *jobInfo) { return device_start_file(self, jobInfo); @@ -338,11 +304,6 @@ typedef struct Device { return device_write_block(self, size, data); } - gboolean - write_from_fd(queue_fd_t *queue_fd) { - return device_write_from_fd(self, queue_fd); - } - gboolean finish_file() { return device_finish_file(self); @@ -363,10 +324,6 @@ typedef struct Device { return device_read_block(self, buffer, size); } - gboolean read_to_fd(queue_fd_t *queue_fd) { - return device_read_to_fd(self, queue_fd); - } - gboolean erase() { return device_erase(self); @@ -404,6 +361,53 @@ typedef struct Device { return conn; } + %newobject accept_with_cond; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + accept_with_cond(GMutex *abort_mutex, GCond *abort_cond) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_accept_with_cond(self, &conn, abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + + %newobject connect; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + connect(gboolean for_writing, DirectTCPAddr *addrs) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_connect(self, for_writing, addrs, &conn, NULL, NULL); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + + %newobject connect_with_cond; /* connection is already ref'd, so we own it */ + DirectTCPConnection * + connect_with_cond(gboolean for_writing, DirectTCPAddr *addrs, + GMutex *abort_mutex, GCond *abort_cond) { + DirectTCPConnection *conn = NULL; + gboolean rv; + + rv = device_connect_with_cond(self, for_writing, addrs, &conn, + abort_mutex, abort_cond); + if (!rv && conn) { + /* conn is ref'd for our convenience, but we don't want it */ + g_object_unref(conn); + conn = NULL; + } + return conn; + } + gboolean use_connection(DirectTCPConnection *conn) { return device_use_connection(self, conn); @@ -467,10 +471,10 @@ typedef struct Device { if (SvPOK($input)) pname = SvPV_nolen($input); - if (pname) $1 = (DevicePropertyBase *)device_property_get_by_name(pname); - if (!pname || !$1) { - SWIG_exception_fail(SWIG_ValueError, "Invalid property name"); - } + if (pname) + $1 = (DevicePropertyBase *)device_property_get_by_name(pname); + else + $1 = NULL; } /* A typemap to convert the GValue in property_get to a return value. The @@ -516,7 +520,11 @@ typedef struct Device { void property_get(DevicePropertyBase *pbase, GValue *out_val, PropertySurety *surety, PropertySource *source, gboolean *val_found) { - *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source); + if (pbase) { + *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source); + } else { + *val_found = FALSE; + } } /* delete typemaps */ @@ -531,18 +539,22 @@ typedef struct Device { gboolean property_set(DevicePropertyBase *pbase, SV *sv) { GValue gval; + + if (!pbase) + goto fail; memset(&gval, 0, sizeof(gval)); g_value_init(&gval, pbase->type); if (!set_gvalue_from_sv(sv, &gval)) - goto fail; + goto failunset; if (!device_property_set(self, pbase->ID, &gval)) - goto fail; + goto failunset; g_value_unset(&gval); return TRUE; - fail: + failunset: g_value_unset(&gval); + fail: return FALSE; } @@ -584,6 +596,7 @@ typedef struct Device { gsize min_block_size(void) { return self->min_block_size; } gsize max_block_size(void) { return self->max_block_size; } gsize block_size(void) { return self->block_size; } + gsize header_block_size(void) { return self->header_block_size; } dumpfile_t *volume_header(void) { return self->volume_header; } }; @@ -626,6 +639,86 @@ sub new_rait_from_children { } %} +/* + * Utilities for installchecks (not described in POD) + */ + +%inline %{ + +/* write LENGTH bytes of random data to FILENAME, seeded with SEED */ +gboolean +write_random_to_device(guint32 seed, size_t length, Device *device) { + simpleprng_state_t prng; + char *buf; + gsize block_size = device->block_size; + g_assert(block_size < G_MAXUINT); + + buf = g_malloc(block_size); + simpleprng_seed(&prng, seed); + + while (length) { + size_t to_write = min(block_size, length); + + simpleprng_fill_buffer(&prng, buf, to_write); + if (!device_write_block(device, (guint)block_size, buf)) { + g_free(buf); + return FALSE; + } + length -= to_write; + } + + g_free(buf); + return TRUE; +} + +/* read LENGTH bytes of random data from FILENAME verifying it against + * a PRNG seeded with SEED. Sends any error messages to stderr. + */ +gboolean +verify_random_from_device(guint32 seed, size_t length, Device *device) { + simpleprng_state_t prng; + char *buf = NULL; /* first device_read_block will get the size */ + int block_size = 0; + + simpleprng_seed(&prng, seed); + + while (length) { + int bytes_read; + int size = block_size; + + bytes_read = device_read_block(device, buf, &size); + if (bytes_read == 0 && size > block_size) { + g_free(buf); + block_size = size; + buf = g_malloc(block_size); + continue; + } + if (bytes_read == -1) { + if (device->status == DEVICE_STATUS_SUCCESS) { + g_assert(device->is_eof); + g_debug("verify_random_from_device got unexpected EOF"); + } + goto error; + } + + /* strip padding */ + bytes_read = min(bytes_read, length); + + if (!simpleprng_verify_buffer(&prng, buf, bytes_read)) + goto error; + + length -= bytes_read; + } + + g_free(buf); + return TRUE; + +error: + g_free(buf); + return FALSE; +} +%} + /* * Constants */ @@ -706,12 +799,6 @@ amglue_add_constant_short(MEDIA_ACCESS_MODE_READ_WRITE, "READ_WRITE", MediaAcces amglue_add_constant_short(MEDIA_ACCESS_MODE_WRITE_ONLY, "WRITE_ONLY", MediaAccessMode); amglue_copy_to_tag(MediaAccessMode, constants); -amglue_add_enum_tag_fns(SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_UNKNOWN, "UNKNOWN", SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_ESTIMATE, "ESTIMATE", SizeAccuracy); -amglue_add_constant_short(SIZE_ACCURACY_REAL, "REAL", SizeAccuracy); -amglue_copy_to_tag(SizeAccuracy, constants); - amglue_add_flag_tag_fns(PropertySurety); amglue_add_constant_short(PROPERTY_SURETY_BAD, "SURETY_BAD", PropertySurety); amglue_add_constant_short(PROPERTY_SURETY_GOOD, "SURETY_GOOD", PropertySurety);