@@ -24,6 +24,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "openvswitch/dynamic-string.h"
#include "openvswitch/json.h"
#include "openvswitch/vlog.h"
#include "lockfile.h"
@@ -419,18 +420,32 @@ ovsdb_log_unread(struct ovsdb_log *file)
file->offset = file->prev_offset;
}
+void
+ovsdb_log_compose_record(const struct json *json,
+ const char *magic, struct ds *header, struct ds *data)
+{
+ ovs_assert(json->type == JSON_OBJECT || json->type == JSON_ARRAY);
+ ovs_assert(!header->length);
+ ovs_assert(!data->length);
+
+ /* 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_to_ds(json, 0, data);
+ ds_put_char(data, '\n');
+
+ /* Compose header. */
+ uint8_t sha1[SHA1_DIGEST_SIZE];
+ sha1_bytes(data->string, data->length, sha1);
+ ds_put_format(header, "%s %"PRIuSIZE" "SHA1_FMT"\n",
+ magic, data->length, SHA1_ARGS(sha1));
+}
+
/* Writes log record 'json' to 'file'. Returns NULL if successful or an error
* (which the caller must eventually destroy) on failure. */
struct ovsdb_error *
ovsdb_log_write(struct ovsdb_log *file, const 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;
switch (file->state) {
case OVSDB_LOG_WRITE:
@@ -463,22 +478,18 @@ ovsdb_log_write(struct ovsdb_log *file, const struct json *json)
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 %"PRIuSIZE" "SHA1_FMT"\n",
- file->magic, length, SHA1_ARGS(sha1));
+ struct ds header = DS_EMPTY_INITIALIZER;
+ struct ds data = DS_EMPTY_INITIALIZER;
+ ovsdb_log_compose_record(json, file->magic, &header, &data);
+ size_t total_length = header.length + data.length;
/* Write. */
- if (fwrite(header, strlen(header), 1, file->stream) != 1
- || fwrite(json_string, length, 1, file->stream) != 1
- || fflush(file->stream))
- {
+ bool ok = (fwrite(header.string, header.length, 1, file->stream) == 1
+ && fwrite(data.string, data.length, 1, file->stream) == 1
+ && fflush(file->stream) == 0);
+ ds_destroy(&header);
+ ds_destroy(&data);
+ if (!ok) {
error = ovsdb_io_error(errno, "%s: write failed", file->name);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
@@ -492,14 +503,12 @@ ovsdb_log_write(struct ovsdb_log *file, const struct json *json)
goto error;
}
- file->offset += strlen(header) + length;
- free(json_string);
+ file->offset += total_length;
return NULL;
error:
file->state = OVSDB_LOG_WRITE_ERROR;
file->error = ovsdb_error_clone(error);
- free(json_string);
return error;
}
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include "compiler.h"
+struct ds;
struct json;
struct ovsdb_log;
@@ -42,6 +43,9 @@ struct ovsdb_error *ovsdb_log_read(struct ovsdb_log *, struct json **)
OVS_WARN_UNUSED_RESULT;
void ovsdb_log_unread(struct ovsdb_log *);
+void ovsdb_log_compose_record(const struct json *, const char *magic,
+ struct ds *header, struct ds *data);
+
struct ovsdb_error *ovsdb_log_write(struct ovsdb_log *, const struct json *)
OVS_WARN_UNUSED_RESULT;
struct ovsdb_error *ovsdb_log_commit(struct ovsdb_log *)
This will acquire a new user later on. Signed-off-by: Ben Pfaff <blp@ovn.org> --- ovsdb/log.c | 55 ++++++++++++++++++++++++++++++++----------------------- ovsdb/log.h | 4 ++++ 2 files changed, 36 insertions(+), 23 deletions(-)