Move deps from _workspace/ to vendor/

godep restore
pushd $GOPATH/src/github.com/appc/spec
git co master
popd
go get go4.org/errorutil
rm -rf Godeps
godep save ./...
git add vendor
git add -f $(git ls-files --other vendor/)
git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
This commit is contained in:
Tim Hockin
2016-05-08 20:30:21 -07:00
parent 899f9b4e31
commit 3c0c5ed4e0
4400 changed files with 16739 additions and 376 deletions

View File

@@ -0,0 +1,53 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package cloudinfo
import (
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
info "github.com/google/cadvisor/info/v1"
)
func onAWS() bool {
// the default client behavior retried the operation multiple times with a 5s timeout per attempt.
// if you were not on aws, you would block for 20s when invoking this operation.
// we reduce retries to 0 and set the timeout to 2s to reduce the time this blocks when not on aws.
client := ec2metadata.New(session.New(&aws.Config{MaxRetries: aws.Int(0)}))
if client.Config.HTTPClient != nil {
client.Config.HTTPClient.Timeout = time.Duration(2 * time.Second)
}
return client.Available()
}
func getAwsMetadata(name string) string {
client := ec2metadata.New(session.New(&aws.Config{}))
data, err := client.GetMetadata(name)
if err != nil {
return info.UnknownInstance
}
return data
}
func getAwsInstanceType() info.InstanceType {
return info.InstanceType(getAwsMetadata("instance-type"))
}
func getAwsInstanceID() info.InstanceID {
return info.InstanceID(getAwsMetadata("instance-id"))
}

View File

@@ -0,0 +1,48 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package cloudinfo
import (
info "github.com/google/cadvisor/info/v1"
"io/ioutil"
"strings"
)
const (
SysVendorFileName = "/sys/class/dmi/id/sys_vendor"
BiosUUIDFileName = "/sys/class/dmi/id/product_uuid"
MicrosoftCorporation = "Microsoft Corporation"
)
func onAzure() bool {
data, err := ioutil.ReadFile(SysVendorFileName)
if err != nil {
return false
}
return strings.Contains(string(data), MicrosoftCorporation)
}
//TODO: Implement method.
func getAzureInstanceType() info.InstanceType {
return info.UnknownInstance
}
func getAzureInstanceID() info.InstanceID {
data, err := ioutil.ReadFile(BiosUUIDFileName)
if err != nil {
return info.UnNamedInstance
}
return info.InstanceID(strings.TrimSuffix(string(data), "\n"))
}

View File

@@ -0,0 +1,103 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
// Get information about the cloud provider (if any) cAdvisor is running on.
package cloudinfo
import (
info "github.com/google/cadvisor/info/v1"
)
type CloudInfo interface {
GetCloudProvider() info.CloudProvider
GetInstanceType() info.InstanceType
GetInstanceID() info.InstanceID
}
type realCloudInfo struct {
cloudProvider info.CloudProvider
instanceType info.InstanceType
instanceID info.InstanceID
}
func NewRealCloudInfo() CloudInfo {
cloudProvider := detectCloudProvider()
instanceType := detectInstanceType(cloudProvider)
instanceID := detectInstanceID(cloudProvider)
return &realCloudInfo{
cloudProvider: cloudProvider,
instanceType: instanceType,
instanceID: instanceID,
}
}
func (self *realCloudInfo) GetCloudProvider() info.CloudProvider {
return self.cloudProvider
}
func (self *realCloudInfo) GetInstanceType() info.InstanceType {
return self.instanceType
}
func (self *realCloudInfo) GetInstanceID() info.InstanceID {
return self.instanceID
}
func detectCloudProvider() info.CloudProvider {
switch {
case onGCE():
return info.GCE
case onAWS():
return info.AWS
case onAzure():
return info.Azure
case onBaremetal():
return info.Baremetal
}
return info.UnknownProvider
}
func detectInstanceType(cloudProvider info.CloudProvider) info.InstanceType {
switch cloudProvider {
case info.GCE:
return getGceInstanceType()
case info.AWS:
return getAwsInstanceType()
case info.Azure:
return getAzureInstanceType()
case info.Baremetal:
return info.NoInstance
}
return info.UnknownInstance
}
func detectInstanceID(cloudProvider info.CloudProvider) info.InstanceID {
switch cloudProvider {
case info.GCE:
return getGceInstanceID()
case info.AWS:
return getAwsInstanceID()
case info.Azure:
return getAzureInstanceID()
case info.Baremetal:
return info.UnNamedInstance
}
return info.UnNamedInstance
}
//TODO: Implement method.
func onBaremetal() bool {
return false
}

View File

@@ -0,0 +1,45 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package cloudinfo
import (
"strings"
info "github.com/google/cadvisor/info/v1"
"google.golang.org/cloud/compute/metadata"
)
func onGCE() bool {
return metadata.OnGCE()
}
func getGceInstanceType() info.InstanceType {
machineType, err := metadata.Get("instance/machine-type")
if err != nil {
return info.UnknownInstance
}
responseParts := strings.Split(machineType, "/") // Extract the instance name from the machine type.
return info.InstanceType(responseParts[len(responseParts)-1])
}
func getGceInstanceID() info.InstanceID {
instanceID, err := metadata.Get("instance/id")
if err != nil {
return info.UnknownInstance
}
return info.InstanceID(info.InstanceType(instanceID))
}

View File

@@ -0,0 +1,31 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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.
package container
import (
info "github.com/google/cadvisor/info/v1"
)
// Returns the alias a container is known by within a certain namespace,
// if available. Otherwise returns the absolute name of the container.
func GetPreferredName(ref info.ContainerReference) string {
var containerName string
if len(ref.Aliases) > 0 {
containerName = ref.Aliases[0]
} else {
containerName = ref.Name
}
return containerName
}

View File

@@ -0,0 +1,46 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package cpuload
import (
"fmt"
info "github.com/google/cadvisor/info/v1"
"github.com/golang/glog"
"github.com/google/cadvisor/utils/cpuload/netlink"
)
type CpuLoadReader interface {
// Start the reader.
Start() error
// Stop the reader and clean up internal state.
Stop()
// Retrieve Cpu load for a given group.
// name is the full hierarchical name of the container.
// Path is an absolute filesystem path for a container under CPU cgroup hierarchy.
GetCpuLoad(name string, path string) (info.LoadStats, error)
}
func New() (CpuLoadReader, error) {
reader, err := netlink.New()
if err != nil {
return nil, fmt.Errorf("failed to create a netlink based cpuload reader: %v", err)
}
glog.Info("Using a netlink-based load reader")
return reader, nil
}

View File

@@ -0,0 +1,95 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package netlink
import (
"bufio"
"bytes"
"encoding/binary"
"os"
"syscall"
)
type Connection struct {
// netlink socket
fd int
// cache pid to use in every netlink request.
pid uint32
// sequence number for netlink messages.
seq uint32
addr syscall.SockaddrNetlink
rbuf *bufio.Reader
}
// Create and bind a new netlink socket.
func newConnection() (*Connection, error) {
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_GENERIC)
if err != nil {
return nil, err
}
conn := new(Connection)
conn.fd = fd
conn.seq = 0
conn.pid = uint32(os.Getpid())
conn.addr.Family = syscall.AF_NETLINK
conn.rbuf = bufio.NewReader(conn)
err = syscall.Bind(fd, &conn.addr)
if err != nil {
syscall.Close(fd)
return nil, err
}
return conn, err
}
func (self *Connection) Read(b []byte) (n int, err error) {
n, _, err = syscall.Recvfrom(self.fd, b, 0)
return n, err
}
func (self *Connection) Write(b []byte) (n int, err error) {
err = syscall.Sendto(self.fd, b, 0, &self.addr)
return len(b), err
}
func (self *Connection) Close() error {
return syscall.Close(self.fd)
}
func (self *Connection) WriteMessage(msg syscall.NetlinkMessage) error {
w := bytes.NewBuffer(nil)
msg.Header.Len = uint32(syscall.NLMSG_HDRLEN + len(msg.Data))
msg.Header.Seq = self.seq
self.seq++
msg.Header.Pid = self.pid
binary.Write(w, binary.LittleEndian, msg.Header)
_, err := w.Write(msg.Data)
if err != nil {
return err
}
_, err = self.Write(w.Bytes())
return err
}
func (self *Connection) ReadMessage() (msg syscall.NetlinkMessage, err error) {
err = binary.Read(self.rbuf, binary.LittleEndian, &msg.Header)
if err != nil {
return msg, err
}
msg.Data = make([]byte, msg.Header.Len-syscall.NLMSG_HDRLEN)
_, err = self.rbuf.Read(msg.Data)
return msg, err
}

View File

@@ -0,0 +1,26 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package netlink
/*
#include <linux/taskstats.h>
*/
import "C"
type TaskStats C.struct_taskstats
const (
__TASKSTATS_CMD_MAX = C.__TASKSTATS_CMD_MAX
)

View File

@@ -0,0 +1,40 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package main
import (
"log"
"github.com/google/cadvisor/utils/cpuload/netlink"
)
func main() {
n, err := netlink.New()
if err != nil {
log.Printf("Failed to create cpu load util: %s", err)
return
}
defer n.Stop()
paths := []string{"/sys/fs/cgroup/cpu", "/sys/fs/cgroup/cpu/docker"}
names := []string{"/", "/docker"}
for i, path := range paths {
stats, err := n.GetCpuLoad(names[i], path)
if err != nil {
log.Printf("Error getting cpu load for %q: %s", path, err)
}
log.Printf("Task load for %s: %+v", path, stats)
}
}

View File

@@ -0,0 +1,242 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package netlink
import (
"bytes"
"encoding/binary"
"fmt"
"os"
"syscall"
info "github.com/google/cadvisor/info/v1"
)
const (
// Kernel constants for tasks stats.
genlIdCtrl = syscall.NLMSG_MIN_TYPE // GENL_ID_CTRL
taskstatsGenlName = "TASKSTATS" // TASKSTATS_GENL_NAME
cgroupStatsCmdAttrFd = 0x1 // CGROUPSTATS_CMD_ATTR_FD
ctrlAttrFamilyId = 0x1 // CTRL_ATTR_FAMILY_ID
ctrlAttrFamilyName = 0x2 // CTRL_ATTR_FAMILY_NAME
ctrlCmdGetFamily = 0x3 // CTRL_CMD_GETFAMILY
)
var (
// TODO(rjnagal): Verify and fix for other architectures.
Endian = binary.LittleEndian
)
type genMsghdr struct {
Command uint8
Version uint8
Reserved uint16
}
type netlinkMessage struct {
Header syscall.NlMsghdr
GenHeader genMsghdr
Data []byte
}
func (self netlinkMessage) toRawMsg() (rawmsg syscall.NetlinkMessage) {
rawmsg.Header = self.Header
w := bytes.NewBuffer([]byte{})
binary.Write(w, Endian, self.GenHeader)
w.Write(self.Data)
rawmsg.Data = w.Bytes()
return rawmsg
}
type loadStatsResp struct {
Header syscall.NlMsghdr
GenHeader genMsghdr
Stats info.LoadStats
}
// Return required padding to align 'size' to 'alignment'.
func padding(size int, alignment int) int {
unalignedPart := size % alignment
return (alignment - unalignedPart) % alignment
}
// Get family id for taskstats subsystem.
func getFamilyId(conn *Connection) (uint16, error) {
msg := prepareFamilyMessage()
conn.WriteMessage(msg.toRawMsg())
resp, err := conn.ReadMessage()
if err != nil {
return 0, err
}
id, err := parseFamilyResp(resp)
if err != nil {
return 0, err
}
return id, nil
}
// Append an attribute to the message.
// Adds attribute info (length and type), followed by the data and necessary padding.
// Can be called multiple times to add attributes. Only fixed size and string type
// attributes are handled. We don't need nested attributes for task stats.
func addAttribute(buf *bytes.Buffer, attrType uint16, data interface{}, dataSize int) {
attr := syscall.RtAttr{
Len: syscall.SizeofRtAttr,
Type: attrType,
}
attr.Len += uint16(dataSize)
binary.Write(buf, Endian, attr)
switch data := data.(type) {
case string:
binary.Write(buf, Endian, []byte(data))
buf.WriteByte(0) // terminate
default:
binary.Write(buf, Endian, data)
}
for i := 0; i < padding(int(attr.Len), syscall.NLMSG_ALIGNTO); i++ {
buf.WriteByte(0)
}
}
// Prepares the message and generic headers and appends attributes as data.
func prepareMessage(headerType uint16, cmd uint8, attributes []byte) (msg netlinkMessage) {
msg.Header.Type = headerType
msg.Header.Flags = syscall.NLM_F_REQUEST
msg.GenHeader.Command = cmd
msg.GenHeader.Version = 0x1
msg.Data = attributes
return msg
}
// Prepares message to query family id for task stats.
func prepareFamilyMessage() (msg netlinkMessage) {
buf := bytes.NewBuffer([]byte{})
addAttribute(buf, ctrlAttrFamilyName, taskstatsGenlName, len(taskstatsGenlName)+1)
return prepareMessage(genlIdCtrl, ctrlCmdGetFamily, buf.Bytes())
}
// Prepares message to query task stats for a task group.
func prepareCmdMessage(id uint16, cfd uintptr) (msg netlinkMessage) {
buf := bytes.NewBuffer([]byte{})
addAttribute(buf, cgroupStatsCmdAttrFd, uint32(cfd), 4)
return prepareMessage(id, __TASKSTATS_CMD_MAX+1, buf.Bytes())
}
// Extracts returned family id from the response.
func parseFamilyResp(msg syscall.NetlinkMessage) (uint16, error) {
m := new(netlinkMessage)
m.Header = msg.Header
err := verifyHeader(msg)
if err != nil {
return 0, err
}
buf := bytes.NewBuffer(msg.Data)
// extract generic header from data.
err = binary.Read(buf, Endian, &m.GenHeader)
if err != nil {
return 0, err
}
id := uint16(0)
// Extract attributes. kernel reports family name, id, version, etc.
// Scan till we find id.
for buf.Len() > syscall.SizeofRtAttr {
var attr syscall.RtAttr
err = binary.Read(buf, Endian, &attr)
if err != nil {
return 0, err
}
if attr.Type == ctrlAttrFamilyId {
err = binary.Read(buf, Endian, &id)
if err != nil {
return 0, err
}
return id, nil
}
payload := int(attr.Len) - syscall.SizeofRtAttr
skipLen := payload + padding(payload, syscall.SizeofRtAttr)
name := make([]byte, skipLen)
err = binary.Read(buf, Endian, name)
if err != nil {
return 0, err
}
}
return 0, fmt.Errorf("family id not found in the response.")
}
// Extract task stats from response returned by kernel.
func parseLoadStatsResp(msg syscall.NetlinkMessage) (*loadStatsResp, error) {
m := new(loadStatsResp)
m.Header = msg.Header
err := verifyHeader(msg)
if err != nil {
return m, err
}
buf := bytes.NewBuffer(msg.Data)
// Scan the general header.
err = binary.Read(buf, Endian, &m.GenHeader)
if err != nil {
return m, err
}
// cgroup stats response should have just one attribute.
// Read it directly into the stats structure.
var attr syscall.RtAttr
err = binary.Read(buf, Endian, &attr)
if err != nil {
return m, err
}
err = binary.Read(buf, Endian, &m.Stats)
if err != nil {
return m, err
}
return m, err
}
// Verify and return any error reported by kernel.
func verifyHeader(msg syscall.NetlinkMessage) error {
switch msg.Header.Type {
case syscall.NLMSG_DONE:
return fmt.Errorf("expected a response, got nil")
case syscall.NLMSG_ERROR:
buf := bytes.NewBuffer(msg.Data)
var errno int32
binary.Read(buf, Endian, errno)
return fmt.Errorf("netlink request failed with error %s", syscall.Errno(-errno))
}
return nil
}
// Get load stats for a task group.
// id: family id for taskstats.
// cfd: open file to path to the cgroup directory under cpu hierarchy.
// conn: open netlink connection used to communicate with kernel.
func getLoadStats(id uint16, cfd *os.File, conn *Connection) (info.LoadStats, error) {
msg := prepareCmdMessage(id, cfd.Fd())
err := conn.WriteMessage(msg.toRawMsg())
if err != nil {
return info.LoadStats{}, err
}
resp, err := conn.ReadMessage()
if err != nil {
return info.LoadStats{}, err
}
parsedmsg, err := parseLoadStatsResp(resp)
if err != nil {
return info.LoadStats{}, err
}
return parsedmsg.Stats, nil
}

View File

@@ -0,0 +1,80 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package netlink
import (
"fmt"
"os"
info "github.com/google/cadvisor/info/v1"
"github.com/golang/glog"
)
type NetlinkReader struct {
familyId uint16
conn *Connection
}
func New() (*NetlinkReader, error) {
conn, err := newConnection()
if err != nil {
return nil, fmt.Errorf("failed to create a new connection: %s", err)
}
id, err := getFamilyId(conn)
if err != nil {
return nil, fmt.Errorf("failed to get netlink family id for task stats: %s", err)
}
glog.V(4).Infof("Family id for taskstats: %d", id)
return &NetlinkReader{
familyId: id,
conn: conn,
}, nil
}
func (self *NetlinkReader) Stop() {
if self.conn != nil {
self.conn.Close()
}
}
func (self *NetlinkReader) Start() error {
// We do the start setup for netlink in New(). Nothing to do here.
return nil
}
// Returns instantaneous number of running tasks in a group.
// Caller can use historical data to calculate cpu load.
// path is an absolute filesystem path for a container under the CPU cgroup hierarchy.
// NOTE: non-hierarchical load is returned. It does not include load for subcontainers.
func (self *NetlinkReader) GetCpuLoad(name string, path string) (info.LoadStats, error) {
if len(path) == 0 {
return info.LoadStats{}, fmt.Errorf("cgroup path can not be empty!")
}
cfd, err := os.Open(path)
defer cfd.Close()
if err != nil {
return info.LoadStats{}, fmt.Errorf("failed to open cgroup path %s: %q", path, err)
}
stats, err := getLoadStats(self.familyId, cfd, self.conn)
if err != nil {
return info.LoadStats{}, err
}
glog.V(4).Infof("Task stats for %q: %+v", path, stats)
return stats, nil
}

View File

@@ -0,0 +1,315 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package machine
import (
"fmt"
"io/ioutil"
"regexp"
"strconv"
"strings"
// s390/s390x changes
"runtime"
"syscall"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/utils"
"github.com/google/cadvisor/utils/sysfs"
"github.com/google/cadvisor/utils/sysinfo"
"github.com/golang/glog"
)
// The utils/machine package contains functions that extract machine-level specs.
var (
cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`)
coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`)
nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`)
// Power systems have a different format so cater for both
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
swapCapacityRegexp = regexp.MustCompile(`SwapTotal:\s*([0-9]+) kB`)
)
const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.
func GetClockSpeed(procInfo []byte) (uint64, error) {
// s390/s390x and aarch64 changes
if true == isSystemZ() || true == isAArch64() {
return 0, nil
}
// First look through sys to find a max supported cpu frequency.
if utils.FileExists(maxFreqFile) {
val, err := ioutil.ReadFile(maxFreqFile)
if err != nil {
return 0, err
}
var maxFreq uint64
n, err := fmt.Sscanf(string(val), "%d", &maxFreq)
if err != nil || n != 1 {
return 0, fmt.Errorf("could not parse frequency %q", val)
}
return maxFreq, nil
}
// Fall back to /proc/cpuinfo
matches := cpuClockSpeedMHz.FindSubmatch(procInfo)
if len(matches) != 2 {
return 0, fmt.Errorf("could not detect clock speed from output: %q", string(procInfo))
}
speed, err := strconv.ParseFloat(string(matches[1]), 64)
if err != nil {
return 0, err
}
// Convert to kHz
return uint64(speed * 1000), nil
}
// GetMachineMemoryCapacity returns the machine's total memory from /proc/meminfo.
// Returns the total memory capacity as an uint64 (number of bytes).
func GetMachineMemoryCapacity() (uint64, error) {
out, err := ioutil.ReadFile("/proc/meminfo")
if err != nil {
return 0, err
}
memoryCapacity, err := parseCapacity(out, memoryCapacityRegexp)
if err != nil {
return 0, err
}
return memoryCapacity, err
}
// GetMachineSwapCapacity returns the machine's total swap from /proc/meminfo.
// Returns the total swap capacity as an uint64 (number of bytes).
func GetMachineSwapCapacity() (uint64, error) {
out, err := ioutil.ReadFile("/proc/meminfo")
if err != nil {
return 0, err
}
swapCapacity, err := parseCapacity(out, swapCapacityRegexp)
if err != nil {
return 0, err
}
return swapCapacity, err
}
// parseCapacity matches a Regexp in a []byte, returning the resulting value in bytes.
// Assumes that the value matched by the Regexp is in KB.
func parseCapacity(b []byte, r *regexp.Regexp) (uint64, error) {
matches := r.FindSubmatch(b)
if len(matches) != 2 {
return 0, fmt.Errorf("failed to match regexp in output: %q", string(b))
}
m, err := strconv.ParseUint(string(matches[1]), 10, 64)
if err != nil {
return 0, err
}
// Convert to bytes.
return m * 1024, err
}
func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
nodes := []info.Node{}
// s390/s390x changes
if true == isSystemZ() {
return nodes, getNumCores(), nil
}
numCores := 0
lastThread := -1
lastCore := -1
lastNode := -1
for _, line := range strings.Split(cpuinfo, "\n") {
if line == "" {
continue
}
ok, val, err := extractValue(line, cpuRegExp)
if err != nil {
return nil, -1, fmt.Errorf("could not parse cpu info from %q: %v", line, err)
}
if ok {
thread := val
numCores++
if lastThread != -1 {
// New cpu section. Save last one.
nodeIdx, err := addNode(&nodes, lastNode)
if err != nil {
return nil, -1, fmt.Errorf("failed to add node %d: %v", lastNode, err)
}
nodes[nodeIdx].AddThread(lastThread, lastCore)
lastCore = -1
lastNode = -1
}
lastThread = thread
continue
}
ok, val, err = extractValue(line, coreRegExp)
if err != nil {
return nil, -1, fmt.Errorf("could not parse core info from %q: %v", line, err)
}
if ok {
lastCore = val
continue
}
ok, val, err = extractValue(line, nodeRegExp)
if err != nil {
return nil, -1, fmt.Errorf("could not parse node info from %q: %v", line, err)
}
if ok {
lastNode = val
continue
}
}
nodeIdx, err := addNode(&nodes, lastNode)
if err != nil {
return nil, -1, fmt.Errorf("failed to add node %d: %v", lastNode, err)
}
nodes[nodeIdx].AddThread(lastThread, lastCore)
if numCores < 1 {
return nil, numCores, fmt.Errorf("could not detect any cores")
}
for idx, node := range nodes {
caches, err := sysinfo.GetCacheInfo(sysFs, node.Cores[0].Threads[0])
if err != nil {
glog.Errorf("failed to get cache information for node %d: %v", node.Id, err)
continue
}
numThreadsPerCore := len(node.Cores[0].Threads)
numThreadsPerNode := len(node.Cores) * numThreadsPerCore
for _, cache := range caches {
c := info.Cache{
Size: cache.Size,
Level: cache.Level,
Type: cache.Type,
}
if cache.Cpus == numThreadsPerNode && cache.Level > 2 {
// Add a node-level cache.
nodes[idx].AddNodeCache(c)
} else if cache.Cpus == numThreadsPerCore {
// Add to each core.
nodes[idx].AddPerCoreCache(c)
}
// Ignore unknown caches.
}
}
return nodes, numCores, nil
}
func extractValue(s string, r *regexp.Regexp) (bool, int, error) {
matches := r.FindSubmatch([]byte(s))
if len(matches) == 2 {
val, err := strconv.ParseInt(string(matches[1]), 10, 32)
if err != nil {
return false, -1, err
}
return true, int(val), nil
}
return false, -1, nil
}
func findNode(nodes []info.Node, id int) (bool, int) {
for i, n := range nodes {
if n.Id == id {
return true, i
}
}
return false, -1
}
func addNode(nodes *[]info.Node, id int) (int, error) {
var idx int
if id == -1 {
// Some VMs don't fill topology data. Export single package.
id = 0
}
ok, idx := findNode(*nodes, id)
if !ok {
// New node
node := info.Node{Id: id}
// Add per-node memory information.
meminfo := fmt.Sprintf("/sys/devices/system/node/node%d/meminfo", id)
out, err := ioutil.ReadFile(meminfo)
// Ignore if per-node info is not available.
if err == nil {
m, err := parseCapacity(out, memoryCapacityRegexp)
if err != nil {
return -1, err
}
node.Memory = uint64(m)
}
*nodes = append(*nodes, node)
idx = len(*nodes) - 1
}
return idx, nil
}
// s390/s390x changes
func getMachineArch() (string, error) {
uname := syscall.Utsname{}
err := syscall.Uname(&uname)
if err != nil {
return "", err
}
var arch string
for _, val := range uname.Machine {
arch += string(int(val))
}
return arch, nil
}
// aarch64 changes
func isAArch64() bool {
arch, err := getMachineArch()
if err == nil {
if true == strings.Contains(arch, "aarch64") {
return true
}
}
return false
}
// s390/s390x changes
func isSystemZ() bool {
arch, err := getMachineArch()
if err == nil {
if true == strings.Contains(arch, "390") {
return true
}
}
return false
}
// s390/s390x changes
func getNumCores() int {
maxProcs := runtime.GOMAXPROCS(0)
numCPU := runtime.NumCPU()
if maxProcs < numCPU {
return maxProcs
}
return numCPU
}

View File

@@ -0,0 +1,44 @@
Jan 5 15:19:01 CRON[14500]: (root) CMD (touch /var/run/crond.sittercheck)
Jan 5 15:19:04 cookie_monster[1249]: uid 0, pid 14504, "/var/lib/certs/machine_cert.crt" accessed by exe "/usr/bin/nsscacheclient", cwd "/root", comm "/usr/bin/nsscacheclient"
Jan 5 15:19:04 cookie_monster[1249]: uid 0, pid 14504, "/var/lib/certs/machine_cert.key" accessed by exe "/usr/bin/nsscacheclient", cwd "/root", comm "/usr/bin/nsscacheclient"
Jan 5 15:19:05 nsscacheclient[14504]: SUCCESS: Completed run (v29/c20 rtime:0.334299 utime:0.136923 stime:0.011736 maxrss:5260k dials:1 sent:1793 rcvd:5143).
Jan 5 15:19:27 kernel: [ 5864.708440] memorymonster invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=0
Jan 5 15:19:27 kernel: [ 5864.708443] memorymonster cpuset=/ mems_allowed=0
Jan 5 15:19:27 kernel: [ 5864.708446] CPU: 5 PID: 13536 Comm: memorymonster Tainted: P OX 3.13.0-43-generic #72-Ubuntu
Jan 5 15:19:27 kernel: [ 5864.708447] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.65 12/19/2013
Jan 5 15:19:27 kernel: [ 5864.708448] ffff88072ae10800 ffff8807a4835c48 ffffffff81720bf6 ffff8807a8e86000
Jan 5 15:19:27 kernel: [ 5864.708451] ffff8807a4835cd0 ffffffff8171b4b1 0000000000000246 ffff88072ae10800
Jan 5 15:19:27 kernel: [ 5864.708453] ffff8807a4835c90 ffff8807a4835ca0 ffffffff811522a7 0000000000000001
Jan 5 15:19:27 kernel: [ 5864.708455] Call Trace:
Jan 5 15:19:27 kernel: [ 5864.708460] [<ffffffff81720bf6>] dump_stack+0x45/0x56
Jan 5 15:19:27 kernel: [ 5864.708463] [<ffffffff8171b4b1>] dump_header+0x7f/0x1f1
Jan 5 15:19:27 kernel: [ 5864.708465] [<ffffffff811522a7>] ? find_lock_task_mm+0x27/0x70
Jan 5 15:19:27 kernel: [ 5864.708467] [<ffffffff811526de>] oom_kill_process+0x1ce/0x330
Jan 5 15:19:27 kernel: [ 5864.708470] [<ffffffff812d6ce5>] ? security_capable_noaudit+0x15/0x20
Jan 5 15:19:27 kernel: [ 5864.708474] [<ffffffff811b491c>] mem_cgroup_oom_synchronize+0x51c/0x560
Jan 5 15:19:27 kernel: [ 5864.708476] [<ffffffff811b3e50>] ? mem_cgroup_charge_common+0xa0/0xa0
Jan 5 15:19:27 kernel: [ 5864.708478] [<ffffffff81152e64>] pagefault_out_of_memory+0x14/0x80
Jan 5 15:19:27 kernel: [ 5864.708480] [<ffffffff81719aa1>] mm_fault_error+0x8e/0x180
Jan 5 15:19:27 kernel: [ 5864.708482] [<ffffffff8172cf31>] __do_page_fault+0x4a1/0x560
Jan 5 15:19:27 kernel: [ 5864.708485] [<ffffffff810a0255>] ? set_next_entity+0x95/0xb0
Jan 5 15:19:27 kernel: [ 5864.708489] [<ffffffff81012609>] ? __switch_to+0x169/0x4c0
Jan 5 15:19:27 kernel: [ 5864.708490] [<ffffffff8172d00a>] do_page_fault+0x1a/0x70
Jan 5 15:19:27 kernel: [ 5864.708492] [<ffffffff81729468>] page_fault+0x28/0x30
Jan 5 15:19:27 kernel: [ 5864.708493] Task in /mem2 killed as a result of limit of /mem2
Jan 5 15:19:27 kernel: [ 5864.708495] memory: usage 980kB, limit 980kB, failcnt 4152239
Jan 5 15:19:27 kernel: [ 5864.708495] memory+swap: usage 0kB, limit 18014398509481983kB, failcnt 0
Jan 5 15:19:27 kernel: [ 5864.708496] kmem: usage 0kB, limit 18014398509481983kB, failcnt 0
Jan 5 15:19:27 kernel: [ 5864.708497] Memory cgroup stats for /mem2: cache:0KB rss:980KB rss_huge:0KB mapped_file:0KB writeback:20KB inactive_anon:560KB active_anon:420KB inactive_file:0KB active_file:0KB unevictable:0KB
Jan 5 15:19:27 kernel: [ 5864.708505] [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
Jan 5 15:19:27 kernel: [ 5864.708600] [13536] 275858 13536 8389663 343 16267 8324326 0 memorymonster
Jan 5 15:19:27 kernel: [ 5864.708607] Memory cgroup out of memory: Kill process 13536 (memorymonster) score 996 or sacrifice child
Jan 5 15:19:27 kernel: [ 5864.708608] Killed process 13536 (memorymonster) total-vm:33558652kB, anon-rss:920kB, file-rss:452kB
Jan 5 15:20:01 CRON[14608]: (root) CMD (touch /var/run/crond.sittercheck)
Jan 5 15:20:01 CRON[14609]: (root) CMD (/usr/bin/alarm 6000 /usr/share/update-notifier/reevaluate.py)
Jan 5 15:20:01 CRON[14610]: (root) CMD (/usr/bin/corp_cronwrap -j 80 -t 600 -A -K -L -l 'nsscache-client' /usr/bin/nsscacheclient all)
Jan 5 15:20:01 /usr/bin/lock: called by /bin/bash for . uid 0, euid 0.
Jan 5 15:21:01 CRON[14639]: (root) CMD (touch /var/run/crond.sittercheck)
Jan 5 15:21:05 cookie_monster[1249]: uid 0, pid 14643, "/var/lib/certs/machine_cert.crt" accessed by exe "/usr/bin/nsscacheclient", cwd "/root", comm "/usr/bin/nsscacheclient"
Jan 5 15:21:05 cookie_monster[1249]: uid 0, pid 14643, "/var/lib/certs/machine_cert.key" accessed by exe "/usr/bin/nsscacheclient", cwd "/root", comm "/usr/bin/nsscacheclient"
Jan 5 15:21:05 nsscacheclient[14643]: auto.auto(no change) time:0.042264697000000004 retries:0
Jan 5 15:21:05 nsscacheclient[14643]: auto.home(63c07d09->8686499b write:3631382) time:0.318774602 retries:0

View File

@@ -0,0 +1,41 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package main
import (
"flag"
"github.com/golang/glog"
"github.com/google/cadvisor/utils/oomparser"
)
// demonstrates how to run oomparser.OomParser to get OomInstance information
func main() {
flag.Parse()
// out is a user-provided channel from which the user can read incoming
// OomInstance objects
outStream := make(chan *oomparser.OomInstance)
oomLog, err := oomparser.New()
if err != nil {
glog.Infof("Couldn't make a new oomparser. %v", err)
} else {
go oomLog.StreamOoms(outStream)
// demonstration of how to get oomLog's list of oomInstances or access
// the user-declared oomInstance channel, here called outStream
for oomInstance := range outStream {
glog.Infof("Reading the buffer. Output is %v", oomInstance)
}
}
}

View File

@@ -0,0 +1,219 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package oomparser
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"path"
"regexp"
"strconv"
"time"
"github.com/google/cadvisor/utils"
"github.com/golang/glog"
)
var (
containerRegexp = regexp.MustCompile(`Task in (.*) killed as a result of limit of (.*)`)
lastLineRegexp = regexp.MustCompile(`(^[A-Z][a-z]{2} .*[0-9]{1,2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) .* Killed process ([0-9]+) \(([\w]+)\)`)
firstLineRegexp = regexp.MustCompile(`invoked oom-killer:`)
)
// struct to hold file from which we obtain OomInstances
type OomParser struct {
ioreader *bufio.Reader
}
// struct that contains information related to an OOM kill instance
type OomInstance struct {
// process id of the killed process
Pid int
// the name of the killed process
ProcessName string
// the time that the process was reported to be killed,
// accurate to the minute
TimeOfDeath time.Time
// the absolute name of the container that OOMed
ContainerName string
// the absolute name of the container that was killed
// due to the OOM.
VictimContainerName string
}
// gets the container name from a line and adds it to the oomInstance.
func getContainerName(line string, currentOomInstance *OomInstance) error {
parsedLine := containerRegexp.FindStringSubmatch(line)
if parsedLine == nil {
return nil
}
currentOomInstance.ContainerName = path.Join("/", parsedLine[1])
currentOomInstance.VictimContainerName = path.Join("/", parsedLine[2])
return nil
}
// gets the pid, name, and date from a line and adds it to oomInstance
func getProcessNamePid(line string, currentOomInstance *OomInstance) (bool, error) {
reList := lastLineRegexp.FindStringSubmatch(line)
if reList == nil {
return false, nil
}
const longForm = "Jan _2 15:04:05 2006"
stringYear := strconv.Itoa(time.Now().Year())
linetime, err := time.ParseInLocation(longForm, reList[1]+" "+stringYear, time.Local)
if err != nil {
return false, err
}
currentOomInstance.TimeOfDeath = linetime
pid, err := strconv.Atoi(reList[2])
if err != nil {
return false, err
}
currentOomInstance.Pid = pid
currentOomInstance.ProcessName = reList[3]
return true, nil
}
// uses regex to see if line is the start of a kernel oom log
func checkIfStartOfOomMessages(line string) bool {
potential_oom_start := firstLineRegexp.MatchString(line)
if potential_oom_start {
return true
}
return false
}
// reads the file and sends only complete lines over a channel to analyzeLines.
// Should prevent EOF errors that occur when lines are read before being fully
// written to the log. It reads line by line splitting on
// the "\n" character.
func readLinesFromFile(lineChannel chan string, ioreader *bufio.Reader) {
linefragment := ""
var line string
var err error
for true {
line, err = ioreader.ReadString('\n')
if err == io.EOF {
if line != "" {
linefragment += line
}
time.Sleep(100 * time.Millisecond)
} else if err == nil {
if linefragment != "" {
line = linefragment + line
linefragment = ""
}
lineChannel <- line
} else if err != nil && err != io.EOF {
glog.Errorf("exiting analyzeLinesHelper with error %v", err)
}
}
}
// Calls goroutine for readLinesFromFile, which feeds it complete lines.
// Lines are checked against a regexp to check for the pid, process name, etc.
// At the end of an oom message group, StreamOoms adds the new oomInstance to
// oomLog
func (self *OomParser) StreamOoms(outStream chan *OomInstance) {
lineChannel := make(chan string, 10)
go func() {
readLinesFromFile(lineChannel, self.ioreader)
}()
for line := range lineChannel {
in_oom_kernel_log := checkIfStartOfOomMessages(line)
if in_oom_kernel_log {
oomCurrentInstance := &OomInstance{
ContainerName: "/",
}
finished := false
for !finished {
err := getContainerName(line, oomCurrentInstance)
if err != nil {
glog.Errorf("%v", err)
}
finished, err = getProcessNamePid(line, oomCurrentInstance)
if err != nil {
glog.Errorf("%v", err)
}
line = <-lineChannel
}
outStream <- oomCurrentInstance
}
}
glog.Infof("exiting analyzeLines")
}
func callJournalctl() (io.ReadCloser, error) {
cmd := exec.Command("journalctl", "-k", "-f")
readcloser, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
return readcloser, err
}
func trySystemd() (*OomParser, error) {
readcloser, err := callJournalctl()
if err != nil {
return nil, err
}
glog.Infof("oomparser using systemd")
return &OomParser{
ioreader: bufio.NewReader(readcloser),
}, nil
}
// List of possible kernel log files. These are prioritized in order so that
// we will use the first one that is available.
var kernelLogFiles = []string{"/var/log/kern.log", "/var/log/messages", "/var/log/syslog"}
// looks for system files that contain kernel messages and if one is found, sets
// the systemFile attribute of the OomParser object
func getSystemFile() (string, error) {
for _, logFile := range kernelLogFiles {
if utils.FileExists(logFile) {
glog.Infof("OOM parser using kernel log file: %q", logFile)
return logFile, nil
}
}
return "", fmt.Errorf("unable to find any kernel log file available from our set: %v", kernelLogFiles)
}
// initializes an OomParser object and calls getSystemFile to set the systemFile
// attribute. Returns and OomParser object and an error
func New() (*OomParser, error) {
systemFile, err := getSystemFile()
if err != nil {
return trySystemd()
}
file, err := os.Open(systemFile)
if err != nil {
return trySystemd()
}
return &OomParser{
ioreader: bufio.NewReader(file),
}, nil
}

View File

@@ -0,0 +1,362 @@
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Hierarchical RCU implementation.
[ 0.000000] RCU dyntick-idle grace-period acceleration is enabled.
[ 0.000000] RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=1.
[ 0.000000] Offload RCU callbacks from all CPUs
[ 0.000000] Offload RCU callbacks from CPUs: 0.
[ 0.000000] NR_IRQS:16640 nr_irqs:256 16
[ 0.000000] Console: colour dummy device 80x25
[ 0.000000] console [ttyS0] enabled
[ 0.000000] allocated 7340032 bytes of page_cgroup
[ 0.000000] please try 'cgroup_disable=memory' option if you don't want memory cgroups
[ 0.000000] tsc: Detected 2500.000 MHz processor
[ 0.008000] Calibrating delay loop (skipped) preset value.. 5000.00 BogoMIPS (lpj=10000000)
[ 0.008000] pid_max: default: 32768 minimum: 301
[ 0.008000] Security Framework initialized
[ 0.008000] AppArmor: AppArmor initialized
[ 0.008000] Yama: becoming mindful.
[ 0.008200] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[ 0.011365] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[ 0.013066] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.014030] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.016266] Initializing cgroup subsys memory
[ 0.016898] Initializing cgroup subsys devices
[ 0.017546] Initializing cgroup subsys freezer
[ 0.018193] Initializing cgroup subsys blkio
[ 0.018793] Initializing cgroup subsys perf_event
[ 0.019416] Initializing cgroup subsys hugetlb
[ 0.020067] Disabled fast string operations
[ 0.020681] CPU: Physical Processor ID: 0
[ 0.021238] CPU: Processor Core ID: 0
[ 0.022587] mce: CPU supports 32 MCE banks
[ 0.023260] Last level iTLB entries: 4KB 512, 2MB 0, 4MB 0
[ 0.023260] Last level dTLB entries: 4KB 512, 2MB 0, 4MB 0
[ 0.023260] tlb_flushall_shift: 6
[ 0.043758] Freeing SMP alternatives memory: 32K (ffffffff81e6c000 - ffffffff81e74000)
[ 0.048361] ACPI: Core revision 20131115
[ 0.049516] ACPI: All ACPI Tables successfully acquired
[ 0.050342] ftrace: allocating 28458 entries in 112 pages
[ 0.060327] Enabling x2apic
[ 0.060740] Enabled x2apic
[ 0.064005] Switched APIC routing to physical x2apic.
[ 0.065489] ..TIMER: vector=0x30 apic1=0 pin1=0 apic2=-1 pin2=-1
[ 0.066331] smpboot: CPU0: Intel(R) Xeon(R) CPU @ 2.50GHz (fam: 06, model: 3e, stepping: 04)
[ 0.072000] APIC calibration not consistent with PM-Timer: 227ms instead of 100ms
[ 0.072000] APIC delta adjusted to PM-Timer: 6250028 (14249259)
[ 0.074382] Performance Events: unsupported p6 CPU model 62 no PMU driver, software events only.
[ 0.077174] x86: Booted up 1 node, 1 CPUs
[ 0.077738] smpboot: Total of 1 processors activated (5000.00 BogoMIPS)
[ 0.078932] NMI watchdog: disabled (cpu0): hardware events not enabled
[ 0.079945] devtmpfs: initialized
[ 0.081784] EVM: security.selinux
[ 0.082251] EVM: security.SMACK64
[ 0.082720] EVM: security.ima
[ 0.083135] EVM: security.capability
[ 0.084729] pinctrl core: initialized pinctrl subsystem
[ 0.085517] regulator-dummy: no parameters
[ 0.086187] RTC time: 19:51:09, date: 01/28/15
[ 0.086869] NET: Registered protocol family 16
[ 0.087613] cpuidle: using governor ladder
[ 0.088009] cpuidle: using governor menu
[ 0.088580] ACPI: bus type PCI registered
[ 0.089191] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[ 0.090220] PCI: Using configuration type 1 for base access
[ 0.091749] bio: create slab <bio-0> at 0
[ 0.092215] ACPI: Added _OSI(Module Device)
[ 0.092799] ACPI: Added _OSI(Processor Device)
[ 0.093410] ACPI: Added _OSI(3.0 _SCP Extensions)
[ 0.094173] ACPI: Added _OSI(Processor Aggregator Device)
[ 0.096962] ACPI: Interpreter enabled
[ 0.097483] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S1_] (20131115/hwxface-580)
[ 0.098762] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S2_] (20131115/hwxface-580)
[ 0.100011] ACPI: (supports S0 S3 S4 S5)
[ 0.100555] ACPI: Using IOAPIC for interrupt routing
[ 0.101252] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[ 0.102545] ACPI: No dock devices found.
[ 0.105210] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[ 0.106060] acpi PNP0A03:00: _OSC: OS supports [ASPM ClockPM Segments MSI]
[ 0.108025] acpi PNP0A03:00: _OSC failed (AE_NOT_FOUND); disabling ASPM
[ 0.109116] acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.
[ 0.112685] PCI host bridge to bus 0000:00
[ 0.113294] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.114054] pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7]
[ 0.115065] pci_bus 0000:00: root bus resource [io 0x0d00-0xffff]
[ 0.116004] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff]
[ 0.116955] pci_bus 0000:00: root bus resource [mem 0x6cc00000-0xfebfffff]
[ 0.117916] pci 0000:00:01.0: [8086:7110] type 00 class 0x060100
[ 0.122089] pci 0000:00:01.3: [8086:7113] type 00 class 0x068000
[ 0.125713] pci 0000:00:01.3: quirk: [io 0xb000-0xb03f] claimed by PIIX4 ACPI
[ 0.127117] pci 0000:00:03.0: [1af4:1004] type 00 class 0x000000
[ 0.128752] pci 0000:00:03.0: reg 0x10: [io 0xc000-0xc03f]
[ 0.130322] pci 0000:00:03.0: reg 0x14: [mem 0xfebfe000-0xfebfe07f]
[ 0.133571] pci 0000:00:04.0: [1af4:1000] type 00 class 0x020000
[ 0.135267] pci 0000:00:04.0: reg 0x10: [io 0xc040-0xc07f]
[ 0.136777] pci 0000:00:04.0: reg 0x14: [mem 0xfebff000-0xfebff03f]
[ 0.140811] ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
[ 0.141879] ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
[ 0.142886] ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
[ 0.144086] ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
[ 0.145067] ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
[ 0.146245] ACPI: Enabled 16 GPEs in block 00 to 0F
[ 0.147038] ACPI: \_SB_.PCI0: notify handler is installed
[ 0.147840] Found 1 acpi root devices
[ 0.148136] vgaarb: loaded
[ 0.148780] SCSI subsystem initialized
[ 0.149472] libata version 3.00 loaded.
[ 0.150070] ACPI: bus type USB registered
[ 0.150659] usbcore: registered new interface driver usbfs
[ 0.151536] usbcore: registered new interface driver hub
[ 0.152055] usbcore: registered new device driver usb
[ 0.153144] PCI: Using ACPI for IRQ routing
[ 0.153756] PCI: pci_cache_line_size set to 64 bytes
[ 0.154617] e820: reserve RAM buffer [mem 0x0009fc00-0x0009ffff]
[ 0.156004] e820: reserve RAM buffer [mem 0x6cbfe000-0x6fffffff]
[ 0.156993] NetLabel: Initializing
[ 0.157498] NetLabel: domain hash size = 128
[ 0.158082] NetLabel: protocols = UNLABELED CIPSOv4
[ 0.158815] NetLabel: unlabeled traffic allowed by default
[ 0.160005] Switched to clocksource kvm-clock
[ 0.168695] AppArmor: AppArmor Filesystem Enabled
[ 0.169361] pnp: PnP ACPI init
[ 0.169853] ACPI: bus type PNP registered
[ 0.170499] pnp 00:00: Plug and Play ACPI device, IDs PNP0b00 (active)
[ 0.171591] pnp 00:01: Plug and Play ACPI device, IDs PNP0501 (active)
[ 0.172574] pnp 00:02: Plug and Play ACPI device, IDs PNP0501 (active)
[ 0.173782] pnp: PnP ACPI: found 3 devices
[ 0.174430] ACPI: bus type PNP unregistered
[ 0.181364] pci_bus 0000:00: resource 4 [io 0x0000-0x0cf7]
[ 0.182172] pci_bus 0000:00: resource 5 [io 0x0d00-0xffff]
[ 0.183049] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff]
[ 0.184120] pci_bus 0000:00: resource 7 [mem 0x6cc00000-0xfebfffff]
[ 0.185051] NET: Registered protocol family 2
[ 0.185859] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[ 0.187117] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[ 0.188393] TCP: Hash tables configured (established 16384 bind 16384)
[ 0.189429] TCP: reno registered
[ 0.189929] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[ 0.190824] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[ 0.191830] NET: Registered protocol family 1
[ 0.192585] PCI: CLS 0 bytes, default 64
[ 0.193412] Trying to unpack rootfs image as initramfs...
[ 0.897565] Freeing initrd memory: 18780K (ffff880035b42000 - ffff880036d99000)
[ 0.898982] microcode: CPU0 sig=0x306e4, pf=0x1, revision=0x1
[ 0.899884] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
[ 0.901196] Scanning for low memory corruption every 60 seconds
[ 0.902497] Initialise system trusted keyring
[ 0.903169] audit: initializing netlink socket (disabled)
[ 0.904016] type=2000 audit(1422474669.702:1): initialized
[ 0.926617] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[ 0.928567] zbud: loaded
[ 0.929030] VFS: Disk quotas dquot_6.5.2
[ 0.929685] Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 0.931113] fuse init (API version 7.22)
[ 0.931781] msgmni has been set to 3390
[ 0.932595] Key type big_key registered
[ 0.933680] Key type asymmetric registered
[ 0.934332] Asymmetric key parser 'x509' registered
[ 0.935078] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[ 0.936224] io scheduler noop registered
[ 0.936858] io scheduler deadline registered (default)
[ 0.937675] io scheduler cfq registered
[ 0.938307] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[ 0.939158] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
[ 0.940239] efifb: probing for efifb
[ 0.940788] efifb: framebuffer at 0xa0000, mapped to 0xffff8800000a0000, using 64k, total 64k
[ 0.942044] efifb: mode is 640x480x1, linelength=80, pages=1
[ 0.942964] efifb: scrolling: redraw
[ 0.943525] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
[ 0.945209] Console: switching to colour frame buffer device 80x30
[ 0.946826] fb0: EFI VGA frame buffer device
[ 0.947485] intel_idle: does not run on family 6 model 62
[ 0.948380] ipmi message handler version 39.2
[ 0.949036] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
[ 0.950135] ACPI: Power Button [PWRF]
[ 0.950722] input: Sleep Button as /devices/LNXSYSTM:00/LNXSLPBN:00/input/input1
[ 0.951773] ACPI: Sleep Button [SLPF]
[ 0.952529] GHES: HEST is not enabled!
[ 0.953921] ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 11
[ 0.955783] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 10
[ 0.957395] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[ 1.112167] 00:01: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[ 1.134843] 00:02: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
[ 1.137110] Linux agpgart interface v0.103
[ 1.138975] brd: module loaded
[ 1.140117] loop: module loaded
[ 1.140923] libphy: Fixed MDIO Bus: probed
[ 1.141640] tun: Universal TUN/TAP device driver, 1.6
[ 1.142342] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 1.144063] virtio-pci 0000:00:04.0: irq 40 for MSI/MSI-X
[ 1.144871] virtio-pci 0000:00:04.0: irq 41 for MSI/MSI-X
[ 1.145670] virtio-pci 0000:00:04.0: irq 42 for MSI/MSI-X
[ 1.151673] PPP generic driver version 2.4.2
[ 1.152344] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 1.153399] ehci-pci: EHCI PCI platform driver
[ 1.154021] ehci-platform: EHCI generic platform driver
[ 1.154939] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 1.155973] ohci-pci: OHCI PCI platform driver
[ 1.156675] ohci-platform: OHCI generic platform driver
[ 1.157423] uhci_hcd: USB Universal Host Controller Interface driver
[ 1.158352] i8042: PNP: No PS/2 controller found. Probing ports directly.
[ 3.646820] i8042: No controller found
[ 3.647493] tsc: Refined TSC clocksource calibration: 2500.002 MHz
[ 3.648490] mousedev: PS/2 mouse device common for all mice
[ 3.649499] rtc_cmos 00:00: RTC can wake from S4
[ 3.650595] rtc_cmos 00:00: rtc core: registered rtc_cmos as rtc0
[ 3.651521] rtc_cmos 00:00: alarms up to one day, 114 bytes nvram
[ 3.652422] device-mapper: uevent: version 1.0.3
[ 3.653131] device-mapper: ioctl: 4.27.0-ioctl (2013-10-30) initialised: dm-devel@redhat.com
[ 3.654281] ledtrig-cpu: registered to indicate activity on CPUs
[ 3.655182] TCP: cubic registered
[ 3.655704] NET: Registered protocol family 10
[ 3.656551] NET: Registered protocol family 17
[ 3.657183] Key type dns_resolver registered
[ 3.657931] Loading compiled-in X.509 certificates
[ 3.659264] Loaded X.509 cert 'Magrathea: Glacier signing key: 23984ac203784325ccf7b95b51f6c119380eb933'
[ 3.660726] registered taskstats version 1
[ 3.663211] Key type trusted registered
[ 3.665462] Key type encrypted registered
[ 3.667679] AppArmor: AppArmor sha1 policy hashing enabled
[ 3.668454] IMA: No TPM chip found, activating TPM-bypass!
[ 3.669388] regulator-dummy: disabling
[ 3.669971] Magic number: 15:428:901
[ 3.670625] clocksource clocksource0: hash matches
[ 3.671311] acpi PNP0501:01: hash matches
[ 3.671953] rtc_cmos 00:00: setting system clock to 2015-01-28 19:51:13 UTC (1422474673)
[ 3.673268] BIOS EDD facility v0.16 2004-Jun-25, 0 devices found
[ 3.674088] EDD information not available.
[ 3.674668] PM: Hibernation image not present or could not be loaded.
[ 3.676577] Freeing unused kernel memory: 1332K (ffffffff81d1f000 - ffffffff81e6c000)
[ 3.678370] Write protecting the kernel read-only data: 12288k
[ 3.681251] Freeing unused kernel memory: 828K (ffff880001731000 - ffff880001800000)
[ 3.684444] Freeing unused kernel memory: 700K (ffff880001b51000 - ffff880001c00000)
[ 3.700162] systemd-udevd[90]: starting version 204
[ 3.866262] virtio-pci 0000:00:03.0: irq 43 for MSI/MSI-X
[ 3.867187] virtio-pci 0000:00:03.0: irq 44 for MSI/MSI-X
[ 3.867997] virtio-pci 0000:00:03.0: irq 45 for MSI/MSI-X
[ 3.876214] virtio-pci 0000:00:03.0: irq 46 for MSI/MSI-X
[ 3.880005] scsi0 : Virtio SCSI HBA
[ 3.912410] scsi 0:0:1:0: Direct-Access Google PersistentDisk 1 PQ: 0 ANSI: 6
[ 3.938957] sd 0:0:1:0: Attached scsi generic sg0 type 0
[ 3.939845] sd 0:0:1:0: [sda] 20971520 512-byte logical blocks: (10.7 GB/10.0 GiB)
[ 3.941149] sd 0:0:1:0: [sda] 4096-byte physical blocks
[ 3.942233] sd 0:0:1:0: [sda] Write Protect is off
[ 3.942988] sd 0:0:1:0: [sda] Mode Sense: 1f 00 00 08
[ 3.944398] sd 0:0:1:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 3.961885] sda: sda1
[ 3.963152] sd 0:0:1:0: [sda] Attached SCSI disk
[ 4.414649] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
[ 5.293574] random: init urandom read with 73 bits of entropy available
[ 6.418187] random: nonblocking pool is initialized
[ 6.692508] EXT4-fs (sda1): re-mounted. Opts: errors=remount-ro
[ 7.121847] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 7.681714] systemd-udevd[293]: starting version 204
[ 8.437234] lp: driver loaded but no devices found
[ 9.164195] piix4_smbus 0000:00:01.3: SMBus base address uninitialized - upgrade BIOS or use force_addr=0xaddr
[ 9.648096] device-mapper: multipath: version 1.6.0 loaded
[ 10.434575] type=1400 audit(1422474680.256:2): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/sbin/dhclient" pid=368 comm="apparmor_parser"
[ 10.437242] type=1400 audit(1422474680.260:3): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=368 comm="apparmor_parser"
[ 10.439901] type=1400 audit(1422474680.260:4): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/connman/scripts/dhclient-script" pid=368 comm="apparmor_parser"
[ 11.126295] type=1400 audit(1422474680.948:5): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/sbin/dhclient" pid=412 comm="apparmor_parser"
[ 11.129123] type=1400 audit(1422474680.952:6): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=412 comm="apparmor_parser"
[ 11.132139] type=1400 audit(1422474680.956:7): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/connman/scripts/dhclient-script" pid=412 comm="apparmor_parser"
[ 11.196173] type=1400 audit(1422474681.020:8): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/sbin/dhclient" pid=458 comm="apparmor_parser"
[ 11.198887] type=1400 audit(1422474681.020:9): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=458 comm="apparmor_parser"
[ 11.201484] type=1400 audit(1422474681.028:10): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/connman/scripts/dhclient-script" pid=458 comm="apparmor_parser"
[ 11.361371] init: udev-fallback-graphics main process (454) terminated with status 1
[ 11.378437] type=1400 audit(1422474681.200:11): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=458 comm="apparmor_parser"
[ 14.366411] init: failsafe main process (491) killed by TERM signal
kateknister@kateknister-test3:~$ tail -f /var/log/syslog
Jan 28 19:51:47 localhost ntpdate[1240]: adjust time server 169.254.169.254 offset -0.383723 sec
Jan 28 19:51:47 localhost ntpd[1312]: ntpd 4.2.6p5@1.2349-o Wed Oct 9 19:08:06 UTC 2013 (1)
Jan 28 19:51:47 localhost ntpd[1313]: proto: precision = 0.449 usec
Jan 28 19:51:47 localhost ntpd[1313]: ntp_io: estimated max descriptors: 1024, initial socket boundary: 16
Jan 28 19:51:47 localhost ntpd[1313]: Listen and drop on 0 v4wildcard 0.0.0.0 UDP 123
Jan 28 19:51:47 localhost ntpd[1313]: Listen and drop on 1 v6wildcard :: UDP 123
Jan 28 19:51:47 localhost ntpd[1313]: Listen normally on 2 lo 127.0.0.1 UDP 123
Jan 28 19:51:47 localhost ntpd[1313]: Listen normally on 3 eth0 10.240.192.196 UDP 123
Jan 28 19:51:47 localhost ntpd[1313]: peers refreshed
Jan 28 19:51:47 localhost ntpd[1313]: Listening on routing socket on fd #20 for interface updates
Jan 28 19:58:45 localhost kernel: [ 455.498827] badsysprogram invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
Jan 28 19:58:45 localhost kernel: [ 455.500173] badsysprogram cpuset=/ mems_allowed=0
Jan 28 19:58:45 localhost kernel: [ 455.501007] CPU: 0 PID: 1532 Comm: badsysprogram Not tainted 3.13.0-27-generic #50-Ubuntu
Jan 28 19:58:45 localhost kernel: [ 455.502301] Hardware name: Google Google, BIOS Google 01/01/2011
Jan 28 19:58:45 localhost kernel: [ 455.503298] 0000000000000000 ffff880069715a90 ffffffff817199c4 ffff8800680d8000
Jan 28 19:58:45 localhost kernel: [ 455.504563] ffff880069715b18 ffffffff817142ff 0000000000000000 0000000000000000
Jan 28 19:58:45 localhost kernel: [ 455.505779] 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Jan 28 19:58:45 localhost kernel: [ 455.506971] Call Trace:
Jan 28 19:58:45 localhost kernel: [ 455.507353] [<ffffffff817199c4>] dump_stack+0x45/0x56
Jan 28 19:58:45 localhost kernel: [ 455.508289] [<ffffffff817142ff>] dump_header+0x7f/0x1f1
Jan 28 19:58:45 localhost kernel: [ 455.509112] [<ffffffff8115196e>] oom_kill_process+0x1ce/0x330
Jan 28 19:58:45 localhost kernel: [ 455.510023] [<ffffffff812d3395>] ? security_capable_noaudit+0x15/0x20
Jan 28 19:58:45 localhost kernel: [ 455.510994] [<ffffffff811520a4>] out_of_memory+0x414/0x450
Jan 28 19:58:45 localhost kernel: [ 455.511820] [<ffffffff81158377>] __alloc_pages_nodemask+0xa87/0xb20
Jan 28 19:58:45 localhost kernel: [ 455.512815] [<ffffffff811985da>] alloc_pages_vma+0x9a/0x140
Jan 28 19:58:45 localhost kernel: [ 455.513647] [<ffffffff8117909b>] handle_mm_fault+0xb2b/0xf10
Jan 28 19:58:45 localhost kernel: [ 455.514498] [<ffffffff81725924>] __do_page_fault+0x184/0x560
Jan 28 19:58:45 localhost kernel: [ 455.515415] [<ffffffff8101b7d9>] ? sched_clock+0x9/0x10
Jan 28 19:58:45 localhost kernel: [ 455.516318] [<ffffffff8109d13d>] ? sched_clock_local+0x1d/0x80
Jan 28 19:58:45 localhost kernel: [ 455.517242] [<ffffffff811112ec>] ? acct_account_cputime+0x1c/0x20
Jan 28 19:58:45 localhost kernel: [ 455.518141] [<ffffffff8109d76b>] ? account_user_time+0x8b/0xa0
Jan 28 19:58:45 localhost kernel: [ 455.519014] [<ffffffff8109dd84>] ? vtime_account_user+0x54/0x60
Jan 28 19:58:45 localhost kernel: [ 455.519910] [<ffffffff81725d1a>] do_page_fault+0x1a/0x70
Jan 28 19:58:45 localhost kernel: [ 455.520712] [<ffffffff81722188>] page_fault+0x28/0x30
Jan 28 19:58:45 localhost kernel: [ 455.521498] Mem-Info:
Jan 28 19:58:45 localhost kernel: [ 455.521873] Node 0 DMA per-cpu:
Jan 28 19:58:45 localhost kernel: [ 455.522388] CPU 0: hi: 0, btch: 1 usd: 0
Jan 28 19:58:45 localhost kernel: [ 455.598342] Node 0 DMA32 per-cpu:
Jan 28 19:58:45 localhost kernel: [ 455.598890] CPU 0: hi: 186, btch: 31 usd: 86
Jan 28 19:58:45 localhost kernel: [ 455.599687] active_anon:405991 inactive_anon:57 isolated_anon:0
Jan 28 19:58:45 localhost kernel: [ 455.599687] active_file:35 inactive_file:69 isolated_file:0
Jan 28 19:58:45 localhost kernel: [ 455.599687] unevictable:0 dirty:0 writeback:0 unstable:0
Jan 28 19:58:45 localhost kernel: [ 455.599687] free:12929 slab_reclaimable:1635 slab_unreclaimable:1919
Jan 28 19:58:45 localhost kernel: [ 455.599687] mapped:34 shmem:70 pagetables:1423 bounce:0
Jan 28 19:58:45 localhost kernel: [ 455.599687] free_cma:0
Jan 28 19:58:45 localhost kernel: [ 455.604585] Node 0 DMA free:7124kB min:412kB low:512kB high:616kB active_anon:8508kB inactive_anon:4kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:4kB slab_reclaimable:16kB slab_unreclaimable:16kB kernel_stack:0kB pagetables:12kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
Jan 28 19:58:45 localhost kernel: [ 455.610811] lowmem_reserve[]: 0 1679 1679 1679
Jan 28 19:58:45 localhost kernel: [ 455.611600] Node 0 DMA32 free:44592kB min:44640kB low:55800kB high:66960kB active_anon:1615456kB inactive_anon:224kB active_file:140kB inactive_file:276kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1765368kB managed:1722912kB mlocked:0kB dirty:0kB writeback:0kB mapped:136kB shmem:276kB slab_reclaimable:6524kB slab_unreclaimable:7660kB kernel_stack:592kB pagetables:5680kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:819 all_unreclaimable? yes
Jan 28 19:58:45 localhost kernel: [ 455.618372] lowmem_reserve[]: 0 0 0 0
Jan 28 19:58:45 localhost kernel: [ 455.619041] Node 0 DMA: 5*4kB (UM) 6*8kB (UEM) 7*16kB (UEM) 1*32kB (M) 2*64kB (UE) 3*128kB (UEM) 1*256kB (E) 2*512kB (EM) 3*1024kB (UEM) 1*2048kB (R) 0*4096kB = 7124kB
Jan 28 19:58:45 localhost kernel: [ 455.621861] Node 0 DMA32: 74*4kB (UEM) 125*8kB (UEM) 78*16kB (UEM) 26*32kB (UE) 12*64kB (UEM) 4*128kB (UE) 4*256kB (UE) 2*512kB (E) 11*1024kB (UE) 7*2048kB (UE) 3*4096kB (UR) = 44592kB
Jan 28 19:58:45 localhost kernel: [ 455.625174] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
Jan 28 19:58:45 localhost kernel: [ 455.626394] 204 total pagecache pages
Jan 28 19:58:45 localhost kernel: [ 455.626954] 0 pages in swap cache
Jan 28 19:58:45 localhost kernel: [ 455.627455] Swap cache stats: add 0, delete 0, find 0/0
Jan 28 19:58:45 localhost kernel: [ 455.628242] Free swap = 0kB
Jan 28 19:58:45 localhost kernel: [ 455.628686] Total swap = 0kB
Jan 28 19:58:45 localhost kernel: [ 455.629147] 445340 pages RAM
Jan 28 19:58:45 localhost kernel: [ 455.629577] 0 pages HighMem/MovableOnly
Jan 28 19:58:45 localhost kernel: [ 455.630301] 10614 pages reserved
Jan 28 19:58:45 localhost kernel: [ 455.630787] [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
Jan 28 19:58:45 localhost kernel: [ 455.631937] [ 273] 0 273 4869 50 13 0 0 upstart-udev-br
Jan 28 19:58:45 localhost kernel: [ 455.633290] [ 293] 0 293 12802 154 28 0 -1000 systemd-udevd
Jan 28 19:58:45 localhost kernel: [ 455.634671] [ 321] 0 321 3819 54 12 0 0 upstart-file-br
Jan 28 19:58:45 localhost kernel: [ 455.636070] [ 326] 102 326 9805 109 24 0 0 dbus-daemon
Jan 28 19:58:45 localhost kernel: [ 455.637373] [ 334] 101 334 63960 94 26 0 0 rsyslogd
Jan 28 19:58:45 localhost kernel: [ 455.638761] [ 343] 0 343 10863 102 26 0 0 systemd-logind
Jan 28 19:58:45 localhost kernel: [ 455.640158] [ 546] 0 546 3815 60 13 0 0 upstart-socket-
Jan 28 19:58:45 localhost kernel: [ 455.641534] [ 710] 0 710 2556 587 8 0 0 dhclient
Jan 28 19:58:45 localhost kernel: [ 455.642834] [ 863] 0 863 3955 48 13 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.644139] [ 865] 0 865 3955 50 13 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.645325] [ 867] 0 867 3955 51 13 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.646621] [ 868] 0 868 3955 51 12 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.647963] [ 870] 0 870 3955 49 13 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.649234] [ 915] 0 915 5914 61 16 0 0 cron
Jan 28 19:58:45 localhost kernel: [ 455.650439] [ 1015] 0 1015 10885 1524 25 0 0 manage_addresse
Jan 28 19:58:45 localhost kernel: [ 455.651817] [ 1028] 0 1028 3955 49 13 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.653091] [ 1033] 0 1033 3197 48 12 0 0 getty
Jan 28 19:58:45 localhost kernel: [ 455.654783] [ 1264] 0 1264 11031 1635 26 0 0 manage_accounts
Jan 28 19:58:45 localhost kernel: [ 455.656657] [ 1268] 0 1268 15341 180 33 0 -1000 sshd
Jan 28 19:58:45 localhost kernel: [ 455.657865] [ 1313] 104 1313 6804 154 17 0 0 ntpd
Jan 28 19:58:45 localhost kernel: [ 455.659085] [ 1389] 0 1389 25889 255 55 0 0 sshd
Jan 28 19:58:45 localhost kernel: [ 455.660440] [ 1407] 1020 1407 25889 255 52 0 0 sshd
Jan 28 19:58:45 localhost kernel: [ 455.661595] [ 1408] 1020 1408 5711 581 17 0 0 bash
Jan 28 19:58:45 localhost kernel: [ 455.662887] [ 1425] 0 1425 25889 256 53 0 0 sshd
Jan 28 19:58:45 localhost kernel: [ 455.664075] [ 1443] 1020 1443 25889 257 52 0 0 sshd
Jan 28 19:58:45 localhost kernel: [ 455.665330] [ 1444] 1020 1444 5711 581 16 0 0 bash
Jan 28 19:58:45 localhost kernel: [ 455.666450] [ 1476] 1020 1476 1809 25 9 0 0 tail
Jan 28 19:58:45 localhost kernel: [ 455.667682] [ 1532] 1020 1532 410347 398810 788 0 0 badsysprogram
Jan 28 19:58:45 localhost kernel: [ 455.669006] Out of memory: Kill process 1532 (badsysprogram) score 919 or sacrifice child
Jan 28 19:58:45 localhost kernel: [ 455.670291] Killed process 1532 (badsysprogram) total-vm:1641388kB, anon-rss:1595164kB, file-rss:76kB
[ 0.170499] pnp 00:00: Plug and Play ACPI device, IDs PNP0b00 (active)
[ 0.171591] pnp 00:01: Plug and Play ACPI device, IDs PNP0501 (active)
[ 0.172574] pnp 00:02: Plug and Play ACPI device, IDs PNP0501 (active)

24
vendor/github.com/google/cadvisor/utils/path.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package utils
import "os"
func FileExists(file string) bool {
if _, err := os.Stat(file); err != nil {
return false
}
return true
}

17
vendor/github.com/google/cadvisor/utils/procfs/doc.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
// procfs contains several low level functions to read information from /proc
// filesystem, and also provides some utility functions like JiffiesToDuration.
package procfs

View File

@@ -0,0 +1,33 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package procfs
/*
#include <unistd.h>
*/
import "C"
import "time"
var userHz uint64
func init() {
userHzLong := C.sysconf(C._SC_CLK_TCK)
userHz = uint64(userHzLong)
}
func JiffiesToDuration(jiffies uint64) time.Duration {
d := jiffies * 1000000000 / userHz
return time.Duration(d)
}

View File

@@ -0,0 +1,114 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package fakesysfs
import (
"os"
"time"
"github.com/google/cadvisor/utils/sysfs"
)
// If we extend sysfs to support more interfaces, it might be worth making this a mock instead of a fake.
type FileInfo struct {
EntryName string
}
func (self *FileInfo) Name() string {
return self.EntryName
}
func (self *FileInfo) Size() int64 {
return 1234567
}
func (self *FileInfo) Mode() os.FileMode {
return 0
}
func (self *FileInfo) ModTime() time.Time {
return time.Time{}
}
func (self *FileInfo) IsDir() bool {
return true
}
func (self *FileInfo) Sys() interface{} {
return nil
}
type FakeSysFs struct {
info FileInfo
cache sysfs.CacheInfo
}
func (self *FakeSysFs) GetBlockDevices() ([]os.FileInfo, error) {
self.info.EntryName = "sda"
return []os.FileInfo{&self.info}, nil
}
func (self *FakeSysFs) GetBlockDeviceSize(name string) (string, error) {
return "1234567", nil
}
func (self *FakeSysFs) GetBlockDeviceScheduler(name string) (string, error) {
return "noop deadline [cfq]", nil
}
func (self *FakeSysFs) GetBlockDeviceNumbers(name string) (string, error) {
return "8:0\n", nil
}
func (self *FakeSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
return []os.FileInfo{&self.info}, nil
}
func (self *FakeSysFs) GetNetworkAddress(name string) (string, error) {
return "42:01:02:03:04:f4\n", nil
}
func (self *FakeSysFs) GetNetworkMtu(name string) (string, error) {
return "1024\n", nil
}
func (self *FakeSysFs) GetNetworkSpeed(name string) (string, error) {
return "1000\n", nil
}
func (self *FakeSysFs) GetNetworkStatValue(name string, stat string) (uint64, error) {
return 1024, nil
}
func (self *FakeSysFs) GetCaches(id int) ([]os.FileInfo, error) {
self.info.EntryName = "index0"
return []os.FileInfo{&self.info}, nil
}
func (self *FakeSysFs) GetCacheInfo(cpu int, cache string) (sysfs.CacheInfo, error) {
return self.cache, nil
}
func (self *FakeSysFs) SetCacheInfo(cache sysfs.CacheInfo) {
self.cache = cache
}
func (self *FakeSysFs) SetEntryName(name string) {
self.info.EntryName = name
}
func (self *FakeSysFs) GetSystemUUID() (string, error) {
return "1F862619-BA9F-4526-8F85-ECEAF0C97430", nil
}

249
vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go generated vendored Normal file
View File

@@ -0,0 +1,249 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package sysfs
import (
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
)
const (
blockDir = "/sys/block"
cacheDir = "/sys/devices/system/cpu/cpu"
netDir = "/sys/class/net"
dmiDir = "/sys/class/dmi"
ppcDevTree = "/proc/device-tree"
s390xDevTree = "/etc" // s390/s390x changes
)
type CacheInfo struct {
// size in bytes
Size uint64
// cache type - instruction, data, unified
Type string
// distance from cpus in a multi-level hierarchy
Level int
// number of cpus that can access this cache.
Cpus int
}
// Abstracts the lowest level calls to sysfs.
type SysFs interface {
// Get directory information for available block devices.
GetBlockDevices() ([]os.FileInfo, error)
// Get Size of a given block device.
GetBlockDeviceSize(string) (string, error)
// Get scheduler type for the block device.
GetBlockDeviceScheduler(string) (string, error)
// Get device major:minor number string.
GetBlockDeviceNumbers(string) (string, error)
GetNetworkDevices() ([]os.FileInfo, error)
GetNetworkAddress(string) (string, error)
GetNetworkMtu(string) (string, error)
GetNetworkSpeed(string) (string, error)
GetNetworkStatValue(dev string, stat string) (uint64, error)
// Get directory information for available caches accessible to given cpu.
GetCaches(id int) ([]os.FileInfo, error)
// Get information for a cache accessible from the given cpu.
GetCacheInfo(cpu int, cache string) (CacheInfo, error)
GetSystemUUID() (string, error)
}
type realSysFs struct{}
func NewRealSysFs() (SysFs, error) {
return &realSysFs{}, nil
}
func (self *realSysFs) GetBlockDevices() ([]os.FileInfo, error) {
return ioutil.ReadDir(blockDir)
}
func (self *realSysFs) GetBlockDeviceNumbers(name string) (string, error) {
dev, err := ioutil.ReadFile(path.Join(blockDir, name, "/dev"))
if err != nil {
return "", err
}
return string(dev), nil
}
func (self *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {
sched, err := ioutil.ReadFile(path.Join(blockDir, name, "/queue/scheduler"))
if err != nil {
return "", err
}
return string(sched), nil
}
func (self *realSysFs) GetBlockDeviceSize(name string) (string, error) {
size, err := ioutil.ReadFile(path.Join(blockDir, name, "/size"))
if err != nil {
return "", err
}
return string(size), nil
}
func (self *realSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
files, err := ioutil.ReadDir(netDir)
if err != nil {
return nil, err
}
// Filter out non-directory & non-symlink files
var dirs []os.FileInfo
for _, f := range files {
if f.Mode()|os.ModeSymlink != 0 {
f, err = os.Stat(path.Join(netDir, f.Name()))
if err != nil {
continue
}
}
if f.IsDir() {
dirs = append(dirs, f)
}
}
return dirs, nil
}
func (self *realSysFs) GetNetworkAddress(name string) (string, error) {
address, err := ioutil.ReadFile(path.Join(netDir, name, "/address"))
if err != nil {
return "", err
}
return string(address), nil
}
func (self *realSysFs) GetNetworkMtu(name string) (string, error) {
mtu, err := ioutil.ReadFile(path.Join(netDir, name, "/mtu"))
if err != nil {
return "", err
}
return string(mtu), nil
}
func (self *realSysFs) GetNetworkSpeed(name string) (string, error) {
speed, err := ioutil.ReadFile(path.Join(netDir, name, "/speed"))
if err != nil {
return "", err
}
return string(speed), nil
}
func (self *realSysFs) GetNetworkStatValue(dev string, stat string) (uint64, error) {
statPath := path.Join(netDir, dev, "/statistics", stat)
out, err := ioutil.ReadFile(statPath)
if err != nil {
return 0, fmt.Errorf("failed to read stat from %q for device %q", statPath, dev)
}
var s uint64
n, err := fmt.Sscanf(string(out), "%d", &s)
if err != nil || n != 1 {
return 0, fmt.Errorf("could not parse value from %q for file %s", string(out), statPath)
}
return s, nil
}
func (self *realSysFs) GetCaches(id int) ([]os.FileInfo, error) {
cpuPath := fmt.Sprintf("%s%d/cache", cacheDir, id)
return ioutil.ReadDir(cpuPath)
}
func bitCount(i uint64) (count int) {
for i != 0 {
if i&1 == 1 {
count++
}
i >>= 1
}
return
}
func getCpuCount(cache string) (count int, err error) {
out, err := ioutil.ReadFile(path.Join(cache, "/shared_cpu_map"))
if err != nil {
return 0, err
}
masks := strings.Split(string(out), ",")
for _, mask := range masks {
// convert hex string to uint64
m, err := strconv.ParseUint(strings.TrimSpace(mask), 16, 64)
if err != nil {
return 0, fmt.Errorf("failed to parse cpu map %q: %v", string(out), err)
}
count += bitCount(m)
}
return
}
func (self *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) {
cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, id, name)
out, err := ioutil.ReadFile(path.Join(cachePath, "/size"))
if err != nil {
return CacheInfo{}, err
}
var size uint64
n, err := fmt.Sscanf(string(out), "%dK", &size)
if err != nil || n != 1 {
return CacheInfo{}, err
}
// convert to bytes
size = size * 1024
out, err = ioutil.ReadFile(path.Join(cachePath, "/level"))
if err != nil {
return CacheInfo{}, err
}
var level int
n, err = fmt.Sscanf(string(out), "%d", &level)
if err != nil || n != 1 {
return CacheInfo{}, err
}
out, err = ioutil.ReadFile(path.Join(cachePath, "/type"))
if err != nil {
return CacheInfo{}, err
}
cacheType := strings.TrimSpace(string(out))
cpuCount, err := getCpuCount(cachePath)
if err != nil {
return CacheInfo{}, err
}
return CacheInfo{
Size: size,
Level: level,
Type: cacheType,
Cpus: cpuCount,
}, nil
}
func (self *realSysFs) GetSystemUUID() (string, error) {
if id, err := ioutil.ReadFile(path.Join(dmiDir, "id", "product_uuid")); err == nil {
return strings.TrimSpace(string(id)), nil
} else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "system-id")); err == nil {
return strings.TrimSpace(string(id)), nil
} else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "vm,uuid")); err == nil {
return strings.TrimSpace(string(id)), nil
} else if id, err = ioutil.ReadFile(path.Join(s390xDevTree, "machine-id")); err == nil {
return strings.TrimSpace(string(id)), nil
} else {
return "", err
}
}

View File

@@ -0,0 +1,206 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package sysinfo
import (
"fmt"
"regexp"
"strconv"
"strings"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/utils/sysfs"
)
var schedulerRegExp = regexp.MustCompile(`.*\[(.*)\].*`)
// Get information about block devices present on the system.
// Uses the passed in system interface to retrieve the low level OS information.
func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
disks, err := sysfs.GetBlockDevices()
if err != nil {
return nil, err
}
diskMap := make(map[string]info.DiskInfo)
for _, disk := range disks {
name := disk.Name()
// Ignore non-disk devices.
// TODO(rjnagal): Maybe just match hd, sd, and dm prefixes.
if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") {
continue
}
disk_info := info.DiskInfo{
Name: name,
}
dev, err := sysfs.GetBlockDeviceNumbers(name)
if err != nil {
return nil, err
}
n, err := fmt.Sscanf(dev, "%d:%d", &disk_info.Major, &disk_info.Minor)
if err != nil || n != 2 {
return nil, fmt.Errorf("could not parse device numbers from %s for device %s", dev, name)
}
out, err := sysfs.GetBlockDeviceSize(name)
if err != nil {
return nil, err
}
// Remove trailing newline before conversion.
size, err := strconv.ParseUint(strings.TrimSpace(out), 10, 64)
if err != nil {
return nil, err
}
// size is in 512 bytes blocks.
disk_info.Size = size * 512
disk_info.Scheduler = "none"
blkSched, err := sysfs.GetBlockDeviceScheduler(name)
if err == nil {
matches := schedulerRegExp.FindSubmatch([]byte(blkSched))
if len(matches) >= 2 {
disk_info.Scheduler = string(matches[1])
}
}
device := fmt.Sprintf("%d:%d", disk_info.Major, disk_info.Minor)
diskMap[device] = disk_info
}
return diskMap, nil
}
// Get information about network devices present on the system.
func GetNetworkDevices(sysfs sysfs.SysFs) ([]info.NetInfo, error) {
devs, err := sysfs.GetNetworkDevices()
if err != nil {
return nil, err
}
netDevices := []info.NetInfo{}
for _, dev := range devs {
name := dev.Name()
// Ignore docker, loopback, and veth devices.
ignoredDevices := []string{"lo", "veth", "docker"}
ignored := false
for _, prefix := range ignoredDevices {
if strings.HasPrefix(name, prefix) {
ignored = true
break
}
}
if ignored {
continue
}
address, err := sysfs.GetNetworkAddress(name)
if err != nil {
return nil, err
}
mtuStr, err := sysfs.GetNetworkMtu(name)
if err != nil {
return nil, err
}
var mtu int64
n, err := fmt.Sscanf(mtuStr, "%d", &mtu)
if err != nil || n != 1 {
return nil, fmt.Errorf("could not parse mtu from %s for device %s", mtuStr, name)
}
netInfo := info.NetInfo{
Name: name,
MacAddress: strings.TrimSpace(address),
Mtu: mtu,
}
speed, err := sysfs.GetNetworkSpeed(name)
// Some devices don't set speed.
if err == nil {
var s int64
n, err := fmt.Sscanf(speed, "%d", &s)
if err != nil || n != 1 {
return nil, fmt.Errorf("could not parse speed from %s for device %s", speed, name)
}
netInfo.Speed = s
}
netDevices = append(netDevices, netInfo)
}
return netDevices, nil
}
func GetCacheInfo(sysFs sysfs.SysFs, id int) ([]sysfs.CacheInfo, error) {
caches, err := sysFs.GetCaches(id)
if err != nil {
return nil, err
}
info := []sysfs.CacheInfo{}
for _, cache := range caches {
if !strings.HasPrefix(cache.Name(), "index") {
continue
}
cacheInfo, err := sysFs.GetCacheInfo(id, cache.Name())
if err != nil {
return nil, err
}
info = append(info, cacheInfo)
}
return info, nil
}
func GetNetworkStats(name string) (info.InterfaceStats, error) {
// TODO(rjnagal): Take syfs as an argument.
sysFs, err := sysfs.NewRealSysFs()
if err != nil {
return info.InterfaceStats{}, err
}
return getNetworkStats(name, sysFs)
}
func getNetworkStats(name string, sysFs sysfs.SysFs) (info.InterfaceStats, error) {
var stats info.InterfaceStats
var err error
stats.Name = name
stats.RxBytes, err = sysFs.GetNetworkStatValue(name, "rx_bytes")
if err != nil {
return stats, err
}
stats.RxPackets, err = sysFs.GetNetworkStatValue(name, "rx_packets")
if err != nil {
return stats, err
}
stats.RxErrors, err = sysFs.GetNetworkStatValue(name, "rx_errors")
if err != nil {
return stats, err
}
stats.RxDropped, err = sysFs.GetNetworkStatValue(name, "rx_dropped")
if err != nil {
return stats, err
}
stats.TxBytes, err = sysFs.GetNetworkStatValue(name, "tx_bytes")
if err != nil {
return stats, err
}
stats.TxPackets, err = sysFs.GetNetworkStatValue(name, "tx_packets")
if err != nil {
return stats, err
}
stats.TxErrors, err = sysFs.GetNetworkStatValue(name, "tx_errors")
if err != nil {
return stats, err
}
stats.TxDropped, err = sysFs.GetNetworkStatValue(name, "tx_dropped")
if err != nil {
return stats, err
}
return stats, nil
}
func GetSystemUUID(sysFs sysfs.SysFs) (string, error) {
return sysFs.GetSystemUUID()
}

155
vendor/github.com/google/cadvisor/utils/timed_store.go generated vendored Normal file
View File

@@ -0,0 +1,155 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.
package utils
import (
"sort"
"time"
)
type timedStoreDataSlice []timedStoreData
func (t timedStoreDataSlice) Less(i, j int) bool {
return t[i].timestamp.Before(t[j].timestamp)
}
func (t timedStoreDataSlice) Len() int {
return len(t)
}
func (t timedStoreDataSlice) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
// A time-based buffer for ContainerStats.
// Holds information for a specific time period and/or a max number of items.
type TimedStore struct {
buffer timedStoreDataSlice
age time.Duration
maxItems int
}
type timedStoreData struct {
timestamp time.Time
data interface{}
}
// Returns a new thread-compatible TimedStore.
// A maxItems value of -1 means no limit.
func NewTimedStore(age time.Duration, maxItems int) *TimedStore {
return &TimedStore{
buffer: make(timedStoreDataSlice, 0),
age: age,
maxItems: maxItems,
}
}
// Adds an element to the start of the buffer (removing one from the end if necessary).
func (self *TimedStore) Add(timestamp time.Time, item interface{}) {
// Remove any elements if over our max size.
if self.maxItems >= 0 && (len(self.buffer)+1) > self.maxItems {
startIndex := len(self.buffer) + 1 - self.maxItems
self.buffer = self.buffer[startIndex:]
}
// Add the new element first and sort. We can then remove an expired element, if required.
copied := item
self.buffer = append(self.buffer, timedStoreData{
timestamp: timestamp,
data: copied,
})
sort.Sort(self.buffer)
// Remove any elements before eviction time.
// TODO(rjnagal): This is assuming that the added entry has timestamp close to now.
evictTime := timestamp.Add(-self.age)
index := sort.Search(len(self.buffer), func(index int) bool {
return self.buffer[index].timestamp.After(evictTime)
})
if index < len(self.buffer) {
self.buffer = self.buffer[index:]
}
}
// Returns up to maxResult elements in the specified time period (inclusive).
// Results are from first to last. maxResults of -1 means no limit.
func (self *TimedStore) InTimeRange(start, end time.Time, maxResults int) []interface{} {
// No stats, return empty.
if len(self.buffer) == 0 {
return []interface{}{}
}
var startIndex int
if start.IsZero() {
// None specified, start at the beginning.
startIndex = len(self.buffer) - 1
} else {
// Start is the index before the elements smaller than it. We do this by
// finding the first element smaller than start and taking the index
// before that element
startIndex = sort.Search(len(self.buffer), func(index int) bool {
// buffer[index] < start
return self.getData(index).timestamp.Before(start)
}) - 1
// Check if start is after all the data we have.
if startIndex < 0 {
return []interface{}{}
}
}
var endIndex int
if end.IsZero() {
// None specified, end with the latest stats.
endIndex = 0
} else {
// End is the first index smaller than or equal to it (so, not larger).
endIndex = sort.Search(len(self.buffer), func(index int) bool {
// buffer[index] <= t -> !(buffer[index] > t)
return !self.getData(index).timestamp.After(end)
})
// Check if end is before all the data we have.
if endIndex == len(self.buffer) {
return []interface{}{}
}
}
// Trim to maxResults size.
numResults := startIndex - endIndex + 1
if maxResults != -1 && numResults > maxResults {
startIndex -= numResults - maxResults
numResults = maxResults
}
// Return in sorted timestamp order so from the "back" to "front".
result := make([]interface{}, numResults)
for i := 0; i < numResults; i++ {
result[i] = self.Get(startIndex - i)
}
return result
}
// Gets the element at the specified index. Note that elements are output in LIFO order.
func (self *TimedStore) Get(index int) interface{} {
return self.getData(index).data
}
// Gets the data at the specified index. Note that elements are output in LIFO order.
func (self *TimedStore) getData(index int) timedStoreData {
return self.buffer[len(self.buffer)-index-1]
}
func (self *TimedStore) Size() int {
return len(self.buffer)
}

29
vendor/github.com/google/cadvisor/utils/utils.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
package utils
import "fmt"
// Returns a mask of all cores on the machine if the passed-in mask is empty.
func FixCpuMask(mask string, cores int) string {
if mask == "" {
if cores > 1 {
mask = fmt.Sprintf("0-%d", cores-1)
} else {
mask = "0"
}
}
return mask
}