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 _______________________________________________ Mongrel-users mailing list Mongrel-users@rubyforge.org http://rubyforge.org/mailman/listinfo/mongrel-users