#! /usr/bin/python
# -*- python -*-
# -*- coding: utf-8 -*-
#
# Copyright (C) 2007-2015 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

import os, time, utilist

VERSION="0.3"

def process_cmdline(pid_info):
	"""
	Returns the process command line, if available in the given `process' class, if
	not available, falls back to using the comm (short process name) in its pidstat key.
	"""
	if pid_info["cmdline"]:
		return reduce(lambda a, b: a + " %s" % b, pid_info["cmdline"]).strip()

	return pid_info["stat"]["comm"]

class pidstat:
	"""Provides a dictionary to access the fields in the per process /proc/PID/stat
	   files.

	   One can obtain the available fields asking for the keys of the dictionary, e.g.:

		>>> p = procfs.pidstat(1)
		>>> print p.keys()
		['majflt', 'rss', 'cnswap', 'cstime', 'pid', 'session', 'startstack', 'startcode', 'cmajflt', 'blocked', 'exit_signal', 'minflt', 'nswap', 'environ', 'priority', 'state', 'delayacct_blkio_ticks', 'policy', 'rt_priority', 'ppid', 'nice', 'cutime', 'endcode', 'wchan', 'num_threads', 'sigcatch', 'comm', 'stime', 'sigignore', 'tty_nr', 'kstkeip', 'utime', 'tpgid', 'itrealvalue', 'kstkesp', 'rlim', 'signal', 'pgrp', 'flags', 'starttime', 'cminflt', 'vsize', 'processor']

	   And then access the various process properties using it as a dictionary:

		>>> print p['comm']
		systemd
		>>> print p['priority']
		20
		>>> print p['state']
		S

	   Please refer to the 'procfs(5)' man page, by using:

		$ man 5 procfs

	   To see information for each of the above fields, it is part of the
           'man-pages' RPM package.
	"""

	# Entries with the same value, the one with a comment after it is the
	# more recent, having replaced the other name in v4.1-rc kernel times.

	PF_ALIGNWARN	 = 0x00000001
	PF_STARTING	 = 0x00000002
	PF_EXITING	 = 0x00000004
	PF_EXITPIDONE	 = 0x00000008
	PF_VCPU		 = 0x00000010
	PF_WQ_WORKER	 = 0x00000020 # /* I'm a workqueue worker */
	PF_FORKNOEXEC	 = 0x00000040
	PF_MCE_PROCESS	 = 0x00000080 # /* process policy on mce errors */
	PF_SUPERPRIV	 = 0x00000100
	PF_DUMPCORE	 = 0x00000200
	PF_SIGNALED	 = 0x00000400
	PF_MEMALLOC	 = 0x00000800
	PF_NPROC_EXCEEDED= 0x00001000 # /* set_user noticed that RLIMIT_NPROC was exceeded */
	PF_FLUSHER	 = 0x00001000
	PF_USED_MATH	 = 0x00002000
	PF_USED_ASYNC	 = 0x00004000 # /* used async_schedule*(), used by module init */
	PF_NOFREEZE	 = 0x00008000
	PF_FROZEN	 = 0x00010000
	PF_FSTRANS	 = 0x00020000
	PF_KSWAPD	 = 0x00040000
	PF_MEMALLOC_NOIO = 0x00080000 # /* Allocating memory without IO involved */
	PF_SWAPOFF	 = 0x00080000
	PF_LESS_THROTTLE = 0x00100000
	PF_KTHREAD	 = 0x00200000
	PF_RANDOMIZE	 = 0x00400000
	PF_SWAPWRITE	 = 0x00800000
	PF_SPREAD_PAGE	 = 0x01000000
	PF_SPREAD_SLAB	 = 0x02000000
	PF_THREAD_BOUND	 = 0x04000000
	PF_NO_SETAFFINITY = 0x04000000 # /* Userland is not allowed to meddle with cpus_allowed */
	PF_MCE_EARLY	 = 0x08000000 # /* Early kill for mce process policy */
	PF_MEMPOLICY	 = 0x10000000
	PF_MUTEX_TESTER	 = 0x20000000
	PF_FREEZER_SKIP	 = 0x40000000
	PF_FREEZER_NOSIG = 0x80000000
	PF_SUSPEND_TASK	 = 0x80000000 # /* this thread called freeze_processes and should not be frozen */

	proc_stat_fields = [ "pid", "comm", "state", "ppid", "pgrp", "session",
			     "tty_nr", "tpgid", "flags", "minflt", "cminflt",
			     "majflt", "cmajflt", "utime", "stime", "cutime",
			     "cstime", "priority", "nice", "num_threads",
			     "itrealvalue", "starttime", "vsize", "rss",
			     "rlim", "startcode", "endcode", "startstack",
			     "kstkesp", "kstkeip", "signal", "blocked",
			     "sigignore", "sigcatch", "wchan", "nswap",
			     "cnswap", "exit_signal", "processor",
			     "rt_priority", "policy",
			     "delayacct_blkio_ticks", "environ" ]

	def __init__(self, pid, basedir = "/proc"):
		self.pid = pid
		self.load(basedir)

	def __getitem__(self, fieldname):
		return self.fields[fieldname]

	def keys(self):
		return self.fields.keys()

	def values(self):
		return self.fields.values()

	def has_key(self, fieldname):
		return self.fields.has_key(fieldname)

	def items(self):
		return self.fields

	def __contains__(self, fieldname):
		return fieldname in self.fields

	def load(self, basedir = "/proc"):
		f = open("%s/%d/stat" % (basedir, self.pid))
		fields = f.readline().strip().split(') ')
		f.close()
		fields = fields[0].split(' (') + fields[1].split()
		self.fields = {}
		nr_fields = min(len(fields), len(self.proc_stat_fields))
		for i in range(nr_fields):
			attrname = self.proc_stat_fields[i]
			value = fields[i]
			if attrname == "comm":
				self.fields["comm"] = value.strip('()')
			else:
				try:
					self.fields[attrname] = int(value)
				except:
					self.fields[attrname] = value

	def is_bound_to_cpu(self):
		"""
		Returns true if this process has a fixed smp affinity mask,
                not allowing it to be moved to a different set of CPUs.
		"""
		return self.fields["flags"] & self.PF_THREAD_BOUND and \
			True or False

	def process_flags(self):
		"""
		Returns a list with all the process flags known, details depend
		on kernel version, declared in the file include/linux/sched.h in
		the kernel sources.

		As of v4.2-rc7 these include (from include/linux/sched.h comments):

			PF_EXITING	   Getting shut down
			PF_EXITPIDONE	   Pi exit done on shut down
			PF_VCPU		   I'm a virtual CPU
			PF_WQ_WORKER	   I'm a workqueue worker
			PF_FORKNOEXEC	   Forked but didn't exec
			PF_MCE_PROCESS	   Process policy on mce errors
			PF_SUPERPRIV	   Used super-user privileges
			PF_DUMPCORE	   Dumped core
			PF_SIGNALED	   Killed by a signal
			PF_MEMALLOC	   Allocating memory
			PF_NPROC_EXCEEDED  Set_user noticed that RLIMIT_NPROC was exceeded
			PF_USED_MATH	   If unset the fpu must be initialized before use
			PF_USED_ASYNC	   Used async_schedule*(), used by module init
			PF_NOFREEZE	   This thread should not be frozen
			PF_FROZEN	   Frozen for system suspend
			PF_FSTRANS	   Inside a filesystem transaction
			PF_KSWAPD	   I am kswapd
			PF_MEMALLOC_NOIO   Allocating memory without IO involved
			PF_LESS_THROTTLE   Throttle me less: I clean memory
			PF_KTHREAD	   I am a kernel thread
			PF_RANDOMIZE	   Randomize virtual address space
			PF_SWAPWRITE	   Allowed to write to swap
			PF_NO_SETAFFINITY  Userland is not allowed to meddle with cpus_allowed
			PF_MCE_EARLY	   Early kill for mce process policy
			PF_MUTEX_TESTER	   Thread belongs to the rt mutex tester
			PF_FREEZER_SKIP	   Freezer should not count it as freezable
			PF_SUSPEND_TASK	   This thread called freeze_processes and should not be frozen
	
		"""
		sflags = []
		for attr in dir(self):
			if attr[:3] != "PF_":
				continue
			value = getattr(self, attr)
			if value & self.fields["flags"]:
				sflags.append(attr)

		return sflags

class pidstatus:
	"""
	Provides a dictionary to access the fields in the per process /proc/PID/status
	files. This provides additional information about processes and threads to what
	can be obtained with the procfs.pidstat() class.

	One can obtain the available fields asking for the keys of the dictionary, e.g.:

		>>> import procfs
		>>> p = procfs.pidstatus(1)
		>>> print p.keys()
		['VmExe', 'CapBnd', 'NSpgid', 'Tgid', 'NSpid', 'VmSize', 'VmPMD', 'ShdPnd', 'State', 'Gid', 'nonvoluntary_ctxt_switches', 'SigIgn', 'VmStk', 'VmData', 'SigCgt', 'CapEff', 'VmPTE', 'Groups', 'NStgid', 'Threads', 'PPid', 'VmHWM', 'NSsid', 'VmSwap', 'Name', 'SigBlk', 'Mems_allowed_list', 'VmPeak', 'Ngid', 'VmLck', 'SigQ', 'VmPin', 'Mems_allowed', 'CapPrm', 'Seccomp', 'VmLib', 'Cpus_allowed', 'Uid', 'SigPnd', 'Pid', 'Cpus_allowed_list', 'TracerPid', 'CapInh', 'voluntary_ctxt_switches', 'VmRSS', 'FDSize']
		>>> print p["Pid"]
		1
		>>> print p["Threads"]
		1
		>>> print p["VmExe"]
		1248 kB
		>>> print p["Cpus_allowed"]
		f
		>>> print p["SigQ"]
		0/30698
		>>> print p["VmPeak"]
		320300 kB
		>>>

	Please refer to the 'procfs(5)' man page, by using:

		$ man 5 procfs

	To see information for each of the above fields, it is part of the
	'man-pages' RPM package.

	In the man page there will be references to further documentation, like
        referring to the "getrlimit(2)" man page when explaining the "SigQ"
        line/field.
	"""

	def __init__(self, pid, basedir = "/proc"):
		self.pid = pid
		self.load(basedir)

	def __getitem__(self, fieldname):
		return self.fields[fieldname]

	def keys(self):
		return self.fields.keys()

	def values(self):
		return self.fields.values()

	def has_key(self, fieldname):
		return self.fields.has_key(fieldname)

	def items(self):
		return self.fields

	def __contains__(self, fieldname):
		return fieldname in self.fields

	def load(self, basedir = "/proc"):
		f = open("%s/%d/status" % (basedir, self.pid))
		self.fields = {}
		for line in f.readlines():
			fields = line.split(":")
			if len(fields) != 2:
				continue
			name = fields[0]
			value = fields[1].strip()
			try:
				self.fields[name] = int(value)
			except:
				self.fields[name] = value
		f.close()

class process:
	"""
	Information about a process with a given pid, provides a dictionary with
	two entries, instances of different wrappers for /proc/ process related
	meta files: "stat" and "status", see the documentation for procfs.pidstat
	and procfs.pidstatus for further info about those classes.
	"""

	def __init__(self, pid, basedir = "/proc"):
		self.pid = pid
		self.basedir = basedir

	def __getitem__(self, attr):
		if not hasattr(self, attr):
			if attr in ("stat", "status"):
				if attr == "stat":
					sclass = pidstat
				else:
					sclass = pidstatus

				setattr(self, attr, sclass(self.pid, self.basedir))
			elif attr == "cmdline":
				self.load_cmdline()
			elif attr == "threads":
				self.load_threads()
			elif attr == "cgroups":
				self.load_cgroups()
			elif attr == "environ":
				self.load_environ()

		return getattr(self, attr)

	def has_key(self, attr):
		return hasattr(self, attr)

	def __contains__(self, attr):
		return hasattr(self, attr)

	def load_cmdline(self):
		f = file("/proc/%d/cmdline" % self.pid)
		self.cmdline = f.readline().strip().split('\0')[:-1]
		f.close()

	def load_threads(self):
		self.threads = pidstats("/proc/%d/task/" % self.pid)
		# remove thread leader
		del self.threads[self.pid]

	def load_cgroups(self):
		f = file("/proc/%d/cgroup" % self.pid)
		self.cgroups = ""
		for line in reversed(f.readlines()):
			if len(self.cgroups):
				self.cgroups = self.cgroups + "," + line[:-1]
			else:
				self.cgroups = line[:-1]
		f.close()

	def load_environ(self):
		"""
		Loads the environment variables for this process. The entries then
		become available via the 'environ' member, or via the 'environ'
		dict key when accessing as p["environ"].

		E.g.:


		>>> all_processes = procfs.pidstats()
		>>> firefox_pid = all_processes.find_by_name("firefox")
		>>> firefox_process = all_processes[firefox_pid[0]]
		>>> print firefox_process["environ"]["PWD"]
		/home/acme
		>>> print len(firefox_process.environ.keys())
		66
		>>> print firefox_process["environ"]["SHELL"]
		/bin/bash
		>>> print firefox_process["environ"]["USERNAME"]
		acme
		>>> print firefox_process["environ"]["HOME"]
		/home/acme
		>>> print firefox_process["environ"]["MAIL"]
		/var/spool/mail/acme
		>>>
		"""
		self.environ = {}
		f = file("/proc/%d/environ" % self.pid)
		for x in f.readline().split('\0'):
			if len(x) > 0:
				y = x.split('=')
				self.environ[y[0]] = y[1]
		f.close()

class pidstats:
	"""
	Provides access to all the processes in the system, to get a picture of
	how many processes there are at any given moment.

	The entries can be accessed as a dictionary, keyed by pid. Also there are
	methods to find processes that match a given COMM or regular expression.
	"""
	def __init__(self, basedir = "/proc"):
		self.basedir = basedir
		self.processes = {}
		self.reload()

	def __getitem__(self, key):
		return self.processes[key]

	def __delitem__(self, key):
		# not clear on why this can fail, but it can
		try:
			del self.processes[key]
		except:
			pass

	def keys(self):
		return self.processes.keys()

	def values(self):
		return self.processes.values()

	def has_key(self, key):
		return self.processes.has_key(key)

	def items(self):
		return self.processes

	def __contains__(self, key):
		return key in self.processes

	def reload(self):
	"""
	This operation will trow away the current dictionary contents, if any, and
	read all the pid files from /proc/, instantiating a 'process' instance for
	each of them.

	This is a high overhead operation, and should be avoided if the perf python
	binding can be used to detect when new threads appear and existing ones
	terminate.

	In RHEL it is found in the python-perf rpm package.

	More information about the perf facilities can be found in the 'perf_event_open'
	man page.
	"""
		del self.processes
		self.processes = {}
		pids = os.listdir(self.basedir)
		for spid in pids:
			try:
				pid = int(spid)
			except:
				continue

			self.processes[pid] = process(pid, self.basedir)

	def reload_threads(self):
		for pid in self.processes.keys():
			try:
				self.processes[pid].load_threads()
			except OSError:
				# process vanished, remove it
				del self.processes[pid]

	def find_by_name(self, name):
		name = name[:15]
		pids = []
		for pid in self.processes.keys():
			try:
				if name == self.processes[pid]["stat"]["comm"]:
					pids.append(pid)
			except IOError:
				# We're doing lazy loading of /proc files
				# So if we get this exception is because the
				# process vanished, remove it
				del self.processes[pid]
				
		return pids

	def find_by_regex(self, regex):
		pids = []
		for pid in self.processes.keys():
			try:
				if regex.match(self.processes[pid]["stat"]["comm"]):
					pids.append(pid)
			except IOError:
				# We're doing lazy loading of /proc files
				# So if we get this exception is because the
				# process vanished, remove it
				del self.processes[pid]
		return pids

	def find_by_cmdline_regex(self, regex):
		pids = []
		for pid in self.processes.keys():
			try:
				if regex.match(process_cmdline(self.processes[pid])):
					pids.append(pid)
			except IOError:
				# We're doing lazy loading of /proc files
				# So if we get this exception is because the
				# process vanished, remove it
				del self.processes[pid]
		return pids

	def get_per_cpu_rtprios(self, basename):
		cpu = 0
		priorities=""
		processed_pids = []
		while True:
			name = "%s/%d" % (basename, cpu)
			pids = self.find_by_name(name)
			if not pids or len([n for n in pids if n not in processed_pids]) == 0:
				break
			for pid in pids:
				try:
					priorities += "%s," % self.processes[pid]["stat"]["rt_priority"]
				except IOError:
					# We're doing lazy loading of /proc files
					# So if we get this exception is because the
					# process vanished, remove it
					del self.processes[pid]
			processed_pids += pids
			cpu += 1

		priorities = priorities.strip(',')
		return priorities

	def get_rtprios(self, name):
		cpu = 0
		priorities=""
		processed_pids = []
		while True:
			pids = self.find_by_name(name)
			if not pids or len([n for n in pids if n not in processed_pids]) == 0:
				break
			for pid in pids:
				try:
					priorities += "%s," % self.processes[pid]["stat"]["rt_priority"]
				except IOError:
					# We're doing lazy loading of /proc files
					# So if we get this exception is because the
					# process vanished, remove it
					del self.processes[pid]
			processed_pids += pids
			cpu += 1

		priorities = priorities.strip(',')
		return priorities

	def is_bound_to_cpu(self, pid):
		"""
		Checks if a given pid can't have its SMP affinity mask changed.
		"""
		return self.processes[pid]["stat"].is_bound_to_cpu()

class interrupts:
	"""
	Information about IRQs in the system. A dictionary keyed by IRQ number
	will have as its value another dictionary with "cpu", "type" and "users"
	keys, with the SMP affinity mask, type of IRQ and the drivers associated
	with each interrupt.

	The information comes from the /proc/interrupts file, documented in
	'man procfs(5)', for instance, the 'cpu' dict is an array with one entry
	per CPU present in the sistem, each value being the number of interrupts
	that took place per CPU.

	E.g.:

	>>> import procfs
	>>> interrupts = procfs.interrupts()
	>>> thunderbolt_irq = interrupts.find_by_user("thunderbolt")
	>>> print thunderbolt_irq
	34
	>>> thunderbolt = interrupts[thunderbolt_irq]
	>>> print thunderbolt
	{'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI', 'cpu': [3495, 0, 81, 0], 'users': ['thunderbolt']}
	>>>
	"""
	def __init__(self):
		self.interrupts = {}
		self.reload()

	def __getitem__(self, key):
		return self.interrupts[str(key)]

	def keys(self):
		return self.interrupts.keys()

	def values(self):
		return self.interrupts.values()

	def has_key(self, key):
		return self.interrupts.has_key(str(key))

	def items(self):
		return self.interrupts

	def __contains__(self, key):
		return str(key) in self.interrupts

	def reload(self):
		del self.interrupts
		self.interrupts = {}
		f = open("/proc/interrupts")

		for line in f.readlines():
			line = line.strip()
			fields = line.split()
			if fields[0][:3] == "CPU":
				self.nr_cpus = len(fields)
				continue
			irq = fields[0].strip(":")
			self.interrupts[irq] = {}
			self.interrupts[irq] = self.parse_entry(fields[1:], line)
			try:
				nirq = int(irq)
			except:
				continue
			self.interrupts[irq]["affinity"] = self.parse_affinity(nirq)

		f.close()

	def parse_entry(self, fields, line):
		dict = {}
		dict["cpu"] = []
		dict["cpu"].append(int(fields[0]))
		nr_fields = len(fields)
		if nr_fields >= self.nr_cpus:
			dict["cpu"] += [int(i) for i in fields[1:self.nr_cpus]]
			if nr_fields > self.nr_cpus:
				dict["type"] = fields[self.nr_cpus]
				# look if there are users (interrupts 3 and 4 haven't)
				if nr_fields > self.nr_cpus + 1:
					dict["users"] = [a.strip() for a in fields[nr_fields - 1].split(',')]
				else:
					dict["users"] = []
		return dict

	def parse_affinity(self, irq):
		try:
			f = file("/proc/irq/%s/smp_affinity" % irq)
			line = f.readline()
			f.close()
			return utilist.bitmasklist(line, self.nr_cpus)
		except IOError:
			return [ 0, ]

	def find_by_user(self, user):
		"""
		Looks up a interrupt number by the name of one of its users"

		E.g.:

		>>> import procfs
		>>> interrupts = procfs.interrupts()
		>>> thunderbolt_irq = interrupts.find_by_user("thunderbolt")
		>>> print thunderbolt_irq
		34
		>>> thunderbolt = interrupts[thunderbolt_irq]
		>>> print thunderbolt
		{'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI', 'cpu': [3495, 0, 81, 0], 'users': ['thunderbolt']}
		>>>
		"""
		for i in self.interrupts.keys():
			if self.interrupts[i].has_key("users") and \
			   user in self.interrupts[i]["users"]:
				return i
		return None

	def find_by_user_regex(self, regex):
		"""
		Looks up a interrupt number by a regex that matches names of its users"

		E.g.:

		>>> import procfs
		>>> import re
		>>> interrupts = procfs.interrupts()
		>>> usb_controllers = interrupts.find_by_user_regex(re.compile(".*hcd"))
		>>> print usb_controllers
		['22', '23', '31']
		>>> print [ interrupts[irq]["users"] for irq in usb_controllers ]
		[['ehci_hcd:usb4'], ['ehci_hcd:usb3'], ['xhci_hcd']]
		>>>
		"""
		irqs = []
		for i in self.interrupts.keys():
			if not self.interrupts[i].has_key("users"):
				continue
			for user in self.interrupts[i]["users"]:
				if regex.match(user):
					irqs.append(i)
					break
		return irqs

class cmdline:
	"""
	Parses the kernel command line (/proc/cmdline), turning it into a dictionary."

	Useful to figure out if some kernel boolean knob has been turned on, as well
	as to find the value associated to other kernel knobs.

	It can also be used to find out about parameters passed to the init process,
	such as 'BOOT_IMAGE', etc.

	E.g.:
	>>> import procfs
	>>> kcmd = procfs.cmdline()
	>>> print kcmd.keys()
	['LANG', 'BOOT_IMAGE', 'quiet', 'rhgb', 'rd.lvm.lv', 'ro', 'root']
	>>> print kcmd["BOOT_IMAGE"]
	/vmlinuz-4.3.0-rc1+
	>>>
	"""

	def __init__(self):
		self.options = {}
		self.parse()

	def parse(self):
		f = file("/proc/cmdline")
		for option in f.readline().strip().split():
			fields = option.split("=")
			if len(fields) == 1:
				self.options[fields[0]] = True
			else:
				self.options[fields[0]] = fields[1]

		f.close()

	def __getitem__(self, key):
		return self.options[key]

	def keys(self):
		return self.options.keys()

	def values(self):
		return self.options.values()

	def items(self):
		return self.options

class cpuinfo:
	"""
	Dictionary with information about CPUs in the system.

	Please refer to 'man procfs(5)' for further information about the
        '/proc/cpuinfo' file, that is the source of the information provided by this
        class. The 'man lscpu(1)' also has information about a program that uses
	the '/proc/cpuinfo' file.

	Using this class one can obtain the number of CPUs in a system:

	  >>> cpus = procfs.cpuinfo()
          >>> print cpus.nr_cpus
          4

	It is also possible to figure out aspects of the CPU topology, such as
	how many CPU physical sockets exists, i.e. groups of CPUs sharing components
	such as CPU memory caches:

	  >>> print len(cpus.sockets)
	  1

	Additionally dictionary with information common to all CPUs in the system is
	available:

	  >>> print cpus["model name"]
          Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz
          >>> print cpus["cache size"]
          4096 KB
          >>>
	"""
	def __init__(self, filename="/proc/cpuinfo"):
		self.tags = {}
		self.nr_cpus = 0
		self.sockets = []
		self.parse(filename)

	def __getitem__(self, key):
		return self.tags[key.lower()]

	def keys(self):
		return self.tags.keys()

	def values(self):
		return self.tags.values()

	def items(self):
		return self.tags

	def parse(self, filename):
		f = file(filename)
		for line in f.readlines():
			line = line.strip()
			if len(line) == 0:
				continue
			fields = line.split(":")
			tagname = fields[0].strip().lower()
			if tagname == "processor":
				self.nr_cpus += 1
				continue
			elif tagname == "core id":
				continue
			self.tags[tagname] = fields[1].strip()
			if tagname == "physical id":
				socket_id = self.tags[tagname]
				if socket_id not in self.sockets:
					self.sockets.append(socket_id)

		f.close()
		self.nr_sockets = self.sockets and len(self.sockets) or \
				  (self.nr_cpus / ("siblings" in self.tags and int(self.tags["siblings"]) or 1))
		self.nr_cores = ("cpu cores" in self.tags and int(self.tags["cpu cores"]) or 1) * self.nr_sockets

class smaps_lib:
	"""
	Representation of an mmap in place for a process. Can be used to figure
	out which processes have an library mapped, etc.

	The 'perm' member can be used to figure out executable mmaps, i.e. libraries.

	The 'vm_start' and 'vm_end' in turn can be used when trying to resolve
	processor instruction pointer addresses to a symbol name in a library.
	"""
	def __init__(self, lines):
		fields = lines[0].split()
		self.vm_start, self.vm_end = map(lambda a: int(a, 16), fields[0].split("-"))
		self.perms = fields[1]
		self.offset = int(fields[2], 16)
		self.major, self.minor = fields[3].split(":")
		self.inode = int(fields[4])
		if len(fields) > 5:
			self.name = fields[5]
		else:
			self.name = None
		self.tags = {}
		for line in lines[1:]:
			fields = line.split()
			tag = fields[0][:-1].lower()
			try:
				self.tags[tag] = int(fields[1])
			except:
				# VmFlags are strings
				self.tags[tag] = fields

	def __getitem__(self, key):
		return self.tags[key.lower()]

	def keys(self):
		return self.tags.keys()

	def values(self):
		return self.tags.values()

	def items(self):
		return self.tags


class smaps:
	"""
	List of libraries mapped by a process. Parses the lines in
	the /proc/PID/smaps file, that is further documented in the
	procfs(5) man page.

	Example: Listing the executable maps for the 'sshd' process:

          >>> import procfs
          >>> processes = procfs.pidstats()
          >>> sshd = processes.find_by_name("sshd")
          >>> sshd_maps = procfs.smaps(sshd[0])
          >>> for i in range(len(sshd_maps)):
          ...     if 'x' in sshd_maps[i].perms:
          ...         print "%s: %s" % (sshd_maps[i].name, sshd_maps[i].perms)
          ...
          /usr/sbin/sshd: r-xp
          /usr/lib64/libnss_files-2.20.so: r-xp
          /usr/lib64/librt-2.20.so: r-xp
          /usr/lib64/libkeyutils.so.1.5: r-xp
          /usr/lib64/libkrb5support.so.0.1: r-xp
          /usr/lib64/libfreebl3.so: r-xp
          /usr/lib64/libpthread-2.20.so: r-xp
	  ...
	"""
	def __init__(self, pid):
		self.pid = pid
		self.entries = []
		self.reload()

	def parse_entry(self, f, line):
		lines = []
		if not line:
			line = f.readline().strip()
		if not line:
			return
		lines.append(line)
		while True:
			line = f.readline()
			if not line:
				break
			line = line.strip()
			if line.split()[0][-1] == ':':
				lines.append(line)
			else:
				break
		self.entries.append(smaps_lib(lines))
		return line

	def __len__(self):
		return len(self.entries)

	def __getitem__(self, index):
		return self.entries[index]

	def reload(self):
		f = file("/proc/%d/smaps" % self.pid)
		line = None
		while True:
			line = self.parse_entry(f, line)
			if not line:
				break
		f.close()
		self.nr_entries = len(self.entries)

	def find_by_name_fragment(self, fragment):
		result = []
		for i in range(self.nr_entries):
			if self.entries[i].name and \
			   self.entries[i].name.find(fragment) >= 0:
			   	result.append(self.entries[i])
				
		return result

class cpustat:
	"""
	CPU statistics, obtained from a line in the '/proc/stat' file, Please
	refer to 'man procfs(5)' for further information about the '/proc/stat'
	file, that is the source of the information provided by this class.
	"""

	def __init__(self, fields):
		self.name = fields[0]
		(self.user,
		 self.nice,
		 self.system,
		 self.idle,
		 self.iowait,
		 self.irq,
		 self.softirq) = [int(i) for i in fields[1:8]]
		if len(fields) > 7:
			self.steal = int(fields[7])
			if len(fields) > 8:
				self.guest = int(fields[8])

	def __repr__(self):
		s = "< user: %s, nice: %s, system: %s, idle: %s, iowait: %s, irq: %s, softirq: %s" % \
			(self.user, self.nice, self.system, self.idle, self.iowait, self.irq, self.softirq)
		if hasattr(self, 'steal'):
			s += ", steal: %d" % self.steal
		if hasattr(self, 'guest'):
			s += ", guest: %d" % self.guest
		return s + ">"

class cpusstats:
	"""
	Dictionary with information about CPUs in the system. First entry in the
	dictionary gives an aggregate view of all CPUs, each other entry is about
	separate CPUs. Please refer to 'man procfs(5)' for further information
	about the '/proc/stat' file, that is the source of the information provided
	by this class.
	"""
	def __init__(self, filename = "/proc/stat"):
		self.entries = {}
		self.time = None
		self.hertz = os.sysconf(2)
		self.filename = filename
		self.reload()

	def __iter__(self):
		return iter(self.entries)

	def __getitem__(self, key):
		return self.entries[key]

	def __len__(self):
		return len(self.entries.keys())

	def keys(self):
		return self.entries.keys()

	def values(self):
		return self.entries.values()

	def items(self):
		return self.entries

	def reload(self):
		last_entries = self.entries
		self.entries = {}
		f = file(self.filename)
		for line in f.readlines():
			fields = line.strip().split()
			if fields[0][:3].lower() != "cpu":
				continue
			c = cpustat(fields)
			if c.name == "cpu":
				idx = 0
			else:
				idx = int(c.name[3:]) + 1
			self.entries[idx] = c
		f.close()
		last_time = self.time
		self.time = time.time()
		if last_entries:
			delta_sec = self.time - last_time
			interval_hz = delta_sec * self.hertz
			for cpu in self.entries.keys():
				if cpu not in last_entries:
					curr.usage = 0
					continue
				curr = self.entries[cpu]
				prev = last_entries[cpu]
				delta = (curr.user - prev.user) + \
					(curr.nice - prev.nice) + \
					(curr.system - prev.system)
				curr.usage = (delta / interval_hz) * 100
				if curr.usage > 100:
					curr.usage = 100

if __name__ == '__main__':
	import sys

	ints = interrupts()

	for i in ints.interrupts.keys():
		print "%s: %s" % (i, ints.interrupts[i])

	options = cmdline()
	for o in options.options.keys():
		print "%s: %s" % (o, options.options[o])

	cpu = cpuinfo()
	print "\ncpuinfo data: %d processors" % cpu.nr_cpus
	for tag in cpu.keys():
		print "%s=%s" % (tag, cpu[tag])

	print "smaps:\n" + ("-" * 40)
	s = smaps(int(sys.argv[1]))
	for i in range(s.nr_entries):
		print "%#x %s" % (s.entries[i].vm_start, s.entries[i].name)
	print "-" * 40
	for a in s.find_by_name_fragment(sys.argv[2]):
		print a["Size"]

	ps = pidstats()
	print ps[1]

	cs = cpusstats()
	while True:
		time.sleep(1)
		cs.reload()
		for cpu in cs:
			print "%s: %d" % (cpu.name, cpu.usage)
		print "-" * 10
