Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions containers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,22 +485,22 @@ func (c *Container) ensureProcess(pid uint32) *Process {
func (c *Container) onProcessStart(pid uint32) *Process {
c.lock.Lock()
defer c.lock.Unlock()
stats, err := TaskstatsPID(pid)
if err != nil {
startedAt := proc.GetStartTime(pid)
if startedAt.IsZero() {
return nil
}
c.zombieAt = time.Time{}
p := NewProcess(pid, stats, c.registry.tracer)
p := NewProcess(pid, startedAt, c.registry.tracer)

if p == nil {
return nil
}
c.processes[pid] = p

if c.startedAt.IsZero() {
c.startedAt = stats.BeginTime
c.startedAt = startedAt
} else {
min := stats.BeginTime
min := startedAt
for _, p := range c.processes {
if p.StartedAt.Before(min) {
min = p.StartedAt
Expand Down
5 changes: 2 additions & 3 deletions containers/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/coroot/coroot-node-agent/gpu"
"github.com/coroot/coroot-node-agent/proc"
"github.com/jpillora/backoff"
"github.com/mdlayher/taskstats"
)

type GpuUsage struct {
Expand Down Expand Up @@ -66,8 +65,8 @@ type inboundHttp2State struct {
connTimestamp uint64
}

func NewProcess(pid uint32, stats *taskstats.Stats, tracer *ebpftracer.Tracer) *Process {
p := &Process{Pid: pid, StartedAt: stats.BeginTime, tracer: tracer, instrumentDone: make(chan struct{})}
func NewProcess(pid uint32, startedAt time.Time, tracer *ebpftracer.Tracer) *Process {
p := &Process{Pid: pid, StartedAt: startedAt, tracer: tracer, instrumentDone: make(chan struct{})}
p.Flags, _ = proc.GetFlags(pid)
p.ctx, p.cancelFunc = context.WithCancel(context.Background())
go p.instrument(tracer)
Expand Down
13 changes: 0 additions & 13 deletions containers/taskstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,3 @@ func TaskstatsTGID(pid uint32) (*taskstats.Stats, error) {
}
return s, nil
}

func TaskstatsPID(pid uint32) (*taskstats.Stats, error) {
if taskstatsClient == nil {
return nil, fmt.Errorf("taskstats client not initialized")
}
taskstatsLock.Lock()
defer taskstatsLock.Unlock()
s, err := taskstatsClient.PID(int(pid))
if err != nil {
return nil, err
}
return s, nil
}
40 changes: 39 additions & 1 deletion proc/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,28 @@ import (
"path"
"strconv"
"strings"
"time"

"github.com/coroot/coroot-node-agent/cgroup"
)

var root = "/proc"
var (
root = "/proc"
bootTime int64
)

func init() {
data, err := os.ReadFile(root + "/stat")
if err != nil {
return
}
for _, line := range strings.Split(string(data), "\n") {
if fields := strings.Fields(line); len(fields) == 2 && fields[0] == "btime" {
bootTime, _ = strconv.ParseInt(fields[1], 10, 64)
return
}
}
}

func Path(pid uint32, subpath ...string) string {
return path.Join(append([]string{root, strconv.Itoa(int(pid))}, subpath...)...)
Expand Down Expand Up @@ -64,6 +81,27 @@ func ReadCgroup(pid uint32) (*cgroup.Cgroup, error) {
return cgroup.NewFromProcessCgroupFile(Path(pid, "cgroup"))
}

func GetStartTime(pid uint32) time.Time {
data, err := os.ReadFile(Path(pid, "stat"))
if err != nil {
return time.Time{}
}
s := string(data)
idx := strings.LastIndex(s, ")")
if idx < 0 {
return time.Time{}
}
fields := strings.Fields(s[idx+1:])
if len(fields) < 20 {
return time.Time{}
}
startTicks, err := strconv.ParseUint(fields[19], 10, 64)
if err != nil || bootTime == 0 {
return time.Time{}
}
return time.Unix(bootTime+int64(float64(startTicks)/100), 0)
}

func ListPids() ([]uint32, error) {
root, err := os.Open(root)
if err != nil {
Expand Down
Loading