From 66c33aab22d73f374cb081baefe9d72a5bab3de5 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 15 Jul 2010 15:22:34 +0200 Subject: libmount: clean up lock.c Signed-off-by: Karel Zak --- shlibs/mount/src/lock.c | 114 ++++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 52 deletions(-) (limited to 'shlibs/mount/src/lock.c') diff --git a/shlibs/mount/src/lock.c b/shlibs/mount/src/lock.c index 0f35aa3bd..beea23980 100644 --- a/shlibs/mount/src/lock.c +++ b/shlibs/mount/src/lock.c @@ -36,7 +36,6 @@ * lock handler */ struct _mnt_lock { - pid_t id; /* getpid() or so (see linkfile)... */ char *lockfile; /* path to lock file (e.g. /etc/mtab~) */ char *linkfile; /* path to link file (e.g. /etc/mtab~.) */ int lockfile_fd; /* lock file descriptor */ @@ -46,30 +45,44 @@ struct _mnt_lock { /** * mnt_new_lock: - * @lockfile: path to lockfile or NULL (default is _PATH_MOUNTED_LOCK) + * @dataname: the file that should be covered by the lock * @id: unique linkfile identifier or 0 (default is getpid()) * * Returns: newly allocated lock handler or NULL on case of error. */ -mnt_lock *mnt_new_lock(const char *lockfile, pid_t id) +mnt_lock *mnt_new_lock(const char *datafile, pid_t id) { - mnt_lock *ml = calloc(1, sizeof(struct _mnt_lock)); + mnt_lock *ml = NULL; + char *lo = NULL, *ln = NULL; - if (!ml) + /* lockfile */ + if (!datafile) return NULL; - ml->lockfile_fd = -1; - ml->id = id; - if (lockfile) { - ml->lockfile = strdup(lockfile); - if (!ml->lockfile) { - free(ml); - return NULL; - } + if (asprintf(&lo, "%s~", datafile) == -1) { + lo = NULL; + goto err; + } + if (asprintf(&ln, "%s~.%d", datafile, id ? : getpid()) == -1) { + ln = NULL; + goto err; } + ml = calloc(1, sizeof(struct _mnt_lock) ); + if (!ml) + goto err; + + ml->lockfile_fd = -1; + ml->linkfile = ln; + ml->lockfile = lo; return ml; +err: + free(lo); + free(ln); + free(ml); + return NULL; } + /** * mnt_free_lock: * @ml: mnt_lock handler @@ -93,38 +106,21 @@ void mnt_free_lock(mnt_lock *ml) */ const char *mnt_lock_get_lockfile(mnt_lock *ml) { - if (!ml) - return NULL; - if (ml->lockfile) - return ml->lockfile; - return _PATH_MOUNTED_LOCK; + return ml ? ml->lockfile : NULL; } /** * mnt_lock_get_linkfile: * @ml: mnt_lock handler * - * Returns: unique (per process) path to linkfile. + * Note that the filename is generated by mnt_new_lock() and depends on + * getpid() or 'id' argument of the mnt_new_lock() function. + * + * Returns: unique (per process/thread) path to linkfile. */ const char *mnt_lock_get_linkfile(mnt_lock *ml) { - if (!ml) - return NULL; - - if (!ml->linkfile) { - const char *lf = mnt_lock_get_lockfile(ml); - size_t sz; - - if (!lf) - return NULL; - sz = strlen(lf) + 32; - - ml->linkfile = malloc(sz); - if (ml->linkfile) - snprintf(ml->linkfile, sz, "%s.%d", - lf, ml->id ? ml->id : getpid()); - } - return ml->linkfile; + return ml ? ml->linkfile : NULL; } static void mnt_lockalrm_handler(int sig) @@ -208,8 +204,10 @@ static int mnt_wait_lock(mnt_lock *ml, struct flock *fl, time_t maxtime) * * This mtab locking code has been refactored and moved to libmount. The mtab * locking is really not perfect (e.g. SIGALRM), but it's stable, reliable and - * backwardly compatible code. Don't forget that this code has to be compatible - * with 3rd party mounts (/sbin/mount.) and has to work with NFS. + * backwardly compatible code. + * + * Don't forget that this code has to be compatible with 3rd party mounts + * (/sbin/mount.) and has to work with NFS. * -- kzak@redhat.com [May-2009] */ @@ -219,13 +217,20 @@ static int mnt_wait_lock(mnt_lock *ml, struct flock *fl, time_t maxtime) /* sleep time (in microseconds, max=999999) between attempts */ #define MOUNTLOCK_WAITTIME 5000 -/* Remove lock file. */ +/** + * mnt_unlock_file: + * @ml: lock struct + * + * Unlocks the file. The function could be called independently on the + * lock status (for example from exit(3)). + */ void mnt_unlock_file(mnt_lock *ml) { if (!ml) return; - DBG(DEBUG_LOCKS, fprintf(stderr, "LOCK: (%d) unlocking/cleaning.\n", getpid())); + DBG(DEBUG_LOCKS, fprintf(stderr, + "LOCK: (%d) unlocking/cleaning.\n", getpid())); if (ml->locked == 0 && ml->lockfile && ml->linkfile) { @@ -286,10 +291,14 @@ void mnt_unlock_file(mnt_lock *ml) * int update_mtab() * { * int sig = 0; + * const char *mtab; * - * atexit(unlock_fallback); + * if (!(mtab = mnt_get_writable_mtab_path())) + * return 0; // system without mtab + * if (!(ml = mnt_new_lock(mtab, 0))) + * return -1; // error * - * ml = mnt_new_lock(NULL, 0); + * atexit(unlock_fallback); * * if (mnt_lock_file(ml) != 0) { * printf(stderr, "cannot create %s lockfile\n", @@ -404,7 +413,7 @@ int mnt_lock_file(mnt_lock *ml) } DBG(DEBUG_LOCKS, fprintf(stderr, "LOCK: %s: (%d) successfully locked\n", - ml->lockfile, getpid())); + lockfile, getpid())); unlink(linkfile); return 0; @@ -464,15 +473,14 @@ void sig_handler(int sig) int test_lock(struct mtest *ts, int argc, char *argv[]) { - const char *lockfile, *datafile; + const char *datafile; int verbose = 0, loops, l; - if (argc < 4) + if (argc < 3) return -1; - lockfile = argv[1]; - datafile = argv[2]; - loops = atoi(argv[3]); + datafile = argv[1]; + loops = atoi(argv[2]); if (argc == 5 && strcmp(argv[4], "--verbose") == 0) verbose = 1; @@ -493,11 +501,13 @@ int test_lock(struct mtest *ts, int argc, char *argv[]) } for (l = 0; l < loops; l++) { - lock = mnt_new_lock(lockfile, 0); + lock = mnt_new_lock(datafile, 0); + if (!lock) + return -1; if (mnt_lock_file(lock) == -1) { - fprintf(stderr, "%d: failed to create lock file: %s\n", - getpid(), lockfile); + fprintf(stderr, "%d: failed to lock %s file\n", + getpid(), datafile); return -1; } @@ -518,7 +528,7 @@ int test_lock(struct mtest *ts, int argc, char *argv[]) int main(int argc, char *argv[]) { struct mtest tss[] = { - { "--lock", test_lock, " [--verbose] increment number in datafile" }, + { "--lock", test_lock, " [--verbose] increment number in datafile" }, { NULL } }; -- cgit v1.2.3-55-g7522