[ovs-dev] [PATCH 1/2] ovsdb windows: Allow online compacting

Alin Serdean aserdean at cloudbasesolutions.com
Thu Oct 27 21:45:42 UTC 2016


This patch allows online compacting to be done under Windows.

To achieve the above we need to close all file handles before trying to
rename the file, switch from rename to MoveFileEx (because rename/MoveFile
fails if the destination exists), reopen the right type of log after the
rename.

If we could not reopen the compacted database or the original database
after the close simply abort and rely on the service manager. This
can be changed in the future.

Signed-off-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
---
 ovsdb/file.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/ovsdb/file.c b/ovsdb/file.c
index 7f8554a..9ff839d 100644
--- a/ovsdb/file.c
+++ b/ovsdb/file.c
@@ -667,28 +667,84 @@ ovsdb_file_compact(struct ovsdb_file *file)
         goto exit;
     }
 
+#ifdef _WIN32
+    /* On Windows we must close the file handles before trying to rename
+     * the files */
+    ovsdb_log_close(file->log);
+    ovsdb_log_close(new_log);
+    file->log = NULL;
+    new_log = NULL;
+#endif
+
     /* Replace original by temporary. */
+#ifdef _WIN32
+    if (!MoveFileEx(tmp_name, file->file_name, MOVEFILE_REPLACE_EXISTING
+                    | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED)) {
+        VLOG_ERR("fcntl: %s", ovs_lasterror_to_string());
+        error = ovsdb_io_error(EACCES, "failed to rename \"%s\" to \"%s\"",
+                               tmp_name, file->file_name);
+        goto exit;
+    }
+#else
     if (rename(tmp_name, file->file_name)) {
         error = ovsdb_io_error(errno, "failed to rename \"%s\" to \"%s\"",
                                tmp_name, file->file_name);
         goto exit;
     }
     fsync_parent_dir(file->file_name);
+#endif
 
 exit:
     if (!error) {
+#ifdef _WIN32
+        error = ovsdb_file_open_log(file->file_name, OVSDB_LOG_READ_WRITE,
+                                    &file->log, NULL);
+        if (error) {
+            goto cleanup;
+        }
+        error = ovsdb_file_txn_commit(NULL, NULL, false, file->log);
+        if (error) {
+            goto cleanup;
+        }
+#else
         ovsdb_log_close(file->log);
         file->log = new_log;
+#endif
         file->last_compact = time_msec();
         file->next_compact = file->last_compact + COMPACT_MIN_MSEC;
         file->n_transactions = 1;
     } else {
+#ifdef _WIN32
+        struct ovsdb_error *temp_error = error;
         ovsdb_log_close(new_log);
+        if (!file->log) {
+            error = ovsdb_file_open_log(file->file_name, OVSDB_LOG_READ_WRITE,
+                                        &file->log, NULL);
+            if (error) {
+                goto cleanup;
+            }
+            error = ovsdb_file_txn_commit(NULL, NULL, false, file->log);
+            if (error) {
+                goto cleanup;
+            }
+            error = temp_error;
+        }
+#else
+        ovsdb_log_close(new_log);
+#endif
         if (tmp_lock) {
             unlink(tmp_name);
         }
     }
 
+#ifdef _WIN32
+cleanup:
+    /* XXX In the future we could retry to open the file instead of
+     * doing an abort. */
+    if (error) {
+        ovs_fatal(1, "could not reopen database");
+    }
+#endif
     lockfile_unlock(tmp_lock);
     free(tmp_name);
     free(comment);
-- 
2.9.2.windows.1



More information about the dev mailing list