On 30/09/10 22:48, Jason Wright wrote:
> On Thu, Sep 30, 2010 at 11:41 AM, Brice Figureau
> <[email protected]> wrote:
>> It should fix the 1) issue outlined above. I don't think it is the root
>> cause of your issue, but that's the best I could think about :(
>> So let's try if that fixes it, we might be lucky today :)
> 
> This doesn't seem to help.  :(

The following patch seems to fix the issue for me.

My understanding is that there is a bug in the handing of ruby Sync module. 
For some reasons it is possible for a thread to enter the read SH section 
while another thread is in the write EX
section. 

What happens then is that due to the properties of flock(2) the
exclusive OS file lock is then downgraded to a shared lock, and another
process can then enter the writelock method and write the file. The
first process still writes the same file and we get a file corruption.

My fix is to use mutexes instead of a read/write lock. This might reduce 
the concurrency, but I sincerely doubt it would affect performance.

diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb
index 8b194ed..629de3e 100644
--- a/lib/puppet/util/file_locking.rb
+++ b/lib/puppet/util/file_locking.rb
@@ -1,12 +1,23 @@
 require 'puppet/util'
+require 'thread'
+require 'monitor'
 
 module Puppet::Util::FileLocking
   module_function
 
+  @@mutexes = {}.extend(MonitorMixin)
+
+  def mutex(resource)
+    @@mutexes.synchronize do
+      @@mutexes[resource] ||= Mutex.new
+      @@mutexes[resource]
+    end
+  end
+
   # Create a shared lock for reading
   def readlock(file)
     raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or 
File.file?(file)
-    Puppet::Util.sync(file).synchronize(Sync::SH) do
+    mutex(file).synchronize do
       File.open(file) { |f|
         f.lock_shared { |lf| yield lf }
       }
@@ -33,7 +44,7 @@ module Puppet::Util::FileLocking
       end
     end
 
-    Puppet::Util.sync(file).synchronize(Sync::EX) do
+    mutex(file).synchronize do
       File.open(file, "w", mode) do |rf|
         rf.lock_exclusive do |lrf|
           yield lrf

Jason, can you confirm it works for you?
I'll open a ticket over the week-end to summarize my findings.
-- 
Brice Figureau
My Blog: http://www.masterzen.fr/

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to