List:Commits« Previous MessageNext Message »
From:Rafal Somla Date:September 4 2008 9:01am
Subject:bzr commit into mysql-6.0-backup branch (rsomla:2691) Bug#37522
View as plain text  
#At file:///ext/mysql/bzr/backup/bug37522/

 2691 Rafal Somla	2008-09-04
      BUG#37522 (Backup: stream_v1_transport: Error condition should be checked for as_* calls)
      
      This patch adds checks for errors in stream_v1_transport.c where the low level I/O 
      functions are called.
modified:
  sql/backup/stream_v1.h
  sql/backup/stream_v1_transport.c

per-file messages:
  sql/backup/stream_v1.h
    Add specifications for the low-level I/O functions implementing abstract stream
    interface.
  sql/backup/stream_v1_transport.c
    - Make sure error is reported and stream state set to ERROR whenever the low-level I/O functions report error.
    - Turn append_to_buffer() into void function as it can never error.
=== modified file 'sql/backup/stream_v1.h'
--- a/sql/backup/stream_v1.h	2008-05-14 00:35:24 +0000
+++ b/sql/backup/stream_v1.h	2008-09-04 09:01:30 +0000
@@ -378,6 +378,16 @@ int bstream_next_chunk(backup_stream*);
   the bytes being written to/read from a backup stream. This is done by
   storing pointers to functions performing basic I/O operations inside
   this structure.
+  
+  Low-level @c write(), @c read() and @c forward() functions should return 
+  BSTREAM_OK on success and BSTREAM_ERROR on error. Additionally, @c read() 
+  should return BSTREAM_EOS if there is no more data in the input stream.
+  
+  Functions @c write() and @c read() should behave like functions
+  @c bstream_write_part() and @c bstream_read_part(), respectively. The latter
+  are documented in stream_v1_transport.c. The only difference is that low-level
+  @c read() doesn't deal with chunk boundaries and never returns BSTREAM_EOC. 
+  However, it should detect end of stream and return BSTREAM_EOS in that case.
  */
 struct st_abstract_stream
 {

=== modified file 'sql/backup/stream_v1_transport.c'
--- a/sql/backup/stream_v1_transport.c	2008-07-19 03:03:39 +0000
+++ b/sql/backup/stream_v1_transport.c	2008-09-04 09:01:30 +0000
@@ -386,7 +386,14 @@ int write_buffer(backup_stream *s)
   int ret= BSTREAM_OK;
 
   if (s->buf.pos > s->buf.begin)
+  {
     ret= as_write_all(&s->stream,*(bstream_blob*)&s->buf,s->mem);
+    if (ret != BSTREAM_OK)
+    {
+      s->state= ERROR;
+      return BSTREAM_ERROR;
+    }
+  }
 
   /*
     Now buffer should be empty. If whole block has been written, reset buffer
@@ -398,7 +405,7 @@ int write_buffer(backup_stream *s)
   else
     s->buf.begin= s->buf.header= s->buf.pos; /* now invariant should hold */
 
-  return ret;
+  return BSTREAM_OK;
 }
 
 /**
@@ -408,18 +415,16 @@ int write_buffer(backup_stream *s)
   is left for fragment`s header.
 */
 static
-int append_to_buffer(backup_stream *s, blob *b)
+void append_to_buffer(backup_stream *s, blob *b)
 {
   if (b->begin >= b->end) /* no data to append */
-    return BSTREAM_OK;
+    return;
 
   if(s->buf.pos == s->buf.header) /* current fragment empty */
     s->buf.pos++;
 
   while ((s->buf.pos < s->buf.end) && (b->begin < b->end))
    *(s->buf.pos++)= *(b->begin++);
-
-  return BSTREAM_OK;
 }
 
 /**
@@ -658,6 +663,12 @@ int load_buffer(backup_stream *s)
 
     ret= as_read(&s->stream,&data,s->mem);
 
+    if (ret == BSTREAM_ERROR)
+    {
+      s->state= ERROR;
+      return BSTREAM_ERROR;
+    }
+
     s->buf.pos= data.begin;
 
     /*
@@ -751,6 +762,7 @@ int load_buffer(backup_stream *s)
   @retval BSTREAM_OK   next fragment has been entered
   @retval BSTREAM_EOC  the entered fragment is the last fragment of a chunk
   @retval BSTREAM_EOS  there are no more fragments in the stream
+  @retval BSTREAM_ERROR error when reading from underlying stream
 */
 static
 int load_next_fragment(backup_stream *s)
@@ -766,7 +778,7 @@ int load_next_fragment(backup_stream *s)
 
   s->state= NORMAL; /* default, unless changed below */
 
-  ret= read_fragment_header(&s->buf.header);
+  ret= read_fragment_header(&s->buf.header);    // Never errors.
 
   /*
     If buf.header was not moved, it means that the fragment extends to
@@ -1052,7 +1064,10 @@ int bstream_write_part(backup_stream *s,
 
     ret= as_write_all(&s->stream,*data,buf);
     if (ret != BSTREAM_OK)
+    {
+      s->state= ERROR;
       return ret;
+    }
 
     data->begin= data->end;
     data->end= saved_end;
@@ -1088,6 +1103,11 @@ int bstream_write_part(backup_stream *s,
     data->end= data->begin + (fragment.begin - s->buf.pos);
 
     ret= as_write_all(&s->stream,*data,*data);
+    if (ret != BSTREAM_OK)
+    {
+      s->state= ERROR;
+      return ret;
+    }
 
     data->begin= data->end;
     data->end= saved_end;
@@ -1185,6 +1205,8 @@ int bstream_end_chunk(backup_stream *s)
   else
   {
     ret= close_current_fragment(s);
+    if (ret != BSTREAM_OK)
+      return BSTREAM_ERROR;
 
     /*
       If the last fragment in the buffer is a small fragment, we can mark it as
@@ -1423,7 +1445,6 @@ int bstream_read_part(backup_stream *s, 
   if ((s->buf.begin == s->buf.end) || (s->buf.begin == s->buf.header))
   {
     ret= load_buffer(s);
-
     if (ret != BSTREAM_OK)
       return ret;
   }
@@ -1482,11 +1503,17 @@ int bstream_read_part(backup_stream *s, 
     saved= *data;
     data->end= data->begin + howmuch;
 
-    if (as_read(&s->stream, data, buf) == BSTREAM_EOS)
+    ret= as_read(&s->stream, data, buf);
+
+    if (ret == BSTREAM_ERROR)
     {
-      s->state= EOS;
+      s->state= ERROR;
+      return BSTREAM_ERROR;
     }
 
+    if (ret == BSTREAM_EOS)
+      s->state= EOS;
+
     s->buf.begin += data->begin - saved.begin;
     s->buf.pos= s->buf.begin;
 
@@ -1592,7 +1619,14 @@ int bstream_next_chunk(backup_stream *s)
     else
     {
       howmuch= s->buf.header - s->buf.pos;
-      as_forward(&s->stream, &howmuch);
+      ret= as_forward(&s->stream, &howmuch);
+      
+      if (ret != BSTREAM_OK)
+      {
+        s->state= ERROR;
+        return BSTREAM_ERROR;
+      }
+
       s->buf.begin= s->buf.pos= s->buf.header;
     }
   }
@@ -1621,6 +1655,9 @@ int bstream_next_chunk(backup_stream *s)
 
   ret= load_next_fragment(s);
 
+  if (ret == BSTREAM_ERROR)     // To avoid invariant check below.
+    return ret;
+
   /* if we hit EOC marker here, we treat it as empty chunk */
   if (ret == BSTREAM_EOC)
     ret= BSTREAM_OK;
@@ -1638,5 +1675,13 @@ int bstream_next_chunk(backup_stream *s)
 */
 int bstream_skip(backup_stream *s, unsigned long int howmuch)
 {
-  return as_forward(&s->stream, &howmuch);
+  int ret= as_forward(&s->stream, &howmuch);
+
+  if (ret != BSTREAM_OK)
+  {
+    s->state= ERROR;
+    return BSTREAM_ERROR;
+  }
+
+  return BSTREAM_OK;
 }

Thread
bzr commit into mysql-6.0-backup branch (rsomla:2691) Bug#37522Rafal Somla4 Sep
  • Re: bzr commit into mysql-6.0-backup branch (rsomla:2691) Bug#37522Jørgen Løland8 Sep
  • Re: bzr commit into mysql-6.0-backup branch (rsomla:2691) Bug#37522Øystein Grøvlen9 Sep
    • Re: bzr commit into mysql-6.0-backup branch (rsomla:2691) Bug#37522Rafal Somla10 Sep