1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| package main
import (
"fmt"
"time"
"sage/sagecon/backup"
"sage/sagecon/core"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/eventlog"
)
const DEFAULT_SERVER_PORT = 9923
type myservices struct {
elog *eventlog.Log
backup_manager core.IBackup
}
func (m *myservices) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
service_panic := func(err interface{}) bool {
if err == nil {
return false
}
m.elog.Error(1, core.WrapError(fmt.Errorf("FATAL ERROR: %s", err)).Error())
return true
}
defer func() {
service_panic(recover())
}()
app, err := RunApp(core.MakeLog(m.elog), m.backup_manager, service_panic)
if err != nil {
m.elog.Error(1, err.Error())
changes <- svc.Status{State: svc.StopPending}
return
}
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:
for c := range r {
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
time.Sleep(100 * time.Millisecond)
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
break loop
case svc.Pause:
m.backup_manager.Pause()
app.do_pause()
changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
case svc.Continue:
m.backup_manager.Continue()
app.do_continue()
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
default:
m.elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
}
}
changes <- svc.Status{State: svc.StopPending}
m.backup_manager.Uninit()
app.listen_close()
app.do_continue()
changes <- svc.Status{State: svc.Stopped}
return
}
func RunService(name string) error {
elog, err := eventlog.Open(name)
if err != nil {
return core.WrapError(err)
}
defer elog.Close()
elog.Info(1, fmt.Sprintf("starting %s service", name))
err = svc.Run(name, &myservices{elog: elog, backup_manager: backup.MakeManager(core.MakeLog(elog))})
if err != nil {
err = core.WrapError(err)
elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
return err
}
elog.Info(1, fmt.Sprintf("%s service stopped", name))
return nil
} |
Partager