X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ovsdb%2Flog.c;h=9c2767cb7206a05ed1efa245e925033f3efce99e;hb=76f105d9be03588c2d5ec0b94ff769a1d269f2e4;hp=837f2155417fe9cc752614c04465bf104ffe5e2f;hpb=c69ee87c10818267f991236201150b1fa51ae519;p=openvswitch diff --git a/ovsdb/log.c b/ovsdb/log.c index 837f2155..9c2767cb 100644 --- a/ovsdb/log.c +++ b/ovsdb/log.c @@ -29,6 +29,7 @@ #include "ovsdb.h" #include "ovsdb-error.h" #include "sha1.h" +#include "socket-util.h" #include "transaction.h" #include "util.h" @@ -50,21 +51,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 +88,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; } @@ -85,22 +107,10 @@ ovsdb_log_open(const char *name, int flags, struct ovsdb_log **filep) 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); + fsync_parent_dir(name); } - 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;