func (vs *VirtualServer) forceRestart() error { vs.status.Log(status.Verbose, "Forcing kill server %v.", vs.VirtualServerName) pid, err := util.ReadPidInt(vs.PidFile) if e.Contains(err, ErrNoSuchFile) { vs.status.Log(status.Verbose, "Server %v is about to restart. Pid file not found.", vs.VirtualServerName) err := vs.forceKill() if err != nil { msg := "Forcekill script failed in " + vs.VirtualServerName + " with error: " + err.Error() + ". Giving up restart server." msg += " Trace: " + e.Trace(e.Forward(err)) vs.status.Log(status.Verbose, msg) return nil } goto restart } else if err != nil { return e.Forward(err) } err = syscall.Kill(pid, 9) if err != nil { return e.Forward(err) } restart: err = vs.beforeStart() if err != nil { return e.Forward(err) } err = vs.restart() if err != nil { return e.Forward(err) } return nil }
func (d *Daemon) changePid() { pid, err := util.ReadPidInt(d.PidFile) if err != nil { d.pid = -1 return } if d.pid != pid { if d.pid >= 0 { d.status.LogAndEmail(status.Normal, "Pid "+d.DaemonName+" changed.", "Pid %v changed from %v to %v.", d.DaemonName, d.pid, pid) } d.pid = pid } }
func Init(d *Daemon) (monitors.Monitor, error) { pid, err := util.ReadPidInt(d.PidFile) if err != nil && !e.Contains(err, "no such file or directory") { return nil, e.Forward(err) } if d.DaemonName == "" { return nil, e.New("empty daemon name") } if d.RestartCmd == "" { return nil, e.New("empty restart command") } if d.RestartArgs == nil { return nil, e.New("restart arguments is invalid") } if d.PidFile == "" { return nil, e.New("empty pid file") } if d.Sleep <= 0 { return nil, e.New("sleep is equal or less than zero") } if d.Tries < 0 { return nil, e.New("tries is equal or less than zero") } if d.Prio < 0 { return nil, e.New("prio have to be greater or equal to zero") } if d.Queue == nil { return nil, e.New("invalid queue") } if d.ExecTimeout <= 0 { return nil, e.New("exectution timeout is greater than zero") } d.MonitorBase = base.New() d.pid = pid d.killMonitor = make(chan bool) d.running = true d.status = status.NewStatuses(d.DaemonName, d.Email, definitions.LengthStatusHistory, status.NewStatus, d.SendEvent, nil) d.fswatcher, err = fsnotify.NewWatcher() if err != nil { return nil, e.Forward(err) } go func() { F: for { select { case ev := <-d.fswatcher.Event: if ev == nil { //watcher closed return } if ev.Name != d.PidFile { continue F } if ev.IsDelete() { d.pid = -1 } else if !(ev.IsCreate() && ev.IsModify()) { continue F } d.changePid() case err := <-d.fswatcher.Error: if err != nil { d.status.Log(status.Verbose, "Pid file %v watcher error: %v", d.PidFile, e.Trace(e.Forward(err))) } } } }() err = d.fswatcher.Watch(filepath.Dir(d.PidFile)) if err != nil { return nil, e.Push(err, e.New("invalid pid file %v", d.PidFile)) } d.monitor() return d, nil }