zrepl/zfs/zfscmd/zfscmd_report.go
Christian Schwarz aed6149c8c zfscmd: fix crash in zfscmd_prometheus.go due to incorrectly extracted ProcessState
fixup of 96e188d7c4
refs #196
refs #301

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x9a472a]

goroutine 15826 [running]:
os.(*ProcessState).systemTime(...)
        /home/cs/go1.13/src/os/exec_unix.go:98
os.(*ProcessState).SystemTime(...)
        /home/cs/go1.13/src/os/exec.go:141
github.com/zrepl/zrepl/zfs/zfscmd.waitPostPrometheus(0xc000c04800, 0xe21ce0, 0xc000068270, 0xbf9f80d88107e861, 0x19bae710e6, 0x13a8b60)
        /home/cs/zrepl/zrepl/zfs/zfscmd/zfscmd_prometheus.go:69 +0x22a
github.com/zrepl/zrepl/zfs/zfscmd.(*Cmd).waitPost(0xc000c04800, 0xe21ce0, 0xc000068270)
        /home/cs/zrepl/zrepl/zfs/zfscmd/zfscmd.go:155 +0x18a
github.com/zrepl/zrepl/zfs/zfscmd.(*Cmd).CombinedOutput(0xc000c04800, 0xc0004b8270, 0xd02eea, 0x3, 0xc0001f6c40, 0x3)
        /home/cs/zrepl/zrepl/zfs/zfscmd/zfscmd.go:40 +0xb3
github.com/zrepl/zrepl/zfs.ZFSRelease(0xe36aa0, 0xc0004b8270, 0xc0009a3a40, 0x13, 0xc0004a5d00, 0x1, 0x1, 0xed62eb221, 0x13a8b60)
        /home/cs/zrepl/zrepl/zfs/holds.go:102 +0x2a7
github.com/zrepl/zrepl/endpoint.ReleaseStep(0xe36aa0, 0xc0004b8270, 0xc0004befc0, 0xe, 0xd08482, 0x8, 0xc0001cb02f, 0x2, 0x1eeea3bff89dc90b, 0x134d6, ...)
        /home/cs/zrepl/zrepl/endpoint/endpoint_zfs_abstraction_step.go:130 +0x367
github.com/zrepl/zrepl/endpoint.(*Sender).SendCompleted.func2(0xc000459190, 0xc000390e30, 0xc00041fd80, 0xc0004befc0, 0xe, 0xd08482, 0x8, 0xc0001cb02f, 0x2, 0x1eeea3bff89dc90b, ...)
        /home/cs/zrepl/zrepl/endpoint/endpoint.go:419 +0x1c3
created by github.com/zrepl/zrepl/endpoint.(*Sender).SendCompleted
        /home/cs/zrepl/zrepl/endpoint/endpoint.go:413 +0x776
2020-04-21 14:10:25 +02:00

69 lines
1.1 KiB
Go

package zfscmd
import (
"fmt"
"sync"
"time"
)
type Report struct {
Active []ActiveCommand
}
type ActiveCommand struct {
Path string
Args []string
StartedAt time.Time
}
func GetReport() *Report {
active.mtx.RLock()
defer active.mtx.RUnlock()
var activeCommands []ActiveCommand
for c := range active.cmds {
c.mtx.RLock()
activeCommands = append(activeCommands, ActiveCommand{
Path: c.cmd.Path,
Args: c.cmd.Args,
StartedAt: c.startedAt,
})
c.mtx.RUnlock()
}
return &Report{
Active: activeCommands,
}
}
var active struct {
mtx sync.RWMutex
cmds map[*Cmd]bool
}
func init() {
active.cmds = make(map[*Cmd]bool)
}
func startPostReport(c *Cmd, err error, now time.Time) {
if err != nil {
return
}
active.mtx.Lock()
prev := active.cmds[c]
if prev {
panic("impl error: duplicate active command")
}
active.cmds[c] = true
active.mtx.Unlock()
}
func waitPostReport(c *Cmd, _ usage, now time.Time) {
active.mtx.Lock()
defer active.mtx.Unlock()
prev := active.cmds[c]
if !prev {
panic(fmt.Sprintf("impl error: onWaitDone must only be called on an active command: %s", c))
}
delete(active.cmds, c)
}