[Mongrel] Patch to fix mongrel_service bugs with Windows Vista/2008 support and log file location
Daniel Gies
daniel_gies at bigfix.com
Fri Sep 11 13:03:39 EDT 2009
Hello Mongrel users,
I¹m a software developer at BigFix ( http://www.bigfix.com ) and we use
Mongrel in one of our products. We have made changes to the mongrel_service
component to address problems outlined in Mongrel tickets 44 and 54:
http://mongrel.rubyforge.org/ticket/44
http://mongrel.rubyforge.org/ticket/54
The modifications are as follows:
Change the way mongrel_service detects its runtime environment to use a
method compliant with the Windows Vista security model. This modification
consists primarily of replacing elevated privilege code for process
inspection with a command-line argument.
Check for the ³-l² command line option and use that for the log file instead
of using a hard-coded location. The ³-P² option was not implemented.
In accordance with term 2.a of the Ruby License (
http://www.ruby-lang.org/en/LICENSE.txt ), we are making our changes freely
available to the open source community.
The patch is based off of root/branches/stable_1-2/projects/mongrel_service
as of 2009-09-10, also known as mongrel_service 0.35.
If you would prefer to receive the patch in an email attachment please let
me know.
The patch is included below:
diff -r -u old/CHANGELOG new/CHANGELOG
--- old/CHANGELOG 2008-04-18 07:09:00.000000000 -0700
+++ new/CHANGELOG 2009-09-10 11:39:13.000000000 -0700
@@ -1,3 +1,8 @@
+* BigFix *
+ * Fixed issue with Windows Server 208 support by replacing detection of
parent
+ process with checking first argument "single".
+ * The option "-l LOGFILE" works now
+
* 0.3.5 *
* Wait longer for child process terminate properly (max 20 seconds).
Imported
diff -r -u old/lib/ServiceFB/ServiceFB.bas new/lib/ServiceFB/ServiceFB.bas
--- old/lib/ServiceFB/ServiceFB.bas 2007-09-10 21:38:00.000000000 -0700
+++ new/lib/ServiceFB/ServiceFB.bas 2009-09-10 11:39:12.000000000 -0700
@@ -258,23 +258,25 @@
dim commandline as string
dim param_line as string
dim temp as string
+ dim logfile as string
_dprint("_main()")
'# debug dump of argc and argv
dim idx as integer = 0
+ dim argskip as integer = 0
for idx = 0 to (argc - 1)
_dprint(str(idx) + ": " + *argv[idx])
next idx
'# retrieve all the information (mode, service name and command
line
- _build_commandline(run_mode, service_name, commandline)
+ _build_commandline(run_mode, service_name, commandline, logfile,
argskip)
service = _find_in_references(service_name)
'# build parameter line (passed from SCM)
- if (argc > 1) then
+ if (argc > argskip) then
param_line = ""
- for idx = 1 to (argc - 1)
+ for idx = argskip to (argc - 1)
temp = *argv[idx]
if (instr(temp, chr(32)) > 0) then
param_line += """" + temp + """"
@@ -561,10 +563,11 @@
'# mode (if present)
'# valid service name (after lookup in the table)
'# command line to be passed to service
- sub _build_commandline(byref mode as string, byref service_name as
string, byref commandline as string)
+ sub _build_commandline(byref mode as string, byref service_name as
string, byref commandline as string, byref logfile as string, byref idxskip
as integer)
dim result_mode as string
dim result_name as string
dim result_cmdline as string
+ dim result_logfile as string
dim service as ServiceProcess ptr
dim idx as integer
dim temp as string
@@ -607,6 +610,17 @@
result_name = ""
end if
end if
+
+ '# check for log name
+ temp = command(idx)
+ if(temp = "-l") or (temp = "--log") then
+ idx += 1
+ result_logfile = command(idx)
+ idx += 1
+ end if
+ idxskip = idx
+
+ _dprint("_build_commandline():result_logfile = "+result_logfile)
result_cmdline = ""
@@ -628,6 +642,7 @@
mode = result_mode
service_name = result_name
commandline = result_cmdline
+ logfile = result_logfile
end sub
diff -r -u old/lib/ServiceFB/ServiceFB_Utils.bas
new/lib/ServiceFB/ServiceFB_Utils.bas
--- old/lib/ServiceFB/ServiceFB_Utils.bas 2008-04-17 18:59:00.000000000
-0700
+++ new/lib/ServiceFB/ServiceFB_Utils.bas 2009-09-10 11:39:12.000000000
-0700
@@ -80,27 +80,33 @@
dim start_mode as string
_dprint("ServiceController.RunMode()")
+
+ '#_dprint("Modified to always RunAsService")
+ '#result = RunAsService
+ '#return result
'# get this process PID
- currPID = GetCurrentProcessId()
- _dprint("CurrentPID: " + str(currPID))
+ '#currPID = GetCurrentProcessId()
+ '#_dprint("CurrentPID: " + str(currPID))
'# get the parent PID
- parent_pid = _parent_pid(currPID)
- _dprint("ParentPID: " + str(parent_pid))
+ '#parent_pid = _parent_pid(currPID)
+ '#_dprint("ParentPID: " + str(parent_pid))
'# now the the name
- parent_name = _process_name(parent_pid)
- if (parent_name = "<unknown>") then
- parent_name = _process_name_dyn_psapi(parent_pid)
- end if
- _dprint("Parent Name: " + parent_name)
+ '#parent_name = _process_name(parent_pid)
+ '#if (parent_name = "<unknown>") then
+ '# parent_name = _process_name_dyn_psapi(parent_pid)
+ '#end if
+ '#_dprint("Parent Name: " + parent_name)
+
+ _dprint("command: "+command)
'# this process started as service?
'# that means his parent is services.exe
- if (parent_name = "services.exe") then
- result = RunAsService
- else
+ '#if (parent_name = "services.exe") then
+ '# result = RunAsService
+ '#else
'# ok, it didn't start as service, analyze command line then
start_mode = lcase(trim(command(1)))
if (start_mode = "manage") then
@@ -109,12 +115,15 @@
elseif (start_mode = "console") then
'# start ServiceController.Console()
result = RunAsConsole
+ elseif (start_mode = "single") then
+ '# start ServiceController.Console()
+ result = RunAsService
else
'# ok, the first paramenter in the commandline didn't work,
'# report back so we could send the banner!
result = RunAsUnknown
end if
- end if
+ '#end if
_dprint("ServiceController.RunMode() done")
return result
@@ -146,6 +155,8 @@
dim service as ServiceProcess ptr
dim commandline as string
dim success as integer
+ dim logfile as string
+ dim argskip as integer
_dprint("ServiceController.Console()")
@@ -154,7 +165,7 @@
'# determine how many service exist in references
if (_svc_references_count > 0) then
- _build_commandline(run_mode, service_name, commandline)
+ _build_commandline(run_mode, service_name, commandline,
logfile, argskip)
service = _find_in_references(service_name)
if (service = 0) then
diff -r -u old/lib/ServiceFB/_internals.bi new/lib/ServiceFB/_internals.bi
--- old/lib/ServiceFB/_internals.bi 2007-06-01 22:22:00.000000000 -0700
+++ new/lib/ServiceFB/_internals.bi 2009-09-10 11:39:12.000000000 -0700
@@ -34,7 +34,7 @@
'# mode (if present)
'# valid service name (after lookup in the table)
'# command line to be passed to service
- declare sub _build_commandline(byref as string, byref as string, byref
as string)
+ declare sub _build_commandline(byref as string, byref as string, byref
as string, byref as string, byref as integer)
'# I started this as simple, unique service served from one process
'# but the idea of share the same process space (and reduce resources
use) was good.
diff -r -u old/lib/mongrel_service/init.rb new/lib/mongrel_service/init.rb
--- old/lib/mongrel_service/init.rb 2008-04-17 23:20:00.000000000 -0700
+++ new/lib/mongrel_service/init.rb 2009-09-10 11:39:12.000000000 -0700
@@ -112,6 +112,9 @@
:debug => @debug, :includes => ["mongrel"], :config_script =>
@config_script,
:num_procs => @num_procs, :timeout => @timeout, :cpu => @cpu,
:prefix => @prefix
}
+
+
+ argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
# if we are using a config file, pass -c and -C to the service
instead of each start parameter.
if @config_file
@@ -130,7 +133,6 @@
argv << "-e #{@options[:environment]}" if @options[:environment]
argv << "-p #{@options[:port]}"
argv << "-a #{@options[:host]}" if @options[:host]
- argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
argv << "-P \"#{@options[:pid_file]}\""
argv << "-c \"#{@options[:cwd]}\"" if @options[:cwd]
argv << "-t #{@options[:timeout]}" if @options[:timeout]
diff -r -u old/native/mongrel_service.bas new/native/mongrel_service.bas
--- old/native/mongrel_service.bas 2007-09-24 05:57:00.000000000 -0700
+++ new/native/mongrel_service.bas 2009-09-10 11:39:13.000000000 -0700
@@ -6,7 +6,7 @@
'# Copyright (c) 2006 Multimedia systems
'# (c) and code by Luis Lavena
'#
-'# mongrel_service (native) and mongrel_service gem_pluing are licensed
+'# mongrel_service (native) and mongrel_service gem_plugin are licensed
'# in the same terms as mongrel, please review the mongrel license at
'# http://mongrel.rubyforge.org/license.html
'#
@@ -23,8 +23,17 @@
#include once "_debug.bi"
namespace mongrel_service
+
constructor SingleMongrel()
- dim redirect_file as string
+ dim redirect_file as string = EXEPATH + "\mongrel.test.log"
+ dim flag as string
+
+ if(len(command) > 2) then
+ flag = command(2)
+ if(flag = "-l") or (flag = "--log") then
+ redirect_file = command(3)
+ end if
+ end if
with this.__service
.name = "single"
@@ -40,7 +49,6 @@
end with
with this.__console
- redirect_file = EXEPATH + "\mongrel.log"
debug("redirecting to: " + redirect_file)
.redirect(ProcessStdBoth, redirect_file)
end with
@@ -68,6 +76,7 @@
'# due lack of inheritance, we use single_mongrel_ref as pointer to
'# SingleMongrel instance. now we should call StillAlive
+
self.StillAlive()
if (len(self.commandline) > 0) then
'# assign the program
@@ -149,11 +158,13 @@
end sub
sub application()
+
dim simple as SingleMongrel
dim host as ServiceHost
dim ctrl as ServiceController = ServiceController("Mongrel Win32
Service", "version " + VERSION, _
"(c) 2006 The
Mongrel development team.")
+
'# add SingleMongrel (service)
host.Add(simple.__service)
select case ctrl.RunMode()
diff -r -u old/native/mongrel_service.bi new/native/mongrel_service.bi
--- old/native/mongrel_service.bi 2007-09-24 05:57:00.000000000 -0700
+++ new/native/mongrel_service.bi 2009-09-10 11:39:13.000000000 -0700
@@ -43,6 +43,7 @@
'# SingleMongrel
type SingleMongrel
+
declare constructor()
declare destructor()
@@ -54,6 +55,7 @@
__service as ServiceProcess
__console as ConsoleProcess
__child_pid as uinteger
+ __log_file as string
end type
'# TODO: replace with inheritance here
More information about the Mongrel-users
mailing list