diff --git a/src/rrd_open.c b/src/rrd_open.c
index 03cc5b9a1bdf09299d71f60bea509e62da68a97b..46a5fcf412b6b0a2beb41990e49ac97c528d500b 100644 (file)
--- a/src/rrd_open.c
+++ b/src/rrd_open.c
/*****************************************************************************
/*****************************************************************************
- * RRDtool 1.3.2 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
*****************************************************************************
* rrd_open.c Open an RRD File
*****************************************************************************
* $Id$
*****************************************************************************/
*****************************************************************************
* rrd_open.c Open an RRD File
*****************************************************************************
* $Id$
*****************************************************************************/
+#include "rrd_tool.h"
+#include "unused.h"
+
#ifdef WIN32
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif
#ifdef WIN32
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif
+
#ifdef HAVE_BROKEN_MS_ASYNC
#include <sys/types.h>
#include <utime.h>
#endif
#ifdef HAVE_BROKEN_MS_ASYNC
#include <sys/types.h>
#include <utime.h>
#endif
-#include "rrd_tool.h"
-#include "unused.h"
#define MEMBLK 8192
#ifdef WIN32
#define MEMBLK 8192
#ifdef WIN32
if (rdwr & RRD_READONLY) {
flags |= O_RDONLY;
#ifdef HAVE_MMAP
if (rdwr & RRD_READONLY) {
flags |= O_RDONLY;
#ifdef HAVE_MMAP
+# if !defined(AIX)
rrd_simple_file->mm_flags = MAP_PRIVATE;
rrd_simple_file->mm_flags = MAP_PRIVATE;
+# endif
# ifdef MAP_NORESERVE
rrd_simple_file->mm_flags |= MAP_NORESERVE; /* readonly, so no swap backing needed */
# endif
# ifdef MAP_NORESERVE
rrd_simple_file->mm_flags |= MAP_NORESERVE; /* readonly, so no swap backing needed */
# endif
if (rdwr & RRD_CREAT) {
flags |= (O_CREAT | O_TRUNC);
}
if (rdwr & RRD_CREAT) {
flags |= (O_CREAT | O_TRUNC);
}
+ if (rdwr & RRD_EXCL) {
+ flags |= O_EXCL;
+ }
}
if (rdwr & RRD_READAHEAD) {
#ifdef MAP_POPULATE
}
if (rdwr & RRD_READAHEAD) {
#ifdef MAP_POPULATE
rrd_file->file_len = statb.st_size;
} else {
rrd_file->file_len = newfile_size;
rrd_file->file_len = statb.st_size;
} else {
rrd_file->file_len = newfile_size;
+#ifdef HAVE_POSIX_FALLOCATE
+ if (posix_fallocate(rrd_simple_file->fd, 0, newfile_size) == -1) {
+ rrd_set_error("posix_fallocate '%s': %s", file_name,
+ rrd_strerror(errno));
+ goto out_close;
+ }
+#else
lseek(rrd_simple_file->fd, newfile_size - 1, SEEK_SET);
if ( write(rrd_simple_file->fd, "\0", 1) == -1){ /* poke */
rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
goto out_close;
}
lseek(rrd_simple_file->fd, 0, SEEK_SET);
lseek(rrd_simple_file->fd, newfile_size - 1, SEEK_SET);
if ( write(rrd_simple_file->fd, "\0", 1) == -1){ /* poke */
rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
goto out_close;
}
lseek(rrd_simple_file->fd, 0, SEEK_SET);
+#endif
}
#ifdef HAVE_POSIX_FADVISE
/* In general we need no read-ahead when dealing with rrd_files.
}
#ifdef HAVE_POSIX_FADVISE
/* In general we need no read-ahead when dealing with rrd_files.
*/
#ifdef HAVE_MMAP
*/
#ifdef HAVE_MMAP
+#ifndef HAVE_POSIX_FALLOCATE
+ /* force allocating the file on the underlaying filesystem to prevent any
+ * future bus error when the filesystem is full and attempting to write
+ * trough the file mapping. Filling the file using memset on the file
+ * mapping can also lead some bus error, so we use the old fashioned
+ * write().
+ */
+ if (rdwr & RRD_CREAT) {
+ char buf[4096];
+ unsigned i;
+
+ memset(buf, DNAN, sizeof buf);
+ lseek(rrd_simple_file->fd, offset, SEEK_SET);
+
+ for (i = 0; i < (newfile_size - 1) / sizeof buf; ++i)
+ {
+ if (write(rrd_simple_file->fd, buf, sizeof buf) == -1)
+ {
+ rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
+ goto out_close;
+ }
+ }
+
+ if (write(rrd_simple_file->fd, buf,
+ (newfile_size - 1) % sizeof buf) == -1)
+ {
+ rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
+ goto out_close;
+ }
+
+ lseek(rrd_simple_file->fd, 0, SEEK_SET);
+ }
+#endif
+
data = mmap(0, rrd_file->file_len,
rrd_simple_file->mm_prot, rrd_simple_file->mm_flags,
rrd_simple_file->fd, offset);
data = mmap(0, rrd_file->file_len,
rrd_simple_file->mm_prot, rrd_simple_file->mm_flags,
rrd_simple_file->fd, offset);
goto out_close;
}
rrd_simple_file->file_start = data;
goto out_close;
}
rrd_simple_file->file_start = data;
- if (rdwr & RRD_CREAT) {
- memset(data, DNAN, newfile_size - 1);
- goto out_done;
- }
#endif
if (rdwr & RRD_CREAT)
goto out_done;
#endif
if (rdwr & RRD_CREAT)
goto out_done;
int whence)
{
off_t ret = 0;
int whence)
{
off_t ret = 0;
+#ifndef HAVE_MMAP
rrd_simple_file_t *rrd_simple_file;
rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt;
rrd_simple_file_t *rrd_simple_file;
rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt;
-
+#endif
+
#ifdef HAVE_MMAP
if (whence == SEEK_SET)
rrd_file->pos = off;
#ifdef HAVE_MMAP
if (whence == SEEK_SET)
rrd_file->pos = off;
if((rrd_file->pos + count) > old_size)
{
if((rrd_file->pos + count) > old_size)
{
- rrd_set_error("attempting to write beyond end of file");
+ rrd_set_error("attempting to write beyond end of file (%ld + %ld > %ld)",rrd_file->pos, count, old_size);
return -1;
}
memcpy(rrd_simple_file->file_start + rrd_file->pos, buf, count);
return -1;
}
memcpy(rrd_simple_file->file_start + rrd_file->pos, buf, count);
/* this is a leftover from the old days, it serves no purpose
and is therefore turned into a no-op */
void rrd_flush(
/* this is a leftover from the old days, it serves no purpose
and is therefore turned into a no-op */
void rrd_flush(
- rrd_file_t *rrd_file __attribute__((unused)))
+ rrd_file_t UNUSED(*rrd_file))
{
}
{
}
* aligning RRAs within stripes, or other performance enhancements
*/
void rrd_notify_row(
* aligning RRAs within stripes, or other performance enhancements
*/
void rrd_notify_row(
- rrd_file_t *rrd_file __attribute__((unused)),
- int rra_idx __attribute__((unused)),
- unsigned long rra_row __attribute__((unused)),
- time_t rra_time __attribute__((unused)))
+ rrd_file_t UNUSED(*rrd_file),
+ int UNUSED(rra_idx),
+ unsigned long UNUSED(rra_row),
+ time_t UNUSED(rra_time))
{
}
{
}
* don't change to a new disk block at the same time
*/
unsigned long rrd_select_initial_row(
* don't change to a new disk block at the same time
*/
unsigned long rrd_select_initial_row(
- rrd_file_t *rrd_file __attribute__((unused)),
- int rra_idx __attribute__((unused)),
+ rrd_file_t UNUSED(*rrd_file),
+ int UNUSED(rra_idx),
rra_def_t *rra
)
{
rra_def_t *rra
)
{