Initial commit
This commit is contained in:
181
main.go
Normal file
181
main.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
proc "github.com/shirou/gopsutil/v3/process"
|
||||
)
|
||||
|
||||
// main основная функция программы.
|
||||
func main() {
|
||||
if os.Getenv("HOME") == "" {
|
||||
log.Fatalln("Unable to get HOME environment variable value")
|
||||
}
|
||||
|
||||
cnf, err := readConf(os.Getenv("HOME") + "/.reniced.yaml")
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("unable to parse config: %s", err)
|
||||
}
|
||||
|
||||
// Основной цикл.
|
||||
for {
|
||||
processList, err := proc.Processes()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to get process list: %s", err)
|
||||
}
|
||||
|
||||
// Не самый эффективный, зато работающий способ - простой перебор массивов.
|
||||
for _, p := range processList {
|
||||
if processName, err := p.Name(); err == nil {
|
||||
for _, k := range cnf.Kill {
|
||||
for _, killProcessName := range k.Name {
|
||||
if processName == killProcessName {
|
||||
switch k.Sig {
|
||||
case "kill":
|
||||
_ = p.SendSignal(syscall.SIGKILL)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "stop":
|
||||
if s, err := p.Status(); err == nil && s[0] != "stop" {
|
||||
_ = p.SendSignal(syscall.SIGSTOP)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
} else if err == nil && s[0] == "stop" && cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s) and it is already stopped",
|
||||
processName,
|
||||
)
|
||||
}
|
||||
case "term":
|
||||
_ = p.SendSignal(syscall.SIGTERM)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "int":
|
||||
_ = p.SendSignal(syscall.SIGINT)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "quit":
|
||||
_ = p.SendSignal(syscall.SIGQUIT)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "abrt":
|
||||
_ = p.SendSignal(syscall.SIGABRT)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "hup":
|
||||
_ = p.SendSignal(syscall.SIGHUP)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "usr1":
|
||||
_ = p.SendSignal(syscall.SIGUSR1)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
case "usr2":
|
||||
_ = p.SendSignal(syscall.SIGUSR2)
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Matching processName with killProcessname (%s), SIG%s sent",
|
||||
processName,
|
||||
strings.ToUpper(k.Sig),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Для каждого процесса извлекаем его текущий nicelevel.
|
||||
if currentNiceLevel, err := p.Nice(); err == nil {
|
||||
// Вынимаем список приоритетов.
|
||||
for _, n := range cnf.Prio {
|
||||
// Для каждого приоритета, проходимся по списку имён процессов.
|
||||
for _, name := range n.Name {
|
||||
// Достаём имя текущего процесса.
|
||||
if processName, err = p.Name(); err == nil {
|
||||
// Если имя процесса совпадает с одним из списка в конфиге, то пробуем менять ему nice.
|
||||
if processName == name {
|
||||
if currentNiceLevel != n.Nice {
|
||||
_ = syscall.Setpriority(syscall.PRIO_PROCESS, int(p.Pid), int(n.Nice))
|
||||
|
||||
if cnf.Debug {
|
||||
log.Printf(
|
||||
"Set niceness for %s(%d) to %d (was %d)",
|
||||
name,
|
||||
p.Pid,
|
||||
n.Nice,
|
||||
currentNiceLevel,
|
||||
)
|
||||
}
|
||||
} else if cnf.Debug {
|
||||
log.Printf("Nicelevel for %d already set to %d", p.Pid, n.Nice)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * time.Duration(cnf.CmdDelay))
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * time.Duration(cnf.LoopDelay))
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||
Reference in New Issue
Block a user