#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
#
""" A thin wrapper around the kstats support provided by rad """
from __future__ import absolute_import
import rad.client as client
import rad.util as util
import os
_RAD_KSTAT_DOMAIN = "com.oracle.solaris.rad.kstat"
_RAD_KSTAT_MODULE = "/usr/lib/rad/module/kstat.so"
def index_kstat_named(ss):
"""
Given a list of kstat_named, returns a dictionary of its stats
indexed by name.
"""
return dict([(x.name, x.value) for x in ss])
class Kstats:
""" Represents the system's kstats """
ctlname = client.Name(_RAD_KSTAT_DOMAIN, [("type", "Control")])
def __init__(self, conn = None):
if conn is None:
self._rc = util.connect_unix()
else:
self._rc = conn
self._ctl = self._rc.get_object(Kstats.ctlname)
def __safe_wrap(self, name):
try:
return self._rc.get_object(name)
except:
pass
return None
@staticmethod
def connect_private():
"""
Create a connection to a private (piped) minimalist (kstat module
only) RAD instance.
Returns:
rad.client.RadConnection: the private connection
"""
return util.connect_private([ _RAD_KSTAT_MODULE ])
def lookup(self, module, name, instance):
"""
Look up a single kstat instance by module, name, and instance.
"""
return self._rc.get_object(
client.Name(_RAD_KSTAT_DOMAIN, [("type", "Kstat"),
("module", module), ("name", name),
("instance", "%d" % instance)]))
def lookup_many(self, module = None, name = None, instance = None,
clazz = None):
"""
Retrieve a list of kstat instances, filtered by optional module, name,
and instance.
"""
keys = [("type", "Kstat")]
if module is not None:
keys.append(("module", module))
if name is not None:
keys.append(("name", name))
if instance is not None:
keys.append(("instance", "%d" % instance))
if clazz is not None:
keys.append(("klass", clazz))
o = self._rc.list_objects(client.Name(_RAD_KSTAT_DOMAIN, keys))
# Enumeration and lookup can race; silently drop failures
return filter (lambda x : x is not None,
[ self.__safe_wrap(name) for name in o ])
def update(self):
""" Call update() on the singleton control instance """
self._ctl.update()
def close(self):
""" Close the connection to the RAD server """
self._rc.close()