#!/bin/sh # The next line restarts using tclsh. \ exec tclsh "$0" "$@" # $Id: kill-nsd.tcl,v 1.5 2004/07/22 08:20:11 andy Exp $ # by Andrew Piskorski set nsd_pname {nsd} set nsd_log_dir {C:/nsd4-dtk/log} # Probably we want this to be a bit longer than the current ns_param # shutdowntimeout of 5 s: set stop_kill_pause_ms 6000 # Defined by Windows version of AOLserver (see code for the -I switch): set win_serv_prefix {AOLserver-} # Defined by virtual server name in ../nsd.tcl config file: set nsd_server {TODO-YOUR-SERVER-NAME-HERE} set nsd_service "${win_serv_prefix}${nsd_server}" set this_script [file tail $argv0] set USAGE " Usage: $this_script { start | stop | restart } Description: Starts and stops the $nsd_service Window Service. " global tcl_platform if { ![string equal $tcl_platform(platform) {windows}] } { puts $USAGE error "This script is for use on Windows only, not on: $tcl_platform(platform)" } if { [llength $argv] == 0 || [regexp {^-+[hH?]} [lindex $argv 0]] } { puts $USAGE return } proc dtk_log {severity proc_name mesg} { puts "${severity}: ${proc_name}: ${mesg}" } proc dtk_ok_kill_file {nsd_service} { global nsd_log_dir return "${nsd_log_dir}/ok-kill-${nsd_service}.txt" } # TODO: For killing the AOLserver process, we would like to use: # package require twapi # twapi::get_process_ids -name {nsd.exe} # twapi::end_process $nsd_pid -force -wait 7000 # but the 'twapi::get_process_ids -name' calls twapi::get_process_name # on every process, which is excruciatingly slow. # --atp@piskorski.com, 2004/07/15 18:44 EDT proc dtk_killall {pname} { # Kill processes by name: # This REQUIRES that PsTools from # "http://www.sysinternals.com/ntw2k/freeware/pstools.shtml" be # installed and in the system Path: # pskill appears to always write to stderr and thus always get # caught here: catch { set msg [exec pskill $pname] } msg return $msg } proc dtk_pause {ms} { puts "" dtk_log Notice {dtk_pause} "Pausing for [expr {$ms /1000.0}] seconds..." after $ms } proc dtk_nsd_kill {nsd_pname nsd_service} { set proc_name {dtk_nsd_kill} dtk_log Notice $proc_name "Killing all '$nsd_pname' processes now..." puts "" ; puts [dtk_killall $nsd_pname] set ok_kill_file [dtk_ok_kill_file $nsd_service] if { [file exists $ok_kill_file] } { # Give the Windows Service Control Manager to run # dtk_nsd_recover before deleting the file: dtk_pause 4000 file delete $ok_kill_file } } proc dtk_nsd_stop {nsd_service nsd_pname} { set proc_name {dtk_nsd_stop} dtk_log Notice $proc_name "Stopping Windows Service now: $nsd_service" catch { set msg [exec psservice stop $nsd_service] } msg puts $msg } proc dtk_nsd_start {nsd_service} { set proc_name {dtk_nsd_start} dtk_log Notice $proc_name "Starting Windows Service now: $nsd_service" catch { set msg [exec psservice start $nsd_service] } msg puts $msg } proc dtk_nsd_recover {nsd_service} { set proc_name {dtk_nsd_recover} # We set the Windows Service Control Manager to run this whenever # the Service dies unexpectedly - which unfortunately includes when # we purposely kill it. Therefore, dtk_nsd_recover must check # some external persistent state to indicate whether we WANTED the # service to die or not - we use the $ok_kill_file set by # dtk_nsd_kill and dtk_nsd_stop: --atp@piskorski.com, 2004/07/22 # 02:55 EDT set ok_kill_file [dtk_ok_kill_file $nsd_service] if { [file exists $ok_kill_file] && (([clock seconds] - [file mtime $ok_kill_file]) < 60) } { set restart_p 0 } else { set restart_p 1 } if { $restart_p } { dtk_nsd_start $nsd_service } else { dtk_log Notice $proc_name "NOT starting $nsd_service because: $ok_kill_file" } } set proc_name $this_script foreach do $argv { switch -exact -- $do { start - start-nsd { dtk_nsd_start $nsd_service } stop - stop-nsd { dtk_nsd_stop $nsd_service $nsd_pname # Because of Bug #772649, AOLserver will often hang during # shutdown, so we need to kill it: # http://sourceforge.net/tracker/?func=detail&aid=772649&group_id=3152&atid=103152 # --atp@piskorski.com, 2004/07/15 20:00 EDT package require fileutil ::fileutil::touch [dtk_ok_kill_file $nsd_service] dtk_pause $stop_kill_pause_ms dtk_nsd_kill $nsd_pname $nsd_service } stop-no-kill { dtk_nsd_stop $nsd_service $nsd_pname } restart - restart-nsd { dtk_nsd_stop $nsd_service $nsd_pname package require fileutil ::fileutil::touch [dtk_ok_kill_file $nsd_service] dtk_pause $stop_kill_pause_ms dtk_nsd_kill $nsd_pname $nsd_service dtk_nsd_start $nsd_service } kill - kill-nsd { dtk_nsd_kill $nsd_pname $nsd_service } p { dtk_pause 3000 } recover { dtk_nsd_recover $nsd_service } default { dtk_log Error $proc_name "Bogus command: $do" } }}