Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4:Update
autofs
autofs-5.0.6-fix-submount-shutdown-race.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File autofs-5.0.6-fix-submount-shutdown-race.patch of Package autofs
commit 96bdf5342ffbdb5c62daa6095f0d9ae7f4b37a58 Author: Ian Kent <ikent@redhat.com> Date: Thu Dec 1 15:27:17 2011 +0800 autofs-5.0.6 - fix submount shutdown race Shutdown of submounts is problematic because the kernel doesn't know when they are going away and so cannot block path walks while they shut down. After aquiring the locks that cause mount requests to wait, the daemon checks if the submount is active before finally umounting it. If the mount is found to be busy the shutdown is abandoned and the submount returned to a ready state. But, if a mount request arrives at the same time as the daemon is attempting to aquire these locks pthreads appears to become confused and blocks. So change to using the try version of the lock call and handling the return appropriately. Index: autofs-5.0.5/CHANGELOG =================================================================== --- autofs-5.0.5.orig/CHANGELOG +++ autofs-5.0.5/CHANGELOG @@ -87,6 +87,7 @@ - fix fix LDAP result leaks on error paths. - code analysis fixes part 1. - fix wait for master source mutex. +- fix submount shutdown race. 03/09/2009 autofs-5.0.5 ----------------------- Index: autofs-5.0.5/daemon/automount.c =================================================================== --- autofs-5.0.5.orig/daemon/automount.c +++ autofs-5.0.5/daemon/automount.c @@ -1495,6 +1495,41 @@ static void handle_mounts_cleanup(void * return; } +static int submount_source_writelock_nested(struct autofs_point *ap) +{ + struct autofs_point *parent = ap->parent; + int status; + + status = pthread_rwlock_trywrlock(&parent->entry->source_lock); + if (status) + goto done; + + mounts_mutex_lock(parent); + + status = pthread_rwlock_trywrlock(&ap->entry->source_lock); + if (status) { + mounts_mutex_unlock(parent); + master_source_unlock(parent->entry); + } + +done: + if (status && status != EBUSY) { + logmsg("submount nested master_mapent source write lock failed"); + fatal(status); + } + + return status; +} + +static void submount_source_unlock_nested(struct autofs_point *ap) +{ + struct autofs_point *parent = ap->parent; + + master_source_unlock(ap->entry); + mounts_mutex_unlock(parent); + master_source_unlock(parent->entry); +} + void *handle_mounts(void *arg) { struct startup_cond *suc; @@ -1562,23 +1597,32 @@ void *handle_mounts(void *arg) master_mutex_lock(); if (ap->submount) { - master_source_writelock(ap->parent->entry); - mounts_mutex_lock(ap->parent); - } - - master_source_writelock(ap->entry); + /* + * If a mount request arrives before the locks are + * aquired just return to ready state. + */ + ret = submount_source_writelock_nested(ap); + if (ret) { + warn(ap->logopt, + "can't shutdown submount: mount in progress"); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); + master_mutex_unlock(); + pthread_setcancelstate(cur_state, NULL); + continue; + } + } else + master_source_writelock(ap->entry); if (ap->state != ST_SHUTDOWN) { if (!ap->submount) alarm_add(ap, ap->exp_runfreq); /* Return to ST_READY is done immediately */ st_add_task(ap, ST_READY); - master_source_unlock(ap->entry); - if (ap->submount) { - mounts_mutex_unlock(ap->parent); - master_source_unlock(ap->parent->entry); - } - + if (ap->submount) + submount_source_unlock_nested(ap); + else + master_source_unlock(ap->entry); master_mutex_unlock(); pthread_setcancelstate(cur_state, NULL); @@ -1618,12 +1662,10 @@ void *handle_mounts(void *arg) alarm_add(ap, ap->exp_runfreq); /* Return to ST_READY is done immediately */ st_add_task(ap, ST_READY); - master_source_unlock(ap->entry); - if (ap->submount) { - mounts_mutex_unlock(ap->parent); - master_source_unlock(ap->parent->entry); - } - + if (ap->submount) + submount_source_unlock_nested(ap); + else + master_source_unlock(ap->entry); master_mutex_unlock(); pthread_setcancelstate(cur_state, NULL);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor