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 <aserd...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev