Daniel Gies
2009-Sep-11 17:03 UTC
[Mongrel] Patch to fix mongrel_service bugs with Windows Vista/2008 support and log file location
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
Luis Lavena
2009-Sep-11 17:20 UTC
[Mongrel] Patch to fix mongrel_service bugs with Windows Vista/2008 support and log file location
On Fri, Sep 11, 2009 at 7:03 PM, Daniel Gies <daniel_gies at bigfix.com> wrote:> 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.Hello Daniel, Thank you for your patches! I''ll have to invest on mongrel_service the upcoming week to fix this issue and integrate other pull request at GitHub repository. While I can do manually, would you mind review your patches against mongrel_service repository at GitHub? http://github.com/fauna/mongrel_service Either way, I''m going to take care of this. Thank you once again for your contributions. -- Luis Lavena AREA 17 - Perfection in design is achieved not when there is nothing more to add, but rather when there is nothing more to take away. Antoine de Saint-Exup?ry
James Tucker
2009-Sep-11 18:16 UTC
[Mongrel] Patch to fix mongrel_service bugs with Windows Vista/2008 support and log file location
On 11 Sep 2009, at 18:20, Luis Lavena wrote:> On Fri, Sep 11, 2009 at 7:03 PM, Daniel Gies > <daniel_gies at bigfix.com> wrote: >> 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. > > Hello Daniel, > > Thank you for your patches! > > I''ll have to invest on mongrel_service the upcoming week to fix this > issue and integrate other pull request at GitHub repository. > > While I can do manually, would you mind review your patches against > mongrel_service repository at GitHub? > > http://github.com/fauna/mongrel_service > > Either way, I''m going to take care of this. > > Thank you once again for your contributions.Hey Luis, Just thought I''d mention, I''ve got some (very simple) service wrappers using win32-service in http://libraggi.rubyforge.org/ these days, and the codes are up on my github. I know those libs used to be a problem for us, but combined with the rubyw_helper they are very stable these days (in production in a couple of environments). Of course, there''s a side note that win32-service depends on libs that compile with windows system error handling extensions, which won''t build on mingw (gcc specifically), so some of the dependencies have to be gem installed with --platform x86-mswin32 for the prebuilds. You may not be willing to switch over, given the above, and that the freebasic wrappers have been working well for such a long time, but I thought I''d mention it. Regards, James> -- > Luis Lavena > AREA 17 > - > Perfection in design is achieved not when there is nothing more to > add, > but rather when there is nothing more to take away. > Antoine de Saint-Exup?ry > _______________________________________________ > Mongrel-users mailing list > Mongrel-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/mongrel-users