From: Ben Pfaff Date: Fri, 13 Nov 2009 21:23:35 +0000 (-0800) Subject: ovsdb: Rename ovsdb_file to ovsdb_log. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41709cccb8099972f9c6c3faf583b1286cb92e8a;p=openvswitch ovsdb: Rename ovsdb_file to ovsdb_log. This prepares for introducing a new, higher-level ovsdb_file that encapsulates ovsdb storage in a file. --- diff --git a/lib/vlog-modules.def b/lib/vlog-modules.def index 5dc77458..24f62cc6 100644 --- a/lib/vlog-modules.def +++ b/lib/vlog-modules.def @@ -56,7 +56,7 @@ VLOG_MODULE(ofproto) VLOG_MODULE(openflowd) VLOG_MODULE(ovsdb) VLOG_MODULE(ovsdb_client) -VLOG_MODULE(ovsdb_file) +VLOG_MODULE(ovsdb_log) VLOG_MODULE(ovsdb_jsonrpc_server) VLOG_MODULE(ovsdb_server) VLOG_MODULE(ovsdb_tool) diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk index 04fa52da..b996a306 100644 --- a/ovsdb/automake.mk +++ b/ovsdb/automake.mk @@ -6,10 +6,10 @@ ovsdb_libovsdb_a_SOURCES = \ ovsdb/condition.c \ ovsdb/condition.h \ ovsdb/execution.c \ - ovsdb/file.c \ - ovsdb/file.h \ ovsdb/jsonrpc-server.c \ ovsdb/jsonrpc-server.h \ + ovsdb/log.c \ + ovsdb/log.h \ ovsdb/ovsdb-server.c \ ovsdb/ovsdb.c \ ovsdb/ovsdb.h \ diff --git a/ovsdb/execution.c b/ovsdb/execution.c index f3e91726..6bad67c2 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -20,8 +20,8 @@ #include "column.h" #include "condition.h" -#include "file.h" #include "json.h" +#include "log.h" #include "ovsdb-data.h" #include "ovsdb-error.h" #include "ovsdb-parser.h" @@ -211,7 +211,7 @@ ovsdb_execute_abort(struct ovsdb_execution *x UNUSED, static struct ovsdb_error * do_commit(struct ovsdb_execution *x) { - if (x->db->file) { + if (x->db->log) { struct ovsdb_error *error; struct json *json; @@ -221,14 +221,14 @@ do_commit(struct ovsdb_execution *x) return NULL; } - error = ovsdb_file_write(x->db->file, json); + error = ovsdb_log_write(x->db->log, json); json_destroy(json); if (error) { return ovsdb_wrap_error(error, "writing transaction failed"); } if (x->durable) { - error = ovsdb_file_commit(x->db->file); + error = ovsdb_log_commit(x->db->log); if (error) { return ovsdb_wrap_error(error, "committing transaction failed"); diff --git a/ovsdb/file.c b/ovsdb/file.c deleted file mode 100644 index 4883d76f..00000000 --- a/ovsdb/file.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright (c) 2009 Nicira Networks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "file.h" - -#include -#include -#include -#include -#include -#include - -#include "json.h" -#include "lockfile.h" -#include "ovsdb-error.h" -#include "sha1.h" -#include "util.h" - -#define THIS_MODULE VLM_ovsdb_file -#include "vlog.h" - -enum ovsdb_file_mode { - OVSDB_FILE_READ, - OVSDB_FILE_WRITE -}; - -struct ovsdb_file { - off_t offset; - char *name; - struct lockfile *lockfile; - FILE *stream; - struct ovsdb_error *read_error; - struct ovsdb_error *write_error; - enum ovsdb_file_mode mode; -}; - -struct ovsdb_error * -ovsdb_file_open(const char *name, int flags, struct ovsdb_file **filep) -{ - struct lockfile *lockfile; - struct ovsdb_error *error; - struct ovsdb_file *file; - struct stat s; - FILE *stream; - int accmode; - int fd; - - *filep = NULL; - - accmode = flags & O_ACCMODE; - if (accmode == O_RDWR || accmode == O_WRONLY) { - int retval = lockfile_lock(name, 0, &lockfile); - if (retval) { - error = ovsdb_io_error(retval, "%s: failed to lock lockfile", - name); - goto error; - } - } else { - lockfile = NULL; - } - - fd = open(name, flags, 0666); - if (fd < 0) { - const char *op = flags & O_CREAT && flags & O_EXCL ? "create" : "open"; - error = ovsdb_io_error(errno, "%s: %s failed", op, name); - goto error_unlock; - } - - if (!fstat(fd, &s) && s.st_size == 0) { - /* It's (probably) a new file so fsync() its parent directory to ensure - * that its directory entry is committed to disk. */ - char *dir = dir_name(name); - int dirfd = open(dir, O_RDONLY); - if (dirfd >= 0) { - if (fsync(dirfd) && errno != EINVAL) { - VLOG_ERR("%s: fsync failed (%s)", dir, strerror(errno)); - } - close(dirfd); - } else { - VLOG_ERR("%s: open failed (%s)", dir, strerror(errno)); - } - free(dir); - } - - stream = fdopen(fd, (accmode == O_RDONLY ? "rb" - : accmode == O_WRONLY ? "wb" - : "w+b")); - if (!stream) { - error = ovsdb_io_error(errno, "%s: fdopen failed", name); - goto error_close; - } - - file = xmalloc(sizeof *file); - file->name = xstrdup(name); - file->lockfile = lockfile; - file->stream = stream; - file->offset = 0; - file->read_error = NULL; - file->write_error = NULL; - file->mode = OVSDB_FILE_READ; - *filep = file; - return NULL; - -error_close: - close(fd); -error_unlock: - lockfile_unlock(lockfile); -error: - return error; -} - -void -ovsdb_file_close(struct ovsdb_file *file) -{ - if (file) { - free(file->name); - fclose(file->stream); - lockfile_unlock(file->lockfile); - ovsdb_error_destroy(file->read_error); - ovsdb_error_destroy(file->write_error); - free(file); - } -} - -static const char magic[] = "OVSDB JSON "; - -static bool -parse_header(char *header, unsigned long int *length, - uint8_t sha1[SHA1_DIGEST_SIZE]) -{ - char *p; - - /* 'header' must consist of a magic string... */ - if (strncmp(header, magic, strlen(magic))) { - return false; - } - - /* ...followed by a length in bytes... */ - *length = strtoul(header + strlen(magic), &p, 10); - if (!*length || *length == ULONG_MAX || *p != ' ') { - return false; - } - p++; - - /* ...followed by a SHA-1 hash... */ - if (!sha1_from_hex(sha1, p)) { - return false; - } - p += SHA1_HEX_DIGEST_LEN; - - /* ...and ended by a new-line. */ - if (*p != '\n') { - return false; - } - - return true; -} - -struct ovsdb_file_read_cbdata { - char input[4096]; - struct ovsdb_file *file; - int error; - unsigned long length; -}; - -static struct ovsdb_error * -parse_body(struct ovsdb_file *file, off_t offset, unsigned long int length, - uint8_t sha1[SHA1_DIGEST_SIZE], struct json **jsonp) -{ - unsigned long int bytes_left; - struct json_parser *parser; - struct sha1_ctx ctx; - - sha1_init(&ctx); - parser = json_parser_create(JSPF_TRAILER); - - bytes_left = length; - while (length > 0) { - char input[BUFSIZ]; - int chunk; - - chunk = MIN(length, sizeof input); - if (fread(input, 1, chunk, file->stream) != chunk) { - json_parser_abort(parser); - return ovsdb_io_error(ferror(file->stream) ? errno : EOF, - "%s: error reading %lu bytes " - "starting at offset %lld", file->name, - length, (long long int) offset); - } - sha1_update(&ctx, input, chunk); - json_parser_feed(parser, input, chunk); - length -= chunk; - } - - sha1_final(&ctx, sha1); - *jsonp = json_parser_finish(parser); - return NULL; -} - -struct ovsdb_error * -ovsdb_file_read(struct ovsdb_file *file, struct json **jsonp) -{ - uint8_t expected_sha1[SHA1_DIGEST_SIZE]; - uint8_t actual_sha1[SHA1_DIGEST_SIZE]; - struct ovsdb_error *error; - off_t data_offset; - unsigned long data_length; - struct json *json; - char header[128]; - - *jsonp = json = NULL; - - if (file->read_error) { - return ovsdb_error_clone(file->read_error); - } else if (file->mode == OVSDB_FILE_WRITE) { - return OVSDB_BUG("reading file in write mode"); - } - - if (!fgets(header, sizeof header, file->stream)) { - if (feof(file->stream)) { - error = NULL; - } else { - error = ovsdb_io_error(errno, "%s: read failed", file->name); - } - goto error; - } - - if (!parse_header(header, &data_length, expected_sha1)) { - error = ovsdb_syntax_error(NULL, NULL, "%s: parse error at offset " - "%lld in header line \"%.*s\"", - file->name, (long long int) file->offset, - (int) strcspn(header, "\n"), header); - goto error; - } - - data_offset = file->offset + strlen(header); - error = parse_body(file, data_offset, data_length, actual_sha1, &json); - if (error) { - goto error; - } - - if (memcmp(expected_sha1, actual_sha1, SHA1_DIGEST_SIZE)) { - error = ovsdb_syntax_error(NULL, NULL, "%s: %lu bytes starting at " - "offset %lld have SHA-1 hash "SHA1_FMT" " - "but should have hash "SHA1_FMT, - file->name, data_length, - (long long int) data_offset, - SHA1_ARGS(actual_sha1), - SHA1_ARGS(expected_sha1)); - goto error; - } - - if (json->type == JSON_STRING) { - error = ovsdb_syntax_error(NULL, NULL, "%s: %lu bytes starting at " - "offset %lld are not valid JSON (%s)", - file->name, data_length, - (long long int) data_offset, - json->u.string); - goto error; - } - - file->offset = data_offset + data_length; - *jsonp = json; - return 0; - -error: - file->read_error = ovsdb_error_clone(error); - json_destroy(json); - return error; -} - -struct ovsdb_error * -ovsdb_file_write(struct ovsdb_file *file, struct json *json) -{ - uint8_t sha1[SHA1_DIGEST_SIZE]; - struct ovsdb_error *error; - char *json_string; - char header[128]; - size_t length; - - json_string = NULL; - - if (file->write_error) { - return ovsdb_error_clone(file->write_error); - } else if (file->mode == OVSDB_FILE_READ) { - file->mode = OVSDB_FILE_WRITE; - 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); - goto error; - } - if (ftruncate(fileno(file->stream), file->offset)) { - error = ovsdb_io_error(errno, "%s: cannot truncate to length %lld", - file->name, (long long int) file->offset); - goto error; - } - } - - if (json->type != JSON_OBJECT && json->type != JSON_ARRAY) { - error = OVSDB_BUG("bad JSON type"); - goto error; - } - - /* Compose content. Add a new-line (replacing the null terminator) to make - * the file easier to read, even though it has no semantic value. */ - json_string = json_to_string(json, 0); - length = strlen(json_string) + 1; - json_string[length - 1] = '\n'; - - /* Compose header. */ - sha1_bytes(json_string, length, sha1); - snprintf(header, sizeof header, "%s%zu "SHA1_FMT"\n", - magic, length, SHA1_ARGS(sha1)); - - /* Write. */ - if (fwrite(header, strlen(header), 1, file->stream) != 1 - || fwrite(json_string, length, 1, file->stream) != 1 - || fflush(file->stream)) - { - error = ovsdb_io_error(errno, "%s: write failed", file->name); - - /* Remove any partially written data, ignoring errors since there is - * nothing further we can do. */ - ftruncate(fileno(file->stream), file->offset); - - goto error; - } - - file->offset += strlen(header) + length; - free(json_string); - return 0; - -error: - file->write_error = ovsdb_error_clone(error); - free(json_string); - return error; -} - -struct ovsdb_error * -ovsdb_file_commit(struct ovsdb_file *file) -{ - if (fsync(fileno(file->stream))) { - return ovsdb_io_error(errno, "%s: fsync failed", file->name); - } - return 0; -} diff --git a/ovsdb/file.h b/ovsdb/file.h deleted file mode 100644 index 5178140a..00000000 --- a/ovsdb/file.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2009 Nicira Networks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OVSDB_FILE_H -#define OVSDB_FILE_H 1 - -#include -#include "compiler.h" - -struct json; -struct ovsdb_file; - -struct ovsdb_error *ovsdb_file_open(const char *name, int flags, - struct ovsdb_file **) WARN_UNUSED_RESULT; -void ovsdb_file_close(struct ovsdb_file *); - -struct ovsdb_error *ovsdb_file_read(struct ovsdb_file *, struct json **) - WARN_UNUSED_RESULT; -struct ovsdb_error *ovsdb_file_write(struct ovsdb_file *, struct json *) - WARN_UNUSED_RESULT; -struct ovsdb_error *ovsdb_file_commit(struct ovsdb_file *) - WARN_UNUSED_RESULT; - -#endif /* ovsdb/file.h */ diff --git a/ovsdb/log.c b/ovsdb/log.c new file mode 100644 index 00000000..9c2e277c --- /dev/null +++ b/ovsdb/log.c @@ -0,0 +1,363 @@ +/* Copyright (c) 2009 Nicira Networks + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "log.h" + +#include +#include +#include +#include +#include +#include + +#include "json.h" +#include "lockfile.h" +#include "ovsdb.h" +#include "ovsdb-error.h" +#include "sha1.h" +#include "transaction.h" +#include "util.h" + +#define THIS_MODULE VLM_ovsdb_log +#include "vlog.h" + +enum ovsdb_log_mode { + OVSDB_LOG_READ, + OVSDB_LOG_WRITE +}; + +struct ovsdb_log { + off_t offset; + char *name; + struct lockfile *lockfile; + FILE *stream; + struct ovsdb_error *read_error; + struct ovsdb_error *write_error; + enum ovsdb_log_mode mode; +}; + +struct ovsdb_error * +ovsdb_log_open(const char *name, int flags, struct ovsdb_log **filep) +{ + struct lockfile *lockfile; + struct ovsdb_error *error; + struct ovsdb_log *file; + struct stat s; + FILE *stream; + int accmode; + int fd; + + *filep = NULL; + + accmode = flags & O_ACCMODE; + if (accmode == O_RDWR || accmode == O_WRONLY) { + int retval = lockfile_lock(name, 0, &lockfile); + if (retval) { + error = ovsdb_io_error(retval, "%s: failed to lock lockfile", + name); + goto error; + } + } else { + lockfile = NULL; + } + + fd = open(name, flags, 0666); + if (fd < 0) { + const char *op = flags & O_CREAT && flags & O_EXCL ? "create" : "open"; + error = ovsdb_io_error(errno, "%s: %s failed", op, name); + goto error_unlock; + } + + if (!fstat(fd, &s) && s.st_size == 0) { + /* It's (probably) a new file so fsync() its parent directory to ensure + * that its directory entry is committed to disk. */ + char *dir = dir_name(name); + int dirfd = open(dir, O_RDONLY); + if (dirfd >= 0) { + if (fsync(dirfd) && errno != EINVAL) { + VLOG_ERR("%s: fsync failed (%s)", dir, strerror(errno)); + } + close(dirfd); + } else { + VLOG_ERR("%s: open failed (%s)", dir, strerror(errno)); + } + free(dir); + } + + stream = fdopen(fd, (accmode == O_RDONLY ? "rb" + : accmode == O_WRONLY ? "wb" + : "w+b")); + if (!stream) { + error = ovsdb_io_error(errno, "%s: fdopen failed", name); + goto error_close; + } + + file = xmalloc(sizeof *file); + file->name = xstrdup(name); + file->lockfile = lockfile; + file->stream = stream; + file->offset = 0; + file->read_error = NULL; + file->write_error = NULL; + file->mode = OVSDB_LOG_READ; + *filep = file; + return NULL; + +error_close: + close(fd); +error_unlock: + lockfile_unlock(lockfile); +error: + return error; +} + +void +ovsdb_log_close(struct ovsdb_log *file) +{ + if (file) { + free(file->name); + fclose(file->stream); + lockfile_unlock(file->lockfile); + ovsdb_error_destroy(file->read_error); + ovsdb_error_destroy(file->write_error); + free(file); + } +} + +static const char magic[] = "OVSDB JSON "; + +static bool +parse_header(char *header, unsigned long int *length, + uint8_t sha1[SHA1_DIGEST_SIZE]) +{ + char *p; + + /* 'header' must consist of a magic string... */ + if (strncmp(header, magic, strlen(magic))) { + return false; + } + + /* ...followed by a length in bytes... */ + *length = strtoul(header + strlen(magic), &p, 10); + if (!*length || *length == ULONG_MAX || *p != ' ') { + return false; + } + p++; + + /* ...followed by a SHA-1 hash... */ + if (!sha1_from_hex(sha1, p)) { + return false; + } + p += SHA1_HEX_DIGEST_LEN; + + /* ...and ended by a new-line. */ + if (*p != '\n') { + return false; + } + + return true; +} + +struct ovsdb_log_read_cbdata { + char input[4096]; + struct ovsdb_log *file; + int error; + unsigned long length; +}; + +static struct ovsdb_error * +parse_body(struct ovsdb_log *file, off_t offset, unsigned long int length, + uint8_t sha1[SHA1_DIGEST_SIZE], struct json **jsonp) +{ + unsigned long int bytes_left; + struct json_parser *parser; + struct sha1_ctx ctx; + + sha1_init(&ctx); + parser = json_parser_create(JSPF_TRAILER); + + bytes_left = length; + while (length > 0) { + char input[BUFSIZ]; + int chunk; + + chunk = MIN(length, sizeof input); + if (fread(input, 1, chunk, file->stream) != chunk) { + json_parser_abort(parser); + return ovsdb_io_error(ferror(file->stream) ? errno : EOF, + "%s: error reading %lu bytes " + "starting at offset %lld", file->name, + length, (long long int) offset); + } + sha1_update(&ctx, input, chunk); + json_parser_feed(parser, input, chunk); + length -= chunk; + } + + sha1_final(&ctx, sha1); + *jsonp = json_parser_finish(parser); + return NULL; +} + +struct ovsdb_error * +ovsdb_log_read(struct ovsdb_log *file, struct json **jsonp) +{ + uint8_t expected_sha1[SHA1_DIGEST_SIZE]; + uint8_t actual_sha1[SHA1_DIGEST_SIZE]; + struct ovsdb_error *error; + off_t data_offset; + unsigned long data_length; + struct json *json; + char header[128]; + + *jsonp = json = NULL; + + if (file->read_error) { + return ovsdb_error_clone(file->read_error); + } else if (file->mode == OVSDB_LOG_WRITE) { + return OVSDB_BUG("reading file in write mode"); + } + + if (!fgets(header, sizeof header, file->stream)) { + if (feof(file->stream)) { + error = NULL; + } else { + error = ovsdb_io_error(errno, "%s: read failed", file->name); + } + goto error; + } + + if (!parse_header(header, &data_length, expected_sha1)) { + error = ovsdb_syntax_error(NULL, NULL, "%s: parse error at offset " + "%lld in header line \"%.*s\"", + file->name, (long long int) file->offset, + (int) strcspn(header, "\n"), header); + goto error; + } + + data_offset = file->offset + strlen(header); + error = parse_body(file, data_offset, data_length, actual_sha1, &json); + if (error) { + goto error; + } + + if (memcmp(expected_sha1, actual_sha1, SHA1_DIGEST_SIZE)) { + error = ovsdb_syntax_error(NULL, NULL, "%s: %lu bytes starting at " + "offset %lld have SHA-1 hash "SHA1_FMT" " + "but should have hash "SHA1_FMT, + file->name, data_length, + (long long int) data_offset, + SHA1_ARGS(actual_sha1), + SHA1_ARGS(expected_sha1)); + goto error; + } + + if (json->type == JSON_STRING) { + error = ovsdb_syntax_error(NULL, NULL, "%s: %lu bytes starting at " + "offset %lld are not valid JSON (%s)", + file->name, data_length, + (long long int) data_offset, + json->u.string); + goto error; + } + + file->offset = data_offset + data_length; + *jsonp = json; + return 0; + +error: + file->read_error = ovsdb_error_clone(error); + json_destroy(json); + return error; +} + +struct ovsdb_error * +ovsdb_log_write(struct ovsdb_log *file, struct json *json) +{ + uint8_t sha1[SHA1_DIGEST_SIZE]; + struct ovsdb_error *error; + char *json_string; + char header[128]; + size_t length; + + json_string = NULL; + + if (file->write_error) { + return ovsdb_error_clone(file->write_error); + } else if (file->mode == OVSDB_LOG_READ) { + file->mode = OVSDB_LOG_WRITE; + 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); + goto error; + } + if (ftruncate(fileno(file->stream), file->offset)) { + error = ovsdb_io_error(errno, "%s: cannot truncate to length %lld", + file->name, (long long int) file->offset); + goto error; + } + } + + if (json->type != JSON_OBJECT && json->type != JSON_ARRAY) { + error = OVSDB_BUG("bad JSON type"); + goto error; + } + + /* Compose content. Add a new-line (replacing the null terminator) to make + * the file easier to read, even though it has no semantic value. */ + json_string = json_to_string(json, 0); + length = strlen(json_string) + 1; + json_string[length - 1] = '\n'; + + /* Compose header. */ + sha1_bytes(json_string, length, sha1); + snprintf(header, sizeof header, "%s%zu "SHA1_FMT"\n", + magic, length, SHA1_ARGS(sha1)); + + /* Write. */ + if (fwrite(header, strlen(header), 1, file->stream) != 1 + || fwrite(json_string, length, 1, file->stream) != 1 + || fflush(file->stream)) + { + error = ovsdb_io_error(errno, "%s: write failed", file->name); + + /* Remove any partially written data, ignoring errors since there is + * nothing further we can do. */ + ftruncate(fileno(file->stream), file->offset); + + goto error; + } + + file->offset += strlen(header) + length; + free(json_string); + return 0; + +error: + file->write_error = ovsdb_error_clone(error); + free(json_string); + return error; +} + +struct ovsdb_error * +ovsdb_log_commit(struct ovsdb_log *file) +{ + if (fsync(fileno(file->stream))) { + return ovsdb_io_error(errno, "%s: fsync failed", file->name); + } + return 0; +} + diff --git a/ovsdb/log.h b/ovsdb/log.h new file mode 100644 index 00000000..2daa635b --- /dev/null +++ b/ovsdb/log.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2009 Nicira Networks + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OVSDB_LOG_H +#define OVSDB_LOG_H 1 + +#include +#include "compiler.h" + +struct json; +struct ovsdb_log; + +struct ovsdb_error *ovsdb_log_open(const char *name, int flags, + struct ovsdb_log **) WARN_UNUSED_RESULT; +void ovsdb_log_close(struct ovsdb_log *); + +struct ovsdb_error *ovsdb_log_read(struct ovsdb_log *, struct json **) + WARN_UNUSED_RESULT; +struct ovsdb_error *ovsdb_log_write(struct ovsdb_log *, struct json *) + WARN_UNUSED_RESULT; +struct ovsdb_error *ovsdb_log_commit(struct ovsdb_log *) + WARN_UNUSED_RESULT; + +#endif /* ovsdb/log.h */ diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c index d6e0ff94..8b81ef61 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -24,7 +24,7 @@ #include "command-line.h" #include "compiler.h" -#include "file.h" +#include "log.h" #include "json.h" #include "ovsdb.h" #include "ovsdb-error.h" @@ -144,7 +144,7 @@ do_create(int argc UNUSED, char *argv[]) const char *db_file_name = argv[1]; const char *schema_file_name = argv[2]; struct ovsdb_schema *schema; - struct ovsdb_file *db_file; + struct ovsdb_log *log; struct json *json; /* Read schema from file and convert to JSON. */ @@ -152,11 +152,11 @@ do_create(int argc UNUSED, char *argv[]) json = ovsdb_schema_to_json(schema); /* Create database file. */ - check_ovsdb_error(ovsdb_file_open(db_file_name, O_RDWR | O_CREAT | O_EXCL, - &db_file)); - check_ovsdb_error(ovsdb_file_write(db_file, json)); - check_ovsdb_error(ovsdb_file_commit(db_file)); - ovsdb_file_close(db_file); + check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDWR | O_CREAT | O_EXCL, + &log)); + check_ovsdb_error(ovsdb_log_write(log, json)); + check_ovsdb_error(ovsdb_log_commit(log)); + ovsdb_log_close(log); json_destroy(json); } diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index 6d0f131e..7caa229d 100644 --- a/ovsdb/ovsdb.c +++ b/ovsdb/ovsdb.c @@ -19,7 +19,7 @@ #include -#include "file.h" +#include "log.h" #include "json.h" #include "ovsdb-error.h" #include "ovsdb-parser.h" @@ -153,14 +153,14 @@ ovsdb_schema_to_json(const struct ovsdb_schema *schema) } struct ovsdb * -ovsdb_create(struct ovsdb_file *file, struct ovsdb_schema *schema) +ovsdb_create(struct ovsdb_log *log, struct ovsdb_schema *schema) { struct shash_node *node; struct ovsdb *db; db = xmalloc(sizeof *db); db->schema = schema; - db->file = file; + db->log = log; list_init(&db->triggers); db->run_triggers = false; @@ -178,16 +178,16 @@ ovsdb_open(const char *file_name, bool read_only, struct ovsdb **dbp) { struct ovsdb_schema *schema; struct ovsdb_error *error; - struct ovsdb_file *file; + struct ovsdb_log *log; struct json *json; struct ovsdb *db; - error = ovsdb_file_open(file_name, read_only ? O_RDONLY : O_RDWR, &file); + error = ovsdb_log_open(file_name, read_only ? O_RDONLY : O_RDWR, &log); if (error) { return error; } - error = ovsdb_file_read(file, &json); + error = ovsdb_log_read(log, &json); if (error) { return error; } else if (!json) { @@ -204,8 +204,8 @@ ovsdb_open(const char *file_name, bool read_only, struct ovsdb **dbp) } json_destroy(json); - db = ovsdb_create(read_only ? NULL : file, schema); - while ((error = ovsdb_file_read(file, &json)) == NULL && json) { + db = ovsdb_create(read_only ? NULL : log, schema); + while ((error = ovsdb_log_read(log, &json)) == NULL && json) { struct ovsdb_txn *txn; error = ovsdb_txn_from_json(db, json, &txn); @@ -225,7 +225,7 @@ ovsdb_open(const char *file_name, bool read_only, struct ovsdb **dbp) } if (read_only) { - ovsdb_file_close(file); + ovsdb_log_close(log); } *dbp = db; @@ -251,7 +251,7 @@ ovsdb_destroy(struct ovsdb *db) shash_clear(&db->schema->tables); ovsdb_schema_destroy(db->schema); - ovsdb_file_close(db->file); + ovsdb_log_close(db->log); free(db); } } diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h index 3f62966a..d57ebfca 100644 --- a/ovsdb/ovsdb.h +++ b/ovsdb/ovsdb.h @@ -46,7 +46,7 @@ struct json *ovsdb_schema_to_json(const struct ovsdb_schema *); /* Database. */ struct ovsdb { struct ovsdb_schema *schema; - struct ovsdb_file *file; /* Disk file (null for in-memory db). */ + struct ovsdb_log *log; /* Disk log (null for in-memory db). */ struct shash tables; /* Contains "struct ovsdb_table *"s. */ /* Triggers. */ @@ -54,7 +54,7 @@ struct ovsdb { bool run_triggers; }; -struct ovsdb *ovsdb_create(struct ovsdb_file *, struct ovsdb_schema *); +struct ovsdb *ovsdb_create(struct ovsdb_log *, struct ovsdb_schema *); struct ovsdb_error *ovsdb_open(const char *file_name, bool read_only, struct ovsdb **) WARN_UNUSED_RESULT; diff --git a/tests/automake.mk b/tests/automake.mk index f662d950..3a54e133 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -17,7 +17,7 @@ TESTSUITE_AT = \ tests/lockfile.at \ tests/reconnect.at \ tests/ovsdb.at \ - tests/ovsdb-file.at \ + tests/ovsdb-log.at \ tests/ovsdb-types.at \ tests/ovsdb-data.at \ tests/ovsdb-column.at \ diff --git a/tests/ovsdb-file.at b/tests/ovsdb-file.at deleted file mode 100644 index c85b29e2..00000000 --- a/tests/ovsdb-file.at +++ /dev/null @@ -1,282 +0,0 @@ -AT_BANNER([OVSDB -- file I/O]) - -AT_SETUP([create empty, reread]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_CREAT|O_RDWR'], [0], - [file: open successful -], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read], [0], - [file: open successful -file: read: end of file -], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write one, reread]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]']], [0], - [[file: open successful -file: write:[0] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read], [0], - [[file: open successful -file: read: [0] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([check that O_EXCL works]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[1]']], [0], - [[file: open successful -file: write:[1] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read], [0], - [[file: open successful -file: read: [1] -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_CREAT|O_RDWR|O_EXCL' read], [1], - [], [test-ovsdb: I/O error: create: file failed (File exists) -]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write one, reread]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write one, reread, append]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read read read 'write:["append"]']], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: write:["append"] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read: ["append"] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write, reread one, overwrite]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read 'write:["more data"]']], [0], - [[file: open successful -file: read: [0] -file: write:["more data"] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read], [0], - [[file: open successful -file: read: [0] -file: read: ["more data"] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write, add corrupted data, read]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -AT_CHECK([echo 'xxx' >> file]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read failed: syntax error: file: parse error at offset 174 in header line "xxx" -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write, add corrupted data, read, overwrite]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -AT_CHECK([echo 'xxx' >> file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read read read read 'write:[3]']], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read failed: syntax error: file: parse error at offset 174 in header line "xxx" -file: write:[3] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read: [3] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write, corrupt some data, read, overwrite]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -AT_CHECK([[sed 's/\[2]/[3]/' < file > file.tmp]]) -AT_CHECK([mv file.tmp file]) -AT_CHECK([[grep -c '\[3]' file]], [0], [1 -]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read read read 'write:["longer data"]']], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read failed: syntax error: file: 4 bytes starting at offset 170 have SHA-1 hash 5c031e5c0d3a9338cc127ebe40bb2748b6a67e78 but should have hash 98f55556e7ffd432381b56a19bd485b3e6446442 -file: write:["longer data"] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: ["longer data"] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write, truncate file, read, overwrite]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -AT_CHECK([[sed 's/\[2]/2/' < file > file.tmp]]) -AT_CHECK([mv file.tmp file]) -AT_CHECK([[grep -c '^2$' file]], [0], [1 -]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read read read 'write:["longer data"]']], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read failed: I/O error: file: error reading 4 bytes starting at offset 170 (unexpected end of file) -file: write:["longer data"] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: ["longer data"] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP - -AT_SETUP([write bad JSON, read, overwrite]) -AT_KEYWORDS([ovsdb file]) -AT_CAPTURE_FILE([file]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], - [[file: open successful -file: write:[0] successful -file: write:[1] successful -file: write:[2] successful -]], [ignore]) -AT_CHECK([[printf '%s\n%s\n' 'OVSDB JSON 5 d910b02871075d3156ec8675dfc95b7d5d640aa6' 'null' >> file]]) -OVS_CHECK_LCOV( - [[test-ovsdb file-io file 'O_RDWR' read read read read 'write:["replacement data"]']], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (syntax error at beginning of input) -file: write:["replacement data"] successful -]], [ignore]) -OVS_CHECK_LCOV( - [test-ovsdb file-io file 'O_RDONLY' read read read read read], [0], - [[file: open successful -file: read: [0] -file: read: [1] -file: read: [2] -file: read: ["replacement data"] -file: read: end of file -]], [ignore]) -AT_CHECK([test -f .file.~lock~]) -AT_CLEANUP diff --git a/tests/ovsdb-log.at b/tests/ovsdb-log.at new file mode 100644 index 00000000..b0c1c97b --- /dev/null +++ b/tests/ovsdb-log.at @@ -0,0 +1,282 @@ +AT_BANNER([OVSDB -- logging]) + +AT_SETUP([create empty, reread]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([log]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_CREAT|O_RDWR'], [0], + [file: open successful +], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read], [0], + [file: open successful +file: read: end of log +], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write one, reread]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]']], [0], + [[file: open successful +file: write:[0] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read], [0], + [[file: open successful +file: read: [0] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([check that O_EXCL works]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[1]']], [0], + [[file: open successful +file: write:[1] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read], [0], + [[file: open successful +file: read: [1] +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_CREAT|O_RDWR|O_EXCL' read], [1], + [], [test-ovsdb: I/O error: create: file failed (File exists) +]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write one, reread]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write one, reread, append]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read read read 'write:["append"]']], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: write:["append"] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read: ["append"] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write, reread one, overwrite]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read 'write:["more data"]']], [0], + [[file: open successful +file: read: [0] +file: write:["more data"] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read], [0], + [[file: open successful +file: read: [0] +file: read: ["more data"] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write, add corrupted data, read]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +AT_CHECK([echo 'xxx' >> file]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read failed: syntax error: file: parse error at offset 174 in header line "xxx" +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write, add corrupted data, read, overwrite]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +AT_CHECK([echo 'xxx' >> file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read read read read 'write:[3]']], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read failed: syntax error: file: parse error at offset 174 in header line "xxx" +file: write:[3] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read: [3] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write, corrupt some data, read, overwrite]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +AT_CHECK([[sed 's/\[2]/[3]/' < file > file.tmp]]) +AT_CHECK([mv file.tmp file]) +AT_CHECK([[grep -c '\[3]' file]], [0], [1 +]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read read read 'write:["longer data"]']], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read failed: syntax error: file: 4 bytes starting at offset 170 have SHA-1 hash 5c031e5c0d3a9338cc127ebe40bb2748b6a67e78 but should have hash 98f55556e7ffd432381b56a19bd485b3e6446442 +file: write:["longer data"] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: ["longer data"] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write, truncate file, read, overwrite]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +AT_CHECK([[sed 's/\[2]/2/' < file > file.tmp]]) +AT_CHECK([mv file.tmp file]) +AT_CHECK([[grep -c '^2$' file]], [0], [1 +]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read read read 'write:["longer data"]']], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read failed: I/O error: file: error reading 4 bytes starting at offset 170 (unexpected end of file) +file: write:["longer data"] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: ["longer data"] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP + +AT_SETUP([write bad JSON, read, overwrite]) +AT_KEYWORDS([ovsdb log]) +AT_CAPTURE_FILE([file]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_CREAT|O_RDWR' 'write:[0]' 'write:[1]' 'write:[2]']], [0], + [[file: open successful +file: write:[0] successful +file: write:[1] successful +file: write:[2] successful +]], [ignore]) +AT_CHECK([[printf '%s\n%s\n' 'OVSDB JSON 5 d910b02871075d3156ec8675dfc95b7d5d640aa6' 'null' >> file]]) +OVS_CHECK_LCOV( + [[test-ovsdb log-io file 'O_RDWR' read read read read 'write:["replacement data"]']], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read failed: syntax error: file: 5 bytes starting at offset 228 are not valid JSON (syntax error at beginning of input) +file: write:["replacement data"] successful +]], [ignore]) +OVS_CHECK_LCOV( + [test-ovsdb log-io file 'O_RDONLY' read read read read read], [0], + [[file: open successful +file: read: [0] +file: read: [1] +file: read: [2] +file: read: ["replacement data"] +file: read: end of log +]], [ignore]) +AT_CHECK([test -f .file.~lock~]) +AT_CLEANUP diff --git a/tests/ovsdb.at b/tests/ovsdb.at index 0e0e63b0..d3d53bcc 100644 --- a/tests/ovsdb.at +++ b/tests/ovsdb.at @@ -22,7 +22,7 @@ m4_define([OVSDB_CHECK_NEGATIVE], [0], [ignore], [ignore]) AT_CLEANUP]) -m4_include([tests/ovsdb-file.at]) +m4_include([tests/ovsdb-log.at]) m4_include([tests/ovsdb-types.at]) m4_include([tests/ovsdb-data.at]) m4_include([tests/ovsdb-column.at]) diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index bee1818b..72fada14 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -30,7 +30,7 @@ #include "ovsdb-types.h" #include "ovsdb/column.h" #include "ovsdb/condition.h" -#include "ovsdb/file.h" +#include "ovsdb/log.h" #include "ovsdb/ovsdb.h" #include "ovsdb/query.h" #include "ovsdb/row.h" @@ -98,7 +98,7 @@ usage(void) { printf("%s: Open vSwitch database test utility\n" "usage: %s [OPTIONS] COMMAND [ARG...]\n\n" - " file-io FILE FLAGS COMMAND...\n" + " log-io FILE FLAGS COMMAND...\n" " open FILE with FLAGS, run COMMANDs\n" " parse-atomic-type TYPE\n" " parse TYPE as OVSDB atomic type, and re-serialize\n" @@ -196,13 +196,13 @@ check_ovsdb_error(struct ovsdb_error *error) /* Command implementations. */ static void -do_file_io(int argc, char *argv[]) +do_log_io(int argc, char *argv[]) { const char *name = argv[1]; char *mode = argv[2]; struct ovsdb_error *error; - struct ovsdb_file *file; + struct ovsdb_log *log; char *save_ptr = NULL; const char *token; int flags; @@ -226,7 +226,7 @@ do_file_io(int argc, char *argv[]) } } - check_ovsdb_error(ovsdb_file_open(name, flags, &file)); + check_ovsdb_error(ovsdb_log_open(name, flags, &log)); printf("%s: open successful\n", name); for (i = 3; i < argc; i++) { @@ -234,24 +234,24 @@ do_file_io(int argc, char *argv[]) if (!strcmp(command, "read")) { struct json *json; - error = ovsdb_file_read(file, &json); + error = ovsdb_log_read(log, &json); if (!error) { printf("%s: read: ", name); if (json) { print_and_free_json(json); } else { - printf("end of file\n"); + printf("end of log\n"); } continue; } } else if (!strncmp(command, "write:", 6)) { struct json *json = parse_json(command + 6); - error = ovsdb_file_write(file, json); + error = ovsdb_log_write(log, json); json_destroy(json); } else if (!strcmp(command, "commit")) { - error = ovsdb_file_commit(file); + error = ovsdb_log_commit(log); } else { - ovs_fatal(0, "unknown file-io command \"%s\"", command); + ovs_fatal(0, "unknown log-io command \"%s\"", command); } if (error) { char *s = ovsdb_error_to_string(error); @@ -262,7 +262,7 @@ do_file_io(int argc, char *argv[]) } } - ovsdb_file_close(file); + ovsdb_log_close(log); } static void @@ -1207,7 +1207,7 @@ do_transact(int argc, char *argv[]) } static struct command all_commands[] = { - { "file-io", 2, INT_MAX, do_file_io }, + { "log-io", 2, INT_MAX, do_log_io }, { "parse-atomic-type", 1, 1, do_parse_atomic_type }, { "parse-type", 1, 1, do_parse_type }, { "parse-atoms", 2, INT_MAX, do_parse_atoms },