summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsersut <serdar@opscode.com>2013-10-25 04:11:58 -0700
committersersut <serdar@opscode.com>2013-10-25 04:11:58 -0700
commitbe67ca1217fde4fce8f1d94870fc0c8d4ec943d7 (patch)
tree8e4882fc5dffc936b20909ebeaa20957037037e6
parent667f072ac6eb764d39708aae2f304f031b98d0ce (diff)
downloadchef-be67ca1217fde4fce8f1d94870fc0c8d4ec943d7.tar.gz
Check before creating a new system mutex on windows.
This is needed when multiple user accounts are running chef-client on systems. This scenario is imminent when they configure chef to run as service on windows which by default runs as "Local System" and when they try to run chef client manually as Administrator. NOTE: Non-admin users do not wait on the run_lock but can create a run_lock if there is not one already.
-rw-r--r--lib/chef/client.rb6
-rw-r--r--lib/chef/win32/mutex.rb45
2 files changed, 33 insertions, 18 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 30b714cded..837f8ad432 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -471,6 +471,10 @@ class Chef
# === Returns
# true:: Always returns true.
def do_run
+ # Check for windows administrator rights incase they create an
+ # issue while trying to create / acquire run_lock.
+ do_windows_admin_check
+
runlock = RunLock.new(Chef::Config.lockfile)
runlock.acquire
# don't add code that may fail before entering this section to be sure to release lock
@@ -493,8 +497,6 @@ class Chef
Chef::Log.info("Starting Chef Run for #{node.name}")
run_started
- do_windows_admin_check
-
run_context = setup_run_context
converge(run_context)
diff --git a/lib/chef/win32/mutex.rb b/lib/chef/win32/mutex.rb
index b0a9ba210e..3ca0c97ef2 100644
--- a/lib/chef/win32/mutex.rb
+++ b/lib/chef/win32/mutex.rb
@@ -22,25 +22,10 @@ class Chef
module ReservedNames::Win32
class Mutex
include Chef::ReservedNames::Win32::API::Synchronization
- extend Chef::ReservedNames::Win32::API::Synchronization
def initialize(name)
@name = name
- # First check if there exists a mutex in the system with the
- # given name.
-
- # In the initial creation of the mutex initial_owner is set to
- # false so that mutex will not be acquired until someone calls
- # acquire.
- # In order to call "*W" windows apis, strings needs to be
- # encoded as wide strings.
- @handle = CreateMutexW(nil, false, name.to_wstring)
-
- # Fail early if we can't get a handle to the named mutex
- if @handle == 0
- Chef::Log.error("Failed to create system mutex with name'#{name}'")
- Chef::ReservedNames::Win32::Error.raise!
- end
+ create_system_mutex
end
attr_reader :handle
@@ -87,6 +72,34 @@ if the mutex is attempted to be acquired by other threads.")
Chef::ReservedNames::Win32::Error.raise!
end
end
+
+ private
+
+ def create_system_mutex
+ # First check if there exists a mutex in the system with the
+ # given name. We need only synchronize rights if a mutex is
+ # already created.
+ # InheritHandle is set to true so that subprocesses can
+ # inherit the ownership of the mutex.
+ @handle = OpenMutexW(SYNCHRONIZE, true, name.to_wstring)
+
+ if @handle == 0
+ # Mutext doesn't exist so create one.
+ # In the initial creation of the mutex initial_owner is set to
+ # false so that mutex will not be acquired until someone calls
+ # acquire.
+ # In order to call "*W" windows apis, strings needs to be
+ # encoded as wide strings.
+ @handle = CreateMutexW(nil, false, name.to_wstring)
+
+ # Looks like we can't create the mutex for some reason.
+ # Fail early.
+ if @handle == 0
+ Chef::Log.error("Failed to create system mutex with name'#{name}'")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ end
+ end
end
end
end