diff options
author | David Smith <dsmith@redhat.com> | 2010-01-08 13:26:47 -0600 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2010-01-08 13:26:47 -0600 |
commit | 50f2701f68c86e2ec2d03ec39ff6a9099f330c6f (patch) | |
tree | 252dfcf6cf5465fd846838476241991490ec57ab /runtime | |
parent | a5b173656a9d942921d59a3e02bf2f285a46a3e9 (diff) | |
download | systemtap-steved-50f2701f68c86e2ec2d03ec39ff6a9099f330c6f.tar.gz systemtap-steved-50f2701f68c86e2ec2d03ec39ff6a9099f330c6f.tar.xz systemtap-steved-50f2701f68c86e2ec2d03ec39ff6a9099f330c6f.zip |
Fixed PR 11148 by reworking transport directory locks.
* runtime/transport/transport.c (_stp_get_root_dir): No longer
locks/unlocks the transport directory.
(_stp_remove_root_dir): Ditto.
(_stp_transport_fs_init): Locks and unlocks the transport directory.
Ensures that the root directory can't be deleted between calling
_stp_get_root_dir() and creating the module dir.
(_stp_transport_fs_close): Locks and unlocks the transport directory.
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/transport/transport.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index bab5efa9..2d84bc0c 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -322,6 +322,7 @@ static struct dentry *_stp_lockfile = NULL; static int _stp_lock_transport_dir(void) { int numtries = 0; + #if STP_TRANSPORT_VERSION == 1 while ((_stp_lockfile = relayfs_create_dir("systemtap_lock", NULL)) == NULL) { #else @@ -349,7 +350,10 @@ static void _stp_unlock_transport_dir(void) static struct dentry *__stp_root_dir = NULL; /* _stp_get_root_dir() - creates root directory or returns - * a pointer to it if it already exists. */ + * a pointer to it if it already exists. + * + * The caller *must* lock the transport directory. + */ static struct dentry *_stp_get_root_dir(void) { @@ -375,10 +379,6 @@ static struct dentry *_stp_get_root_dir(void) } #endif - if (!_stp_lock_transport_dir()) { - errk("Couldn't lock transport directory.\n"); - return NULL; - } #if STP_TRANSPORT_VERSION == 1 __stp_root_dir = relayfs_create_dir(name, NULL); #else @@ -406,17 +406,17 @@ static struct dentry *_stp_get_root_dir(void) -PTR_ERR(__stp_root_dir)); } - _stp_unlock_transport_dir(); return __stp_root_dir; } +/* _stp_remove_root_dir() - removes root directory (if empty) + * + * The caller *must* lock the transport directory. + */ + static void _stp_remove_root_dir(void) { if (__stp_root_dir) { - if (!_stp_lock_transport_dir()) { - errk("Unable to lock transport directory.\n"); - return; - } if (simple_empty(__stp_root_dir)) { #if STP_TRANSPORT_VERSION == 1 relayfs_remove_dir(__stp_root_dir); @@ -424,7 +424,6 @@ static void _stp_remove_root_dir(void) debugfs_remove(__stp_root_dir); #endif } - _stp_unlock_transport_dir(); __stp_root_dir = NULL; } } @@ -444,9 +443,16 @@ static int _stp_transport_fs_init(const char *module_name) if (module_name == NULL) return -1; + if (!_stp_lock_transport_dir()) { + errk("Couldn't lock transport directory.\n"); + return -1; + } + root_dir = _stp_get_root_dir(); - if (root_dir == NULL) + if (root_dir == NULL) { + _stp_unlock_transport_dir(); return -1; + } #if STP_TRANSPORT_VERSION == 1 __stp_module_dir = relayfs_create_dir(module_name, root_dir); @@ -457,19 +463,23 @@ static int _stp_transport_fs_init(const char *module_name) errk("Could not create module directory \"%s\"\n", module_name); _stp_remove_root_dir(); + _stp_unlock_transport_dir(); return -1; } else if (IS_ERR(__stp_module_dir)) { errk("Could not create module directory \"%s\", error %ld\n", module_name, -PTR_ERR(__stp_module_dir)); _stp_remove_root_dir(); + _stp_unlock_transport_dir(); return -1; } if (_stp_transport_data_fs_init() != 0) { _stp_remove_root_dir(); + _stp_unlock_transport_dir(); return -1; } + _stp_unlock_transport_dir(); dbug_trans(1, "returning 0\n"); return 0; } @@ -481,15 +491,21 @@ static void _stp_transport_fs_close(void) _stp_transport_data_fs_close(); if (__stp_module_dir) { + if (!_stp_lock_transport_dir()) { + errk("Couldn't lock transport directory.\n"); + return; + } + #if STP_TRANSPORT_VERSION == 1 relayfs_remove_dir(__stp_module_dir); #else debugfs_remove(__stp_module_dir); #endif __stp_module_dir = NULL; - } - _stp_remove_root_dir(); + _stp_remove_root_dir(); + _stp_unlock_transport_dir(); + } } |