예제 #1
0
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
}
예제 #2
0
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
	}
}
예제 #3
0
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
}