ovsdb: Allow recovery from transient write errors in log implementation.
authorBen Pfaff <blp@nicira.com>
Fri, 1 Mar 2013 19:16:24 +0000 (11:16 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 12 Mar 2013 19:37:34 +0000 (12:37 -0700)
Until now, the OVSDB data journaling implementation has made write errors
"sticky", so that a single write error persists as long as ovsdb-server is
alive.  However, some kinds of write errors (such as ENOSPC) can be
transient in practice.  I don't know of a good reason to make such errors
sticky, so this commit makes the journaling code retry writes even after
an error occurs, allowing ovsdb-server to recover from transient errors.

Reported-by: likunyun <kunyunli@hotmail.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
ovsdb/log.c

index 440e8d0..ea3c3f3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ struct ovsdb_log {
     struct lockfile *lockfile;
     FILE *stream;
     struct ovsdb_error *read_error;
-    struct ovsdb_error *write_error;
+    bool write_error;
     enum ovsdb_log_mode mode;
 };
 
@@ -133,7 +133,7 @@ ovsdb_log_open(const char *name, enum ovsdb_log_open_mode open_mode,
     file->prev_offset = 0;
     file->offset = 0;
     file->read_error = NULL;
-    file->write_error = NULL;
+    file->write_error = false;
     file->mode = OVSDB_LOG_READ;
     *filep = file;
     return NULL;
@@ -154,7 +154,6 @@ ovsdb_log_close(struct ovsdb_log *file)
         fclose(file->stream);
         lockfile_unlock(file->lockfile);
         ovsdb_error_destroy(file->read_error);
-        ovsdb_error_destroy(file->write_error);
         free(file);
     }
 }
@@ -332,10 +331,9 @@ ovsdb_log_write(struct ovsdb_log *file, struct json *json)
 
     json_string = NULL;
 
-    if (file->write_error) {
-        return ovsdb_error_clone(file->write_error);
-    } else if (file->mode == OVSDB_LOG_READ) {
+    if (file->mode == OVSDB_LOG_READ || file->write_error) {
         file->mode = OVSDB_LOG_WRITE;
+        file->write_error = false;
         if (fseeko(file->stream, file->offset, SEEK_SET)) {
             error = ovsdb_io_error(errno, "%s: cannot seek to offset %lld",
                                    file->name, (long long int) file->offset);
@@ -383,7 +381,7 @@ ovsdb_log_write(struct ovsdb_log *file, struct json *json)
     return NULL;
 
 error:
-    file->write_error = ovsdb_error_clone(error);
+    file->write_error = true;
     free(json_string);
     return error;
 }