📄 taper-disk-port-source.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 2006 Zmanda Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#define selfp (self->_priv)#include "taper-disk-port-source.h"#include "taper-mem-port-source.h"struct _TaperDiskPortSourcePrivate { gboolean retry_mode; int buffer_fd; TaperSource * fallback; gboolean disk_problem; guint64 disk_buffered_bytes; /* This is for extra data we picked up by accident. */ char * excess_buffer; size_t excess_buffer_size; guint64 retry_data_written;};/* here are local prototypes */static void taper_disk_port_source_init (TaperDiskPortSource * o);static void taper_disk_port_source_class_init (TaperDiskPortSourceClass * c);static ssize_t taper_disk_port_source_read (TaperSource * pself, void * buf, size_t count);static gboolean taper_disk_port_source_seek_to_part_start (TaperSource * pself);static void taper_disk_port_source_start_new_part (TaperSource * pself);static gboolean taper_disk_port_source_get_end_of_data(TaperSource * pself);static gboolean taper_disk_port_source_get_end_of_part(TaperSource * pself);static int taper_disk_port_source_predict_parts(TaperSource * pself);/* pointer to the class of our parent */static TaperSourceClass * source_parent_class = NULL;static TaperPortSourceClass *parent_class = NULL;GType taper_disk_port_source_get_type (void) { static GType type = 0; if G_UNLIKELY(type == 0) { static const GTypeInfo info = { sizeof (TaperDiskPortSourceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) taper_disk_port_source_class_init, (GClassFinalizeFunc) NULL, NULL /* class_data */, sizeof (TaperDiskPortSource), 0 /* n_preallocs */, (GInstanceInitFunc) taper_disk_port_source_init, NULL }; type = g_type_register_static (TAPER_TYPE_PORT_SOURCE, "TaperDiskPortSource", &info, (GTypeFlags)0); } return type;}static void taper_disk_port_source_dispose(GObject * obj_self) { TaperDiskPortSource *self = TAPER_DISK_PORT_SOURCE (obj_self); if (G_OBJECT_CLASS (parent_class)->dispose) (* G_OBJECT_CLASS (parent_class)->dispose) (obj_self); if(self->_priv->fallback) { g_object_unref (self->_priv->fallback); }}static voidtaper_disk_port_source_finalize(GObject *obj_self){ TaperDiskPortSource *self = TAPER_DISK_PORT_SOURCE (obj_self); if(G_OBJECT_CLASS(parent_class)->finalize) (* G_OBJECT_CLASS(parent_class)->finalize)(obj_self); amfree(self->buffer_dir_name); amfree(self->_priv->excess_buffer); amfree(self->_priv);}static void taper_disk_port_source_init (TaperDiskPortSource * o G_GNUC_UNUSED){ o->_priv = malloc(sizeof(TaperDiskPortSourcePrivate)); o->_priv->retry_mode = FALSE; o->_priv->buffer_fd = -1; o->_priv->fallback = NULL; o->_priv->disk_problem = FALSE; o->_priv->disk_buffered_bytes = 0; o->_priv->excess_buffer = NULL; o->_priv->excess_buffer_size = 0;}static void taper_disk_port_source_class_init (TaperDiskPortSourceClass * c G_GNUC_UNUSED){ GObjectClass *g_object_class = (GObjectClass*) c; TaperSourceClass *taper_source_class = (TaperSourceClass *)c; parent_class = g_type_class_ref (TAPER_TYPE_PORT_SOURCE); source_parent_class = (TaperSourceClass*)parent_class; taper_source_class->read = taper_disk_port_source_read; taper_source_class->seek_to_part_start = taper_disk_port_source_seek_to_part_start; taper_source_class->start_new_part = taper_disk_port_source_start_new_part; taper_source_class->get_end_of_data = taper_disk_port_source_get_end_of_data; taper_source_class->get_end_of_part = taper_disk_port_source_get_end_of_part; taper_source_class->predict_parts = taper_disk_port_source_predict_parts; g_object_class->dispose = taper_disk_port_source_dispose; g_object_class->finalize = taper_disk_port_source_finalize;}static gboolean taper_disk_port_source_get_end_of_data(TaperSource * pself) { TaperDiskPortSource * self = TAPER_DISK_PORT_SOURCE(pself); g_return_val_if_fail(self != NULL, TRUE); if (self->_priv->fallback != NULL) { return taper_source_get_end_of_data(self->_priv->fallback); } else { return (source_parent_class->get_end_of_data)(pself); }}static gboolean taper_disk_port_source_get_end_of_part(TaperSource * pself) { TaperDiskPortSource * self = TAPER_DISK_PORT_SOURCE(pself); g_return_val_if_fail(self != NULL, TRUE); if (self->_priv->fallback != NULL) { return taper_source_get_end_of_part(self->_priv->fallback); } else { return (source_parent_class->get_end_of_part)(pself); }} static int taper_disk_port_source_predict_parts(TaperSource * pself) { TaperDiskPortSource * self = TAPER_DISK_PORT_SOURCE(pself); g_return_val_if_fail(self != NULL, -1); return -1;}static TaperSource * make_fallback_source(TaperDiskPortSource * self) { TaperSource * rval; TaperPortSource * port_rval; rval = (TaperSource*) g_object_new(TAPER_TYPE_MEM_PORT_SOURCE, NULL); port_rval = (TaperPortSource*)rval; if (rval == NULL) return NULL; port_rval->socket_fd = ((TaperPortSource*)self)->socket_fd; rval->max_part_size = self->fallback_buffer_size; return rval;}/* Open the buffer file. We create the file and then immediately unlink it, to improve security and ease cleanup. */static gboolean open_buffer_file(TaperDiskPortSource * self) { int fd; char * filename; mode_t old_umask; g_return_val_if_fail(self != NULL, FALSE); g_return_val_if_fail(self->buffer_dir_name != NULL, FALSE); filename = g_strdup_printf("%s/amanda-split-buffer-XXXXXX", self->buffer_dir_name); /* This is not thread-safe. :-( */ old_umask = umask(0); fd = g_mkstemp(filename); umask(old_umask); if (fd < 0) { g_fprintf(stderr, "Couldn't open temporary file with template %s: %s\n", filename, strerror(errno)); return FALSE; } /* If it fails, that's annoying, but no great loss. */ if (unlink(filename) != 0) { g_fprintf(stderr, "Unlinking %s failed: %s\n", filename, strerror(errno)); } free(filename); selfp->buffer_fd = fd; return TRUE;}/* An error has occured with the disk buffer; store the extra data in memory until we can recover. */static void store_excess(TaperDiskPortSource * self, char * buf, size_t attempted_size, size_t disk_size) { TaperSource * pself = (TaperSource*)self; g_return_if_fail(attempted_size > 0); g_return_if_fail(disk_size < attempted_size); g_return_if_fail(buf != NULL); g_return_if_fail(selfp->excess_buffer == NULL); selfp->excess_buffer_size = attempted_size - disk_size; selfp->excess_buffer = malloc(selfp->excess_buffer_size); memcpy(selfp->excess_buffer, buf + disk_size, attempted_size - disk_size); selfp->disk_buffered_bytes += disk_size; pself->max_part_size = MIN(pself->max_part_size,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -