diff options
author | Ben Pfaff <blp@nicira.com> | 2010-02-15 11:31:32 -0800 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2010-02-15 11:31:32 -0800 |
commit | 7446f1480bb27ccb63feab066d901cc940d52462 (patch) | |
tree | 9135e88fc73dd1c8dfa352bdd25b90a8abb2c0e4 /ovsdb | |
parent | 475afa1b2c0ced20b47ef8cba25ad5d59c560a08 (diff) | |
download | openvswitch-7446f1480bb27ccb63feab066d901cc940d52462.tar.gz |
ovsdb: Allow ovsdb_log_open()'s caller to choose whether to lock.
The current callers of ovsdb_log_open() always want to lock the file if
they are accessing it for read/write access. An upcoming commit will add
a new caller that does not fit this model (it wants to lock the file
across a wider region) and so the caller should be able to choose whether
to do locking. This commit adds that ability.
Also, get rid of the use of <fcntl.h> flags to choose the open mode, which
has always seemed somewhat crude and which this change would make even
cruder.
Diffstat (limited to 'ovsdb')
-rw-r--r-- | ovsdb/file.c | 4 | ||||
-rw-r--r-- | ovsdb/log.c | 35 | ||||
-rw-r--r-- | ovsdb/log.h | 14 | ||||
-rw-r--r-- | ovsdb/ovsdb-tool.c | 7 |
4 files changed, 45 insertions, 15 deletions
diff --git a/ovsdb/file.c b/ovsdb/file.c index 31086af84..3e07b8449 100644 --- a/ovsdb/file.c +++ b/ovsdb/file.c @@ -43,13 +43,15 @@ static void ovsdb_file_replica_create(struct ovsdb *, struct ovsdb_log *); struct ovsdb_error * ovsdb_file_open(const char *file_name, bool read_only, struct ovsdb **dbp) { + enum ovsdb_log_open_mode open_mode; struct ovsdb_schema *schema; struct ovsdb_error *error; struct ovsdb_log *log; struct json *json; struct ovsdb *db; - error = ovsdb_log_open(file_name, read_only ? O_RDONLY : O_RDWR, &log); + open_mode = read_only ? OVSDB_LOG_READ_ONLY : OVSDB_LOG_READ_WRITE; + error = ovsdb_log_open(file_name, open_mode, -1, &log); if (error) { return error; } diff --git a/ovsdb/log.c b/ovsdb/log.c index 837f21554..6d07aca01 100644 --- a/ovsdb/log.c +++ b/ovsdb/log.c @@ -50,21 +50,33 @@ struct ovsdb_log { enum ovsdb_log_mode mode; }; +/* Attempts to open 'name' with the specified 'open_mode'. On success, stores + * the new log into '*filep' and returns NULL; otherwise returns NULL and + * stores NULL into '*filep'. + * + * Whether the file will be locked using lockfile_lock() depends on 'locking': + * use true to lock it, false not to lock it, or -1 to lock it only if + * 'open_mode' is a mode that allows writing. + */ struct ovsdb_error * -ovsdb_log_open(const char *name, int flags, struct ovsdb_log **filep) +ovsdb_log_open(const char *name, enum ovsdb_log_open_mode open_mode, + int locking, struct ovsdb_log **filep) { struct lockfile *lockfile; struct ovsdb_error *error; struct ovsdb_log *file; struct stat s; FILE *stream; - int accmode; + int flags; int fd; *filep = NULL; - accmode = flags & O_ACCMODE; - if (accmode == O_RDWR || accmode == O_WRONLY) { + assert(locking == -1 || locking == false || locking == true); + if (locking < 0) { + locking = open_mode != OVSDB_LOG_READ_ONLY; + } + if (locking) { int retval = lockfile_lock(name, 0, &lockfile); if (retval) { error = ovsdb_io_error(retval, "%s: failed to lock lockfile", @@ -75,9 +87,18 @@ ovsdb_log_open(const char *name, int flags, struct ovsdb_log **filep) lockfile = NULL; } + if (open_mode == OVSDB_LOG_READ_ONLY) { + flags = O_RDONLY; + } else if (open_mode == OVSDB_LOG_READ_WRITE) { + flags = O_RDWR; + } else if (open_mode == OVSDB_LOG_CREATE) { + flags = O_RDWR | O_CREAT | O_EXCL; + } else { + NOT_REACHED(); + } fd = open(name, flags, 0666); if (fd < 0) { - const char *op = flags & O_CREAT && flags & O_EXCL ? "create" : "open"; + const char *op = open_mode == OVSDB_LOG_CREATE ? "create" : "open"; error = ovsdb_io_error(errno, "%s: %s failed", op, name); goto error_unlock; } @@ -98,9 +119,7 @@ ovsdb_log_open(const char *name, int flags, struct ovsdb_log **filep) free(dir); } - stream = fdopen(fd, (accmode == O_RDONLY ? "rb" - : accmode == O_WRONLY ? "wb" - : "w+b")); + stream = fdopen(fd, open_mode == OVSDB_LOG_READ_ONLY ? "rb" : "w+b"); if (!stream) { error = ovsdb_io_error(errno, "%s: fdopen failed", name); goto error_close; diff --git a/ovsdb/log.h b/ovsdb/log.h index 2daa635ba..045740b93 100644 --- a/ovsdb/log.h +++ b/ovsdb/log.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009 Nicira Networks +/* Copyright (c) 2009, 2010 Nicira Networks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,16 @@ struct json; struct ovsdb_log; -struct ovsdb_error *ovsdb_log_open(const char *name, int flags, - struct ovsdb_log **) WARN_UNUSED_RESULT; +/* Access mode for opening an OVSDB log. */ +enum ovsdb_log_open_mode { + OVSDB_LOG_READ_ONLY, /* Open existing file, read-only. */ + OVSDB_LOG_READ_WRITE, /* Open existing file, read/write. */ + OVSDB_LOG_CREATE /* Create new file, read/write. */ +}; + +struct ovsdb_error *ovsdb_log_open(const char *name, enum ovsdb_log_open_mode, + int locking, struct ovsdb_log **) + WARN_UNUSED_RESULT; void ovsdb_log_close(struct ovsdb_log *); struct ovsdb_error *ovsdb_log_read(struct ovsdb_log *, struct json **) diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c index 34c767618..f419fb852 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -164,8 +164,8 @@ do_create(int argc OVS_UNUSED, char *argv[]) ovsdb_schema_destroy(schema); /* Create database file. */ - check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDWR | O_CREAT | O_EXCL, - &log)); + check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_CREATE, + -1, &log)); check_ovsdb_error(ovsdb_log_write(log, json)); check_ovsdb_error(ovsdb_log_commit(log)); ovsdb_log_close(log); @@ -288,7 +288,8 @@ do_show_log(int argc OVS_UNUSED, char *argv[]) struct ovsdb_log *log; unsigned int i; - check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDONLY, &log)); + check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_READ_ONLY, + -1, &log)); shash_init(&names); for (i = 0; ; i++) { struct json *json; |