Update procfs library (#1640)
Bump procfs to latest release. Fixes: https://github.com/prometheus/node_exporter/issues/1625 Fixes: https://github.com/prometheus/node_exporter/issues/1634 Signed-off-by: Ben Kochie <superq@gmail.com>pull/1621/head
parent
e49a13d0cf
commit
47610d0d2b
@ -1,4 +1,4 @@ |
||||
--- |
||||
linters: |
||||
enable: |
||||
- staticcheck |
||||
- govet |
||||
- golint |
||||
|
||||
@ -0,0 +1,208 @@ |
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package procfs |
||||
|
||||
import ( |
||||
"bufio" |
||||
"fmt" |
||||
"os" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"golang.org/x/sys/unix" |
||||
) |
||||
|
||||
type ProcMapPermissions struct { |
||||
// mapping has the [R]ead flag set
|
||||
Read bool |
||||
// mapping has the [W]rite flag set
|
||||
Write bool |
||||
// mapping has the [X]ecutable flag set
|
||||
Execute bool |
||||
// mapping has the [S]hared flag set
|
||||
Shared bool |
||||
// mapping is marked as [P]rivate (copy on write)
|
||||
Private bool |
||||
} |
||||
|
||||
// ProcMap contains the process memory-mappings of the process,
|
||||
// read from /proc/[pid]/maps
|
||||
type ProcMap struct { |
||||
// The start address of current mapping.
|
||||
StartAddr uintptr |
||||
// The end address of the current mapping
|
||||
EndAddr uintptr |
||||
// The permissions for this mapping
|
||||
Perms *ProcMapPermissions |
||||
// The current offset into the file/fd (e.g., shared libs)
|
||||
Offset int64 |
||||
// Device owner of this mapping (major:minor) in Mkdev format.
|
||||
Dev uint64 |
||||
// The inode of the device above
|
||||
Inode uint64 |
||||
// The file or psuedofile (or empty==anonymous)
|
||||
Pathname string |
||||
} |
||||
|
||||
// parseDevice parses the device token of a line and converts it to a dev_t
|
||||
// (mkdev) like structure.
|
||||
func parseDevice(s string) (uint64, error) { |
||||
toks := strings.Split(s, ":") |
||||
if len(toks) < 2 { |
||||
return 0, fmt.Errorf("unexpected number of fields") |
||||
} |
||||
|
||||
major, err := strconv.ParseUint(toks[0], 16, 0) |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
|
||||
minor, err := strconv.ParseUint(toks[1], 16, 0) |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
|
||||
return unix.Mkdev(uint32(major), uint32(minor)), nil |
||||
} |
||||
|
||||
// parseAddress just converts a hex-string to a uintptr
|
||||
func parseAddress(s string) (uintptr, error) { |
||||
a, err := strconv.ParseUint(s, 16, 0) |
||||
if err != nil { |
||||
return 0, err |
||||
} |
||||
|
||||
return uintptr(a), nil |
||||
} |
||||
|
||||
// parseAddresses parses the start-end address
|
||||
func parseAddresses(s string) (uintptr, uintptr, error) { |
||||
toks := strings.Split(s, "-") |
||||
if len(toks) < 2 { |
||||
return 0, 0, fmt.Errorf("invalid address") |
||||
} |
||||
|
||||
saddr, err := parseAddress(toks[0]) |
||||
if err != nil { |
||||
return 0, 0, err |
||||
} |
||||
|
||||
eaddr, err := parseAddress(toks[1]) |
||||
if err != nil { |
||||
return 0, 0, err |
||||
} |
||||
|
||||
return saddr, eaddr, nil |
||||
} |
||||
|
||||
// parsePermissions parses a token and returns any that are set.
|
||||
func parsePermissions(s string) (*ProcMapPermissions, error) { |
||||
if len(s) < 4 { |
||||
return nil, fmt.Errorf("invalid permissions token") |
||||
} |
||||
|
||||
perms := ProcMapPermissions{} |
||||
for _, ch := range s { |
||||
switch ch { |
||||
case 'r': |
||||
perms.Read = true |
||||
case 'w': |
||||
perms.Write = true |
||||
case 'x': |
||||
perms.Execute = true |
||||
case 'p': |
||||
perms.Private = true |
||||
case 's': |
||||
perms.Shared = true |
||||
} |
||||
} |
||||
|
||||
return &perms, nil |
||||
} |
||||
|
||||
// parseProcMap will attempt to parse a single line within a proc/[pid]/maps
|
||||
// buffer.
|
||||
func parseProcMap(text string) (*ProcMap, error) { |
||||
fields := strings.Fields(text) |
||||
if len(fields) < 5 { |
||||
return nil, fmt.Errorf("truncated procmap entry") |
||||
} |
||||
|
||||
saddr, eaddr, err := parseAddresses(fields[0]) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
perms, err := parsePermissions(fields[1]) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
offset, err := strconv.ParseInt(fields[2], 16, 0) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
device, err := parseDevice(fields[3]) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
inode, err := strconv.ParseUint(fields[4], 10, 0) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
pathname := "" |
||||
|
||||
if len(fields) >= 5 { |
||||
pathname = strings.Join(fields[5:], " ") |
||||
} |
||||
|
||||
return &ProcMap{ |
||||
StartAddr: saddr, |
||||
EndAddr: eaddr, |
||||
Perms: perms, |
||||
Offset: offset, |
||||
Dev: device, |
||||
Inode: inode, |
||||
Pathname: pathname, |
||||
}, nil |
||||
} |
||||
|
||||
// ProcMaps reads from /proc/[pid]/maps to get the memory-mappings of the
|
||||
// process.
|
||||
func (p Proc) ProcMaps() ([]*ProcMap, error) { |
||||
file, err := os.Open(p.path("maps")) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
defer file.Close() |
||||
|
||||
maps := []*ProcMap{} |
||||
scan := bufio.NewScanner(file) |
||||
|
||||
for scan.Scan() { |
||||
m, err := parseProcMap(scan.Text()) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
maps = append(maps, m) |
||||
} |
||||
|
||||
return maps, nil |
||||
} |
||||
Loading…
Reference in new issue