From 86cd58706a4ce8909bf9c706dc9b808aeea4b295 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 13 Apr 2011 16:27:18 +0200 Subject: libmount: use libmnt_lock for utab flock Signed-off-by: Karel Zak --- shlibs/mount/src/context.c | 25 ++++++---- shlibs/mount/src/lock.c | 5 +- shlibs/mount/src/tab_update.c | 104 ++++++------------------------------------ 3 files changed, 32 insertions(+), 102 deletions(-) (limited to 'shlibs/mount/src') diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index eedb82345..1968a4b34 100644 --- a/shlibs/mount/src/context.c +++ b/shlibs/mount/src/context.c @@ -798,8 +798,9 @@ struct libmnt_cache *mnt_context_get_cache(struct libmnt_context *cxt) * small exception: the application has to be able to remove the lock file when * interrupted by signal or signals have to be ignored when the lock is locked. * - * The default behavior is to ignore all signals (except SIGALRM and SIGTRAP) - * when the lock is locked. If this behavior is unacceptable then use: + * The default behavior is to ignore all signals (except SIGALRM and + * SIGTRAP for mtab udate) when the lock is locked. If this behavior + * is unacceptable then use: * * lc = mnt_context_get_lock(cxt); * if (lc) @@ -807,18 +808,21 @@ struct libmnt_cache *mnt_context_get_cache(struct libmnt_context *cxt) * * and don't forget to call mnt_unlock_file(lc) before exit. * - * This function returns NULL if the lock is unnecessary (mtab file is not writable - * or /etc/mtab is symlink to /proc/mounts). - * * Returns: pointer to lock struct or NULL. */ struct libmnt_lock *mnt_context_get_lock(struct libmnt_context *cxt) { - if (!cxt || (cxt->flags & MNT_FL_NOMTAB) || !cxt->mtab_writable) + /* + * DON'T call this function within libmount, it will always allocate + * the lock. The mnt_update_* functions are able to allocate the lock + * only when mtab/utab update is really necessary. + */ + if (!cxt || (cxt->flags & MNT_FL_NOMTAB)) return NULL; - if (!cxt->lock && cxt->mtab_path) { - cxt->lock = mnt_new_lock(cxt->mtab_path, 0); + if (!cxt->lock) { + cxt->lock = mnt_new_lock(cxt->mtab_writable ? + cxt->mtab_path : cxt->utab_path, 0); if (cxt->lock) mnt_lock_block_signals(cxt->lock, TRUE); } @@ -1323,7 +1327,7 @@ int mnt_context_update_tabs(struct libmnt_context *cxt) mnt_update_force_rdonly(cxt->update, cxt->mountflags & MS_RDONLY); - return mnt_update_table(cxt->update, mnt_context_get_lock(cxt)); + return mnt_update_table(cxt->update, cxt->lock); } static int apply_table(struct libmnt_context *cxt, struct libmnt_table *tb, @@ -1610,6 +1614,9 @@ int test_mount(struct libmnt_test *ts, int argc, char *argv[]) mnt_context_set_target(cxt, argv[idx++]); } + /* this is unnecessary -- libmount is able to internaly + * create and manage the lock + */ lock = mnt_context_get_lock(cxt); if (lock) atexit(lock_fallback); diff --git a/shlibs/mount/src/lock.c b/shlibs/mount/src/lock.c index daf204496..53c1115ec 100644 --- a/shlibs/mount/src/lock.c +++ b/shlibs/mount/src/lock.c @@ -88,7 +88,7 @@ struct libmnt_lock *mnt_new_lock(const char *datafile, pid_t id) ml->linkfile = ln; ml->lockfile = lo; - DBG(LOCKS, mnt_debug_h(ml, "alloc: linkfile=%s, lockfile=%s", ln, lo)); + DBG(LOCKS, mnt_debug_h(ml, "alloc: default linkfile=%s, lockfile=%s", ln, lo)); return ml; err: free(lo); @@ -160,7 +160,7 @@ int mnt_lock_use_simplelock(struct libmnt_lock *ml, int enable) else if (!ml->simplelock && endswith(ml->lockfile, ".lock")) memcpy(ml->lockfile + sz - 5, "~", 2); - DBG(LOCKS, mnt_debug_h(ml, "lock filename: '%s'", ml->lockfile)); + DBG(LOCKS, mnt_debug_h(ml, "new lock filename: '%s'", ml->lockfile)); return 0; } @@ -234,6 +234,7 @@ static int lock_simplelock(struct libmnt_lock *ml) rc = -errsv; goto err; } + ml->locked = 1; return 0; err: if (ml->sigblock) diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c index 4822dffc5..d51464184 100644 --- a/shlibs/mount/src/tab_update.c +++ b/shlibs/mount/src/tab_update.c @@ -41,9 +41,6 @@ struct libmnt_update { unsigned long mountflags; int userspace_only; int ready; - - sigset_t oldsigmask; - int utab_lock; }; static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct libmnt_fs **ent); @@ -62,7 +59,6 @@ struct libmnt_update *mnt_new_update(void) if (!upd) return NULL; - upd->utab_lock = -1; DBG(UPDATE, mnt_debug_h(upd, "allocate")); return upd; } @@ -132,14 +128,13 @@ int mnt_update_set_filename(struct libmnt_update *upd, const char *filename, * mnt_update_get_filename: * @upd: update * - * This function returns file name (e.g. /etc/mtab) if the update - * should be covered by mnt_lock, otherwise returne NULL. + * This function returns file name (e.g. /etc/mtab) for the up-dated file. * * Returns: pointer to filename that will be updated or NULL in case of error. */ const char *mnt_update_get_filename(struct libmnt_update *upd) { - return upd && !upd->userspace_only ? upd->filename : NULL; + return upd ? upd->filename : NULL; } /** @@ -634,63 +629,6 @@ leave: return rc; } -static int utab_lock(struct libmnt_update *upd) -{ - char *lfile; - int rc; - sigset_t sigs; - - assert(upd); - assert(upd->filename); - assert(upd->userspace_only); - - if (asprintf(&lfile, "%s.lock", upd->filename) == -1) - return -1; - - DBG(UPDATE, mnt_debug("%s: locking", lfile)); - - sigemptyset(&upd->oldsigmask); - sigfillset(&sigs); - sigprocmask(SIG_BLOCK, &sigs, &upd->oldsigmask); - - upd->utab_lock = open(lfile, O_RDONLY|O_CREAT|O_CLOEXEC, S_IWUSR| - S_IRUSR|S_IRGRP|S_IROTH); - free(lfile); - - if (upd->utab_lock < 0) { - rc = -errno; - goto err; - } - - while (flock(upd->utab_lock, LOCK_EX) < 0) { - int errsv; - if ((errno == EAGAIN) || (errno == EINTR)) - continue; - errsv = errno; - close(upd->utab_lock); - upd->utab_lock = -1; - rc = -errsv; - goto err; - } - return 0; -err: - sigprocmask(SIG_SETMASK, &upd->oldsigmask, NULL); - return rc; -} - -static void utab_unlock(struct libmnt_update *upd) -{ - assert(upd); - assert(upd->userspace_only); - - if (upd->utab_lock >= 0) { - DBG(UPDATE, mnt_debug("unlocking utab")); - close(upd->utab_lock); - upd->utab_lock = -1; - sigprocmask(SIG_SETMASK, &upd->oldsigmask, NULL); - } -} - static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc) { struct libmnt_table *tb; @@ -701,9 +639,7 @@ static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc) DBG(UPDATE, mnt_debug_h(upd, "%s: add entry", upd->filename)); - if (upd->userspace_only) - rc = utab_lock(upd); - else if (lc) + if (lc) rc = mnt_lock_file(lc); if (rc) return rc; @@ -720,9 +656,7 @@ static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc) } } - if (upd->userspace_only) - utab_unlock(upd); - else if (lc) + if (lc) mnt_unlock_file(lc); mnt_free_table(tb); @@ -739,9 +673,7 @@ static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc DBG(UPDATE, mnt_debug_h(upd, "%s: remove entry", upd->filename)); - if (upd->userspace_only) - rc = utab_lock(upd); - else if (lc) + if (lc) rc = mnt_lock_file(lc); if (rc) return rc; @@ -757,9 +689,7 @@ static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc } } - if (upd->userspace_only) - utab_unlock(upd); - else if (lc) + if (lc) mnt_unlock_file(lc); mnt_free_table(tb); @@ -773,9 +703,7 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l DBG(UPDATE, mnt_debug_h(upd, "%s: modify target", upd->filename)); - if (upd->userspace_only) - rc = utab_lock(upd); - else if (lc) + if (lc) rc = mnt_lock_file(lc); if (rc) return rc; @@ -792,9 +720,7 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l } } - if (upd->userspace_only) - utab_unlock(upd); - else if (lc) + if (lc) mnt_unlock_file(lc); mnt_free_table(tb); @@ -814,9 +740,7 @@ static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock * fs = upd->fs; - if (upd->userspace_only) - rc = utab_lock(upd); - else if (lc) + if (lc) rc = mnt_lock_file(lc); if (rc) return rc; @@ -837,9 +761,7 @@ static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock * } } - if (upd->userspace_only) - utab_unlock(upd); - else if (lc) + if (lc) mnt_unlock_file(lc); mnt_free_table(tb); @@ -876,11 +798,13 @@ int mnt_update_table(struct libmnt_update *upd, struct libmnt_lock *lc) if (upd->fs) { DBG(UPDATE, mnt_fs_print_debug(upd->fs, stderr)); } - if (!lc && !upd->userspace_only) { + if (!lc) { lc = mnt_new_lock(upd->filename, 0); if (lc) mnt_lock_block_signals(lc, TRUE); } + if (lc && upd->userspace_only) + mnt_lock_use_simplelock(lc, TRUE); /* use flock */ if (!upd->fs && upd->target) rc = update_remove_entry(upd, lc); /* umount */ @@ -894,10 +818,8 @@ int mnt_update_table(struct libmnt_update *upd, struct libmnt_lock *lc) upd->ready = FALSE; DBG(UPDATE, mnt_debug_h(upd, "%s: update tab: done [rc=%d]", upd->filename, rc)); - if (lc != lc0) mnt_free_lock(lc); - return rc; } -- cgit v1.2.3-55-g7522