rrd resize error

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

rrd resize error

Daniel De Marco
Hi,

I'm trying to resize some rrd files to add more rows to the RRAs and I
get the "ERROR: attempting to write beyond end of file" mentioned in the
following thread ( https://lists.oetiker.ch/pipermail/rrd-users/2011-January/017476.html ).

The thread stopped at the message attached below. Did anybody find a
solution or workaround?

$ rrdtool create pippo.rrd DS:test:GAUGE:120:0:U RRA:AVERAGE:0.5:1:244
$ rrdtool resize pippo.rrd 0 GROW 10
ERROR: attempting to write beyond end of file

Thank you, Daniel.

--------------------------------------------------------------------------------

On Wed, Jan 19, 2011 at 09:12:19AM +0100, Tobias Oetiker wrote:

> Hi Stefan,
>
> Today Stefan Brandl wrote:
>
> >
> > Sorry Tobi, but my C-Programming knowledge is very limited,
> > not to say non-existent :-(
> > Could you tell me, where to put what code to further debug this?
>
> I would guess something like this could serve:
>
> Index: rrd_open.c
> ===================================================================
> --- rrd_open.c  (revision 2172)
> +++ rrd_open.c  (working copy)
> @@ -671,7 +671,7 @@
>
>      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);
>

Ok, thanks.
This gives:

noc at lowrider:~$
noc at lowrider:~$ /opt/rrdtool-1.4.5.002170/bin/rrdtool create
tester.rrd DS:inet:GAUGE:600:0:U RRA:AVERAGE:0.5:1:600
noc at lowrider:~$ /opt/rrdtool-1.4.5.002170/bin/rrdtool resize
tester.rrd 0 GROW 100
ERROR: attempting to write beyond end of file (6144 + 8 > 6148)
noc at lowrider:~$


Stefan

--------------------------------------------------------------------------------

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

oetiker
Administrator
Hi Daniel,

Yesterday Daniel De Marco wrote:

> Hi,
>
> I'm trying to resize some rrd files to add more rows to the RRAs and I
> get the "ERROR: attempting to write beyond end of file" mentioned in the
> following thread ( https://lists.oetiker.ch/pipermail/rrd-users/2011-January/017476.html ).
>
> The thread stopped at the message attached below. Did anybody find a
> solution or workaround?

only in the sense that I was not able to reproduce this on our
systems ... it would be great to figure the cause of this ...

cheers
tobi

>
> $ rrdtool create pippo.rrd DS:test:GAUGE:120:0:U RRA:AVERAGE:0.5:1:244
> $ rrdtool resize pippo.rrd 0 GROW 10
> ERROR: attempting to write beyond end of file
>
> Thank you, Daniel.
>
> --------------------------------------------------------------------------------
>
> On Wed, Jan 19, 2011 at 09:12:19AM +0100, Tobias Oetiker wrote:
> > Hi Stefan,
> >
> > Today Stefan Brandl wrote:
> >
> > >
> > > Sorry Tobi, but my C-Programming knowledge is very limited,
> > > not to say non-existent :-(
> > > Could you tell me, where to put what code to further debug this?
> >
> > I would guess something like this could serve:
> >
> > Index: rrd_open.c
> > ===================================================================
> > --- rrd_open.c  (revision 2172)
> > +++ rrd_open.c  (working copy)
> > @@ -671,7 +671,7 @@
> >
> >      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);
> >
>
> Ok, thanks.
> This gives:
>
> noc at lowrider:~$
> noc at lowrider:~$ /opt/rrdtool-1.4.5.002170/bin/rrdtool create
> tester.rrd DS:inet:GAUGE:600:0:U RRA:AVERAGE:0.5:1:600
> noc at lowrider:~$ /opt/rrdtool-1.4.5.002170/bin/rrdtool resize
> tester.rrd 0 GROW 100
> ERROR: attempting to write beyond end of file (6144 + 8 > 6148)
> noc at lowrider:~$
>
>
> Stefan
>
> --------------------------------------------------------------------------------
>
> _______________________________________________
> rrd-users mailing list
> [hidden email]
> https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
>
>

--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch [hidden email] ++41 62 775 9902 / sb: -9900

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

Daniel De Marco
Hi Tobi,

* Tobias Oetiker <[hidden email]> [06/27/2011 18:33]:
> only in the sense that I was not able to reproduce this on our
> systems ... it would be great to figure the cause of this ...

I looked into it a little bit and I think I found something.

In the text below I'm referring to line numbers as in 1.4.5.

On my system creating a file with:
        ./rrdtool create pippo.rrd DS:test:GAUGE:120:0:U RRA:AVERAGE:0.5:1:2
creates it with a header size of 548, that is not divisible by sizeof(rrd_value_t)=8.
I don't know whether this is normal or not. However this seems connected with
the code in rrd_resize.c around line 264:

    /* Move the rest of the CDPs
     */
    while (1) {
        if (rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1) <= 0)
            break;
        rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
    }

Since the header size is not multiple of sizeof(rrd_value_t) the last
rrd_read in the above block reads just half of a sizeof(rrd_value_t) in
my case and when the write goes to write it out it tries to write past
the end of file triggering the error.

For this block the fix is trivial, but I suspect the problem is in the
header. I tried on a few machines and the header size oddity seems to
happen only on i386. On x86_64 the header size is always a multiple of
sizeof(rrd_value_t). For my example file the header size on x86_64 is
592.

I hope this helps.
Thanks for the great tool, Daniel.

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

Daniel De Marco
* Daniel De Marco <[hidden email]> [06/27/2011 23:09]:
> creates it with a header size of 548, that is not divisible by
> sizeof(rrd_value_t)=8. I don't know whether this is normal or not.

this seems to be normal. However the problem might be in the definition
of rrd_get_header_size in rrd_format.c . To calculate header size the
function includes the sizeof(time_t) that is no longer used in v3.
When rrd_open creates a new file it uses rrd_get_header_size to
determine its size. Then other functions fill it and the 4 extra bytes
remain unused at the end of the file. rrd_resize stumbles on those 4
extra bytes. On x86_64 the sizeof(time_t) is 8, so the extra space at
the end of the file is a multiple of sizeof(rrd_value_t) and rrd_resize
copies it without complaining. What do you think?

Daniel.

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

oetiker
Administrator
Yesterday Daniel De Marco wrote:

> * Daniel De Marco <[hidden email]> [06/27/2011 23:09]:
> > creates it with a header size of 548, that is not divisible by
> > sizeof(rrd_value_t)=8. I don't know whether this is normal or not.
>
> this seems to be normal. However the problem might be in the definition
> of rrd_get_header_size in rrd_format.c . To calculate header size the
> function includes the sizeof(time_t) that is no longer used in v3.
> When rrd_open creates a new file it uses rrd_get_header_size to
> determine its size. Then other functions fill it and the 4 extra bytes
> remain unused at the end of the file. rrd_resize stumbles on those 4
> extra bytes. On x86_64 the sizeof(time_t) is 8, so the extra space at
> the end of the file is a multiple of sizeof(rrd_value_t) and rrd_resize
> copies it without complaining. What do you think?

neat ... so I guess the following should fix this problem:

Index: rrd_format.c
===================================================================
--- rrd_format.c        (revision 2188)
+++ rrd_format.c        (working copy)
@@ -125,8 +125,7 @@
     return sizeof(stat_head_t) + \
         sizeof(ds_def_t) * rrd->stat_head->ds_cnt + \
         sizeof(rra_def_t) * rrd->stat_head->rra_cnt + \
-        sizeof(time_t) + \
-        sizeof(live_head_t) + \
+        atoi(rrd->stat_head->version) < 3 ? sizeof(time_t) : sizeof(live_head_t) + \
         sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt + \
         sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt + \
         sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;

can you try ?

cheers
tobi
>
> Daniel.
>
>

--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch [hidden email] ++41 62 775 9902 / sb: -9900

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

Daniel De Marco
* Tobias Oetiker <[hidden email]> [06/28/2011 18:39]:
> neat ... so I guess the following should fix this problem:
>         atoi(rrd->stat_head->version) < 3 ? sizeof(time_t) : sizeof(live_head_t) + \

this crashes badly. I think it's because the plus has higher precedence.

This seems to work ok:
--- ../../rrdtool-1.4.5/src/rrd_format.c        2010-12-26 14:24:48.000000000 -0500
+++ rrd_format.c        2011-06-29 08:35:38.000000000 -0400
@@ -105,8 +105,7 @@
     return sizeof(stat_head_t) + \
         sizeof(ds_def_t) * rrd->stat_head->ds_cnt + \
         sizeof(rra_def_t) * rrd->stat_head->rra_cnt + \
-        sizeof(time_t) + \
-        sizeof(live_head_t) + \
+       (atoi(rrd->stat_head->version) < 3 ? sizeof(time_t) : sizeof(live_head_t)) + \
         sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt + \
         sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt + \
         sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;

However this solves the problem only for new files.

In order to be able to grow or shrink files created with the old version I used the following:
--- ../../rrdtool-1.4.5/src/rrd_resize.c        2010-12-26 14:24:48.000000000 -0500
+++ rrd_resize.c        2011-06-29 09:07:14.000000000 -0400
@@ -262,9 +262,14 @@
     /* Move the rest of the CDPs
      */
     while (1) {
-        if (rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1) <= 0)
+        ssize_t b_read;
+        if ((b_read=rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1)) <= 0)
             break;
-        rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
+        if(rrd_out_file->pos+b_read > rrd_out_file->file_len) {
+            fprintf(stderr,"WARNING: ignoring last %zu bytes\nWARNING: if you see this message multiple times for a single file you're in trouble\n", b_read);
+            continue;
+        }
+        rrd_write(rrd_out_file, &buffer, b_read);
     }
     rrdnew.rra_def[target_rra].row_cnt += modify;
     rrd_seek(rrd_out_file,

Daniel.

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

oetiker
Administrator
Hi Daniel,
Today Daniel De Marco wrote:

> * Tobias Oetiker <[hidden email]> [06/28/2011 18:39]:
> > neat ... so I guess the following should fix this problem:
> >         atoi(rrd->stat_head->version) < 3 ? sizeof(time_t) : sizeof(live_head_t) + \
>
> this crashes badly. I think it's because the plus has higher precedence.

indeed :-)

>
> This seems to work ok:
> --- ../../rrdtool-1.4.5/src/rrd_format.c        2010-12-26 14:24:48.000000000 -0500
> +++ rrd_format.c        2011-06-29 08:35:38.000000000 -0400
> @@ -105,8 +105,7 @@
>      return sizeof(stat_head_t) + \
>          sizeof(ds_def_t) * rrd->stat_head->ds_cnt + \
>          sizeof(rra_def_t) * rrd->stat_head->rra_cnt + \
> -        sizeof(time_t) + \
> -        sizeof(live_head_t) + \
> +       (atoi(rrd->stat_head->version) < 3 ? sizeof(time_t) : sizeof(live_head_t)) + \
>          sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt + \
>          sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt + \
>          sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;
>
> However this solves the problem only for new files.
>
> In order to be able to grow or shrink files created with the old version I used the following:
> --- ../../rrdtool-1.4.5/src/rrd_resize.c        2010-12-26 14:24:48.000000000 -0500
> +++ rrd_resize.c        2011-06-29 09:07:14.000000000 -0400
> @@ -262,9 +262,14 @@
>      /* Move the rest of the CDPs
>       */
>      while (1) {
> -        if (rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1) <= 0)
> +        ssize_t b_read;
> +        if ((b_read=rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1)) <= 0)
>              break;
> -        rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
> +        if(rrd_out_file->pos+b_read > rrd_out_file->file_len) {
> +            fprintf(stderr,"WARNING: ignoring last %zu bytes\nWARNING: if you see this message multiple times for a single file you're in trouble\n", b_read);
> +            continue;
> +        }
> +        rrd_write(rrd_out_file, &buffer, b_read);
>      }
>      rrdnew.rra_def[target_rra].row_cnt += modify;
>      rrd_seek(rrd_out_file,

neat .... thanks
tobi
>
> Daniel.
>
>

--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch [hidden email] ++41 62 775 9902 / sb: -9900

_______________________________________________
rrd-users mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users
Reply | Threaded
Open this post in threaded view
|

Re: rrd resize error

dawnbreak
Hallo,

I have tested the last SVN snapshot from the 1.4 branch and with new rrd files it works now, but with old rrd files it is not yet working.
$ rrdtool info resize.rrd
ERROR: 'resize.rrd' is too small (should be 116056 bytes)