libcontainer/system/proc: Add Stat and Stat_t
So we can extract more than the start time with a single read. Signed-off-by: W. Trevor King <wking@tremily.us>
This commit is contained in:
parent
c995ee407b
commit
439eaa3584
|
@ -1,23 +1,43 @@
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// look in /proc to find the process start time so that we can verify
|
// Stat_t represents the information from /proc/[pid]/stat, as
|
||||||
// that this pid has started after ourself
|
// described in proc(5).
|
||||||
|
type Stat_t struct {
|
||||||
|
// StartTime is the number of clock ticks after system boot (since
|
||||||
|
// Linux 2.6).
|
||||||
|
StartTime uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat returns a Stat_t instance for the specified process.
|
||||||
|
func Stat(pid int) (stat Stat_t, err error) {
|
||||||
|
bytes, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
|
||||||
|
if err != nil {
|
||||||
|
return stat, err
|
||||||
|
}
|
||||||
|
data := string(bytes)
|
||||||
|
stat.StartTime, err = parseStartTime(data)
|
||||||
|
return stat, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProcessStartTime is deprecated. Use Stat(pid) and
|
||||||
|
// Stat_t.StartTime instead.
|
||||||
func GetProcessStartTime(pid int) (string, error) {
|
func GetProcessStartTime(pid int) (string, error) {
|
||||||
data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
|
stat, err := Stat(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return parseStartTime(string(data))
|
return fmt.Sprintf("%d", stat.StartTime), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseStartTime(stat string) (string, error) {
|
func parseStartTime(stat string) (uint64, error) {
|
||||||
// the starttime is located at pos 22
|
// the starttime is located at pos 22
|
||||||
// from the man page
|
// from the man page
|
||||||
//
|
//
|
||||||
|
@ -39,5 +59,8 @@ func parseStartTime(stat string) (string, error) {
|
||||||
// get parts after last `)`:
|
// get parts after last `)`:
|
||||||
s := strings.Split(stat, ")")
|
s := strings.Split(stat, ")")
|
||||||
parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
|
parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
|
||||||
return parts[22-3], nil // starts at 3 (after the filename pos `2`)
|
startTimeString := parts[22-3] // starts at 3 (after the filename pos `2`)
|
||||||
|
var startTime uint64
|
||||||
|
fmt.Sscanf(startTimeString, "%d", &startTime)
|
||||||
|
return startTime, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ package system
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestParseStartTime(t *testing.T) {
|
func TestParseStartTime(t *testing.T) {
|
||||||
data := map[string]string{
|
data := map[string]uint64{
|
||||||
"4902 (gunicorn: maste) S 4885 4902 4902 0 -1 4194560 29683 29929 61 83 78 16 96 17 20 0 1 0 9126532 52965376 1903 18446744073709551615 4194304 7461796 140733928751520 140733928698072 139816984959091 0 0 16781312 137447943 1 0 0 17 3 0 0 9 0 0 9559488 10071156 33050624 140733928758775 140733928758945 140733928758945 140733928759264 0": "9126532",
|
"4902 (gunicorn: maste) S 4885 4902 4902 0 -1 4194560 29683 29929 61 83 78 16 96 17 20 0 1 0 9126532 52965376 1903 18446744073709551615 4194304 7461796 140733928751520 140733928698072 139816984959091 0 0 16781312 137447943 1 0 0 17 3 0 0 9 0 0 9559488 10071156 33050624 140733928758775 140733928758945 140733928758945 140733928759264 0": 9126532,
|
||||||
"9534 (cat) R 9323 9534 9323 34828 9534 4194304 95 0 0 0 0 0 0 0 20 0 1 0 9214966 7626752 168 18446744073709551615 4194304 4240332 140732237651568 140732237650920 140570710391216 0 0 0 0 0 0 0 17 1 0 0 0 0 0 6340112 6341364 21553152 140732237653865 140732237653885 140732237653885 140732237656047 0": "9214966",
|
"9534 (cat) R 9323 9534 9323 34828 9534 4194304 95 0 0 0 0 0 0 0 20 0 1 0 9214966 7626752 168 18446744073709551615 4194304 4240332 140732237651568 140732237650920 140570710391216 0 0 0 0 0 0 0 17 1 0 0 0 0 0 6340112 6341364 21553152 140732237653865 140732237653885 140732237653885 140732237656047 0": 9214966,
|
||||||
"24767 (irq/44-mei_me) S 2 0 0 0 -1 2129984 0 0 0 0 0 0 0 0 -51 0 1 0 8722075 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 1 50 1 0 0 0 0 0 0 0 0 0 0 0": "8722075",
|
"24767 (irq/44-mei_me) S 2 0 0 0 -1 2129984 0 0 0 0 0 0 0 0 -51 0 1 0 8722075 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 1 50 1 0 0 0 0 0 0 0 0 0 0 0": 8722075,
|
||||||
}
|
}
|
||||||
for line, startTime := range data {
|
for line, startTime := range data {
|
||||||
st, err := parseStartTime(line)
|
st, err := parseStartTime(line)
|
||||||
|
|
Loading…
Reference in New Issue