diff options
author | Ben Pfaff <blp@nicira.com> | 2012-07-30 14:41:13 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2012-08-01 10:55:58 -0700 |
commit | b1fdc5fb270c0ca21de4bbe5002aca4dd79e9911 (patch) | |
tree | 1be30a821d462a2683a82e39f6c80fe0509b1be9 /lib/lockfile.c | |
parent | fee0c9631470e8eb10df25544f6661d0beb43a7a (diff) |
lockfile: Be more forgiving about lockfiles for symlinks.
As the database is being transitioned from /etc to /var, there is a symlink
from the old to the new location for the database and a symlink for its
lockfile. This works OK, but it would be more user-friendly to still work
correctly in case the symlink for the lockfile isn't there (since its
existence is non-obvious), so this commit implements that behavior.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/lockfile.c')
-rw-r--r-- | lib/lockfile.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/lockfile.c b/lib/lockfile.c index c55be661..7ac34659 100644 --- a/lib/lockfile.c +++ b/lib/lockfile.c @@ -59,16 +59,29 @@ static int lockfile_try_lock(const char *name, bool block, struct lockfile **lockfilep); /* Returns the name of the lockfile that would be created for locking a file - * named 'file_name'. The caller is responsible for freeing the returned - * name, with free(), when it is no longer needed. */ + * named 'filename_'. The caller is responsible for freeing the returned name, + * with free(), when it is no longer needed. */ char * -lockfile_name(const char *file_name) +lockfile_name(const char *filename_) { - const char *slash = strrchr(file_name, '/'); - return (slash - ? xasprintf("%.*s/.%s.~lock~", - (int) (slash - file_name), file_name, slash + 1) - : xasprintf(".%s.~lock~", file_name)); + char *filename; + const char *slash; + char *lockname; + + /* If 'filename_' is a symlink, base the name of the lockfile on the + * symlink's target rather than the name of the symlink. That way, if a + * file is symlinked, but there is no symlink for its lockfile, then there + * is only a single lockfile for both the source and the target of the + * symlink, not one for each. */ + filename = follow_symlinks(filename_); + slash = strrchr(filename, '/'); + lockname = (slash + ? xasprintf("%.*s/.%s.~lock~", + (int) (slash - filename), filename, slash + 1) + : xasprintf(".%s.~lock~", filename)); + free(filename); + + return lockname; } /* Locks the configuration file against modification by other processes and |