c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#! /usr/perl5/bin/perl
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# CDDL HEADER START
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# The contents of this file are subject to the terms of the
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Common Development and Distribution License (the "License").
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# You may not use this file except in compliance with the License.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# or http://www.opensolaris.org/os/licensing.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# See the License for the specific language governing permissions
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# and limitations under the License.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# When distributing Covered Code, include this CDDL HEADER in each
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# If applicable, add the following below this CDDL HEADER, with the
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# fields enclosed by brackets "[]" replaced with your own identifying
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# information: Portions Copyright [yyyy] [name of copyright owner]
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# CDDL HEADER END
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
7595fad9bab86562dbe8d6580c4b310bbad949b7akolb# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Use is subject to license terms.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# lgrpinfo: display information about locality groups.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
df0345f7d6cc87cde9e532e8362f1aca053d98ccJohn Sonnenscheinrequire 5.8.4;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse warnings;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse strict;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse Getopt::Long qw(:config no_ignore_case bundling auto_version);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse File::Basename;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Sun::Solaris::Kstat is used to extract per-lgroup load average.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse Sun::Solaris::Kstat;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse POSIX qw(locale_h);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse Sun::Solaris::Utils qw(textdomain gettext);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse Sun::Solaris::Lgrp ':CONSTANTS';
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse constant KB => 1024;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Amount of load contributed by a single thread. The value is exported by the
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# kernel in the 'loadscale' variable of lgroup kstat, but in case it is missing
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# we use the current default value as the best guess.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbuse constant LGRP_LOADAVG_THREAD_MAX => 65516;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get script name
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbour $cmdname = basename($0, ".pl");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get liblgrp version
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $version = Sun::Solaris::Lgrp::lgrp_version();
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbour $VERSION = "%I% (liblgrp version $version)";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# The $loads hash keeps per-lgroup load average.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbour $loads = {};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb########################################
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Main body
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb##
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Set message locale
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsetlocale(LC_ALL, "");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbtextdomain(TEXT_DOMAIN);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Parse command-line options
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbour($opt_a, $opt_l, $opt_m, $opt_c, $opt_C, $opt_e, $opt_t, $opt_h, $opt_u,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $opt_r, $opt_L, $opt_P, $opt_I, $opt_T, $opt_G);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbGetOptions("a" => \$opt_a,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "c" => \$opt_c,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "C" => \$opt_C,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "e" => \$opt_e,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "G" => \$opt_G,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "h|?" => \$opt_h,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "l" => \$opt_l,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "L" => \$opt_L,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "I" => \$opt_I,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "m" => \$opt_m,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "r" => \$opt_r,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "t" => \$opt_t,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "T" => \$opt_T,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "u=s" => \$opt_u,
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "P" => \$opt_P) || usage(3);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbusage(0) if $opt_h;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Check for conflicting options
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $nfilters = 0;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb$nfilters++ if $opt_C;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb$nfilters++ if $opt_P;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb$nfilters++ if $opt_T;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($nfilters > 1) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("%s: Options -C, -T and -P can not be used together\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb usage(3);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_T && ($opt_I || $opt_t)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("%s: Option -T can not be used with -I, -t\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb usage(3);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_T && scalar @ARGV) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("%s: Warning: with '-T' all lgroups on the command line "),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext("are ignored\n\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_L && $opt_I) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext("%s: Option -I can not be used with -L\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb usage(3);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Figure out what to do based on options
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_default = 1 unless
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $opt_a || $opt_l || $opt_m || $opt_c || $opt_e || $opt_t || $opt_r;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $l = Sun::Solaris::Lgrp->new($opt_G ? LGRP_VIEW_OS : LGRP_VIEW_CALLER) or
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb die(gettext("$cmdname: can not get lgroup information from the system\n"));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get list of all lgroups, the root and the list of intermediates
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy @lgrps = nsort($l->lgrps);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $root = $l->root;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy @intermediates = grep { $_ != $root && !$l->isleaf($_) } @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $is_uma = (scalar @lgrps == 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Print everything if -a is specified or it is default without -T
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_all = 1 if $opt_a || ($do_default && !($opt_T || $opt_L));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Print individual information if do_all or requested specific print
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_lat = 1 if $do_all || $opt_l;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_memory = 1 if $do_all || $opt_m;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_cpu = 1 if $do_all || $opt_c;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_topo = 1 if $do_all || $opt_t;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_rsrc = 1 if $do_all || $opt_r;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_load = 1 if $do_all || $opt_e;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_table = 1 if $opt_a || $opt_L;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $do_something = ($do_lat || $do_memory || $do_cpu || $do_topo ||
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $do_rsrc || $do_load);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Does the liblgrp(3LIB) has enough capabilities to support resource view?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($do_rsrc && LGRP_VER_CURRENT == 1) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($opt_r) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("%s: sorry, your system does not support"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR " lgrp_resources(3LGRP)\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $do_rsrc = 0;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get list of lgrps from arguments, expanding symbolic names like
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# "root" and "leaves"
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Use all lgroups if none are specified on the command line
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy @lgrp_list = (scalar (@ARGV) && !$opt_T) ? lgrp_expand($l, @ARGV) : @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Apply 'Parent' or 'Children' operations if requested
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb@lgrp_list = map { $l->parents($_) } @lgrp_list if $opt_P;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb@lgrp_list = map { $l->children($_) } @lgrp_list if $opt_C;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Drop repeating elements and sort lgroups numerically.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb@lgrp_list = uniqsort(@lgrp_list);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# If both -L and -c are specified, just print list of CPUs.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_c && $opt_I) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @cpus = uniqsort(map { $l->cpus($_, LGRP_CONTENT_HIERARCHY) }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb @lgrp_list);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "@cpus\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb exit(0);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $unit_str = "K";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy $units = KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Convert units to canonical numeric and string formats.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_u) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($opt_u =~ /^b$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = 1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "B";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^k$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "K";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^m$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB * KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "M";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^g$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB * KB * KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "G";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^t$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB * KB * KB * KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "T";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^p$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB * KB * KB * KB * KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "P";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($opt_u =~ /^e$/i) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $units = KB * KB * KB * KB * KB * KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $unit_str = "E";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif (! ($opt_u =~ /^m$/i)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("%s: invalid unit '$opt_u', should be [b|k|m|g|t|p|e]"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext(", using the default.\n\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $opt_u = 0;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Collect load average data if requested.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb$loads = get_lav() if $do_load;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get latency values for each lgroup.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmy %self_latencies;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbmap { $self_latencies{$_} = $l->latency($_, $_) } @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# If -T is specified, just print topology and return.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($opt_T) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb lgrp_prettyprint($l);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print_latency_table(\@lgrps, \@lgrps) if $do_table;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb exit(0);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif (!scalar @lgrp_list) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext("%s: No matching lgroups found!\n"), $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb exit(2);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Just print list of lgrps if doing just filtering
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb(print "@lgrp_list\n"), exit 0 if $opt_I;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbif ($do_something) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Walk through each requested lgrp and print whatever is requested.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $lgrp (@lgrp_list) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $is_leaf = $l->isleaf($lgrp);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my ($children, $parents, $cpus, $memstr, $rsrc);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $prefix = ($lgrp == $root) ?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "root": $is_leaf ? gettext("leaf") : gettext("intermediate");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf gettext("lgroup %d (%s):"), $lgrp, $prefix;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_topo) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Get children of this lgrp.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @children = $l->children($lgrp);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $children = $is_leaf ?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("Children: none") :
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("Children: ") . lgrp_collapse(@children);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Are there any parents for this lgrp?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @parents = $l->parents($lgrp);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $parents = @parents ?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(", Parent: ") . "@parents" :
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_cpu) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cpus = lgrp_showcpus($lgrp, LGRP_CONTENT_HIERARCHY);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_memory) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $memstr = lgrp_showmemory($lgrp, LGRP_CONTENT_HIERARCHY);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_rsrc) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $rsrc = lgrp_showresources($lgrp);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print all the information about lgrp.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n\t$children$parents" if $do_topo;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n\t$cpus" if $do_cpu && $cpus;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n\t$memstr" if $do_memory && $memstr;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n\t$rsrc" if $do_rsrc;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n\t$loads->{$lgrp}" if defined ($loads->{$lgrp});
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_lat && defined($self_latencies{$lgrp})) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf gettext("\n\tLatency: %d"), $self_latencies{$lgrp};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbprint_latency_table(\@lgrps, \@lgrp_list) if $do_table;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbexit 0;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# usage(exit_status)
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# print usage message and exit with the specified exit status.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub usage
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext("Usage:\t%s"), $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR " [-aceGlLmrt] [-u unit] [-C|-P] [lgrp] ...\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR " \t$cmdname -I [-c] [-G] [-C|-P] [lgrp] ...\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR " \t$cmdname -T [-aceGlLmr] [-u unit]\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR " \t$cmdname -h\n\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" Display information about locality groups\n\n" .
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "\t-a: Equivalent to \"%s\" without -T and to \"%s\" with -T\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "-celLmrt", "-celLmr";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-c: Print CPU information\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-C: Children of the specified lgroups\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-e: Print lgroup load average\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-h: Print this message and exit\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-I: Print lgroup or CPU IDs only\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-l: Print information about lgroup latencies\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-G: Print OS view of lgroup hierarchy\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-L: Print lgroup latency table\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-m: Print memory information\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-P: Parent(s) of the specified lgroups\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-r: Print lgroup resources\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-t: Print information about lgroup topology\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-T: Print the hierarchy tree\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("\t-u unit: Specify memory unit (b,k,m,g,t,p,e)\n\n\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" The lgrp may be specified as an lgroup ID,"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" \"root\", \"all\",\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" \"intermediate\" or \"leaves\".\n\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" The default set of options is \"%s\"\n\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "-celmrt all";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print STDERR
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext(" Without any options print topology, CPU and memory " .
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "information about each\n" .
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb " lgroup. If any lgroup IDs are specified on the " .
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb "command line only print\n" .
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb " information about the specified lgroup.\n\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb exit(shift);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Return the input list with duplicates removed.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub uniq
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my %seen;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (grep { ++$seen{$_} == 1 } @_);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Sort the list numerically
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Should be called in list context
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub nsort
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (sort { $a <=> $b } @_);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Sort list numerically and remove duplicates
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Should be called in list context
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub uniqsort
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (sort { $a <=> $b } uniq(@_));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Round values
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub round
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $val = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (int($val + 0.5));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Expand list of lgrps.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Translate 'root' to the root lgrp id
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Translate 'all' to the list of all lgrps
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Translate 'leaves' to the list of all lgrps'
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Translate 'intermediate' to the list of intermediates.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_expand
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lobj = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my %seen;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @result;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # create a hash element for every element in @lgrps
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { $seen{$_}++ } @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $lgrp (@_) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb push(@result, $lobj->root), next if $lgrp =~ m/^root$/i;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb push(@result, @lgrps), next if $lgrp =~ m/^all$/i;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb push(@result, $lobj->leaves), next if $lgrp =~ m/^leaves$/i;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb push(@result, @intermediates),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb next if $lgrp =~ m/^intermediate$/i;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb push(@result, $lgrp),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb next if $lgrp =~ m/^\d+$/ && $seen{$lgrp};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf STDERR gettext("%s: skipping invalid lgrp $lgrp\n"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cmdname;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return @result;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# lgrp_tree(class, node)
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Build the tree of the lgroup hierarchy starting with the specified node or
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# root if no initial node is specified. Calls itself recursively specifying each
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# of the children as a starting node. Builds a reference to the list with the
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# node in the end and each element being a subtree.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_tree
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $c = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp = shift || $c->root;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Call itself for each of the children and combine results in a list.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb [ (map { lgrp_tree($c, $_) } $c->children($lgrp)), $lgrp ];
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# lgrp_pp(tree, prefix, childprefix, npeers)
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# pretty-print the hierarchy tree.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Input Arguments:
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Reference to the tree
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Prefix for me to use
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Prefix for my children to use
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Number of peers left
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_pp
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $tree = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $myprefix = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $childprefix = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $npeers = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $el = pop @$tree;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $nchildren = scalar @$tree;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $printprefix = "$childprefix";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $printpostfix = $npeers ? "| " : " ";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return unless defined ($el);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $bar = $npeers ? "|" : "`";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print $childprefix ? $childprefix : "";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print $myprefix ? "$bar" . "-- " : "";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb lgrp_print($el, "$printprefix$printpostfix");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $new_prefix = $npeers ? $myprefix : " ";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Pretty-print the subtree with a new offset.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb lgrp_pp($_, "| ", "$childprefix$new_prefix", --$nchildren)
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } @$tree;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Pretty print the whole tree
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_prettyprint
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $c = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $tree = lgrp_tree $c;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb lgrp_pp($tree, '', '', scalar $tree - 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_print
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $prefix = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my ($cpus, $memstr, $rsrc);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $is_interm = ($lgrp != $root && !$l->isleaf($lgrp));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $not_root = $is_uma || $lgrp != $root;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "$lgrp";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_cpu && $not_root) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $cpus = lgrp_showcpus($lgrp, LGRP_CONTENT_HIERARCHY);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_memory && $not_root) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $memstr = lgrp_showmemory($lgrp, LGRP_CONTENT_HIERARCHY);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_rsrc && ($is_uma || $is_interm)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $rsrc = lgrp_showresources($lgrp) if $do_rsrc;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print all the information about lgrp.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n$prefix$cpus" if $cpus;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n$prefix$memstr" if $memstr;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n$prefix$rsrc" if $rsrc;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n$prefix$loads->{$lgrp}" if defined ($loads->{$lgrp});
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print latency information if requested.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($do_lat && $lgrp != $root && defined($self_latencies{$lgrp})) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n${prefix}";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf gettext("Latency: %d"), $self_latencies{$lgrp};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# What CPUs are in this lgrp?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_showcpus
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $hier = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @cpus = $l->cpus($lgrp, $hier);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $ncpus = @cpus;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return 0 unless $ncpus;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Sort CPU list if there is something to sort.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb @cpus = nsort(@cpus) if ($ncpus > 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $cpu_string = lgrp_collapse(@cpus);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (($ncpus == 1) ?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("CPU: ") . $cpu_string:
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb gettext("CPUs: ") . $cpu_string);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# How much memory does this lgrp contain?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_showmemory
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $hier = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $memory = $l->mem_size($lgrp, LGRP_MEM_SZ_INSTALLED, $hier);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (0) unless $memory;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $freemem = $l->mem_size($lgrp, LGRP_MEM_SZ_FREE, $hier) || 0;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $memory_r = memory_to_string($memory);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $freemem_r = memory_to_string($freemem);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $usedmem = memory_to_string($memory - $freemem);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $memstr = sprintf(gettext("Memory: installed %s"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $memory_r);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $memstr = $memstr . sprintf(gettext(", allocated %s"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $usedmem);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $memstr = $memstr . sprintf(gettext(", free %s"),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $freemem_r);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ($memstr);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Get string containing lgroup resources
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_showresources
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $rsrc_prefix = gettext("Lgroup resources:");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # What resources does this lgroup contain?
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @resources_cpu = nsort($l->resources($lgrp, LGRP_RSRC_CPU));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @resources_mem = nsort($l->resources($lgrp, LGRP_RSRC_MEM));
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $rsrc = @resources_cpu || @resources_mem ? "" : gettext("none");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $rsrc = $rsrc_prefix . $rsrc;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $rsrc_cpu = lgrp_collapse(@resources_cpu);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $rsrc_mem = lgrp_collapse(@resources_mem);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lcpu = gettext("CPU");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lmemory = gettext("memory");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $rsrc = "$rsrc $rsrc_cpu ($lcpu);" if scalar @resources_cpu;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $rsrc = "$rsrc $rsrc_mem ($lmemory)" if scalar @resources_mem;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ($rsrc);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Consolidate consequtive ids as start-end
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Input: list of ids
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Output: string with space-sepated cpu values with ranges
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# collapsed as x-y
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub lgrp_collapse
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ('') unless @_;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @args = uniqsort(@_);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $start = shift(@args);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $result = '';
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $end = $start; # Initial range consists of the first element
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $el (@args) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($el == ($end + 1)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Got consecutive ID, so extend end of range without
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # printing anything since the range may extend further
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $end = $el;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Next ID is not consecutive, so print IDs gotten so
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # far.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($end > $start + 1) { # range
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start-$end";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($end > $start) { # different values
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start $end";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else { # same value
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Try finding consecutive range starting from this ID
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $start = $end = $el;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print last ID(s)
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($end > $start + 1) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start-$end";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($end > $start) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start $end";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = "$result $start";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Remove any spaces in the beginning
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result =~ s/^\s+//;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ($result);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Print latency information if requested and the system has several lgroups.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub print_latency_table
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my ($lgrps1, $lgrps2) = @_;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return unless scalar @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Find maximum lgroup
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $max = $root;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { $max = $_ if $max < $_ } @$lgrps1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Field width for lgroup - the width of the largest lgroup and 1 space
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgwidth = length($max) + 1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Field width for latency. Get the maximum latency and add 1 space.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $width = length($l->latency($root, $root)) + 1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Make sure that width is enough to print lgroup itself.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $width = $lgwidth if $width < $lgwidth;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print table header
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print gettext("\nLgroup latencies:\n");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print horizontal line
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n", "-" x ($lgwidth + 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { print '-' x $width } @$lgrps1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n", " " x $lgwidth, "|";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { printf("%${width}d", $_) } @$lgrps1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n", "-" x ($lgwidth + 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { print '-' x $width } @$lgrps1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print the latency table
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $l1 (@$lgrps2) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf "%-${lgwidth}d|", $l1;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $l2 (@lgrps) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $latency = $l->latency($l1, $l2);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if (!defined ($latency)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf "%${width}s", "-";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb printf "%${width}d", $latency;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Print table footer
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "-" x ($lgwidth + 1);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb map { print '-' x $width } @lgrps;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb print "\n";
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Convert a number to a string representation
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# The number is scaled down until it is small enough to be in a good
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# human readable format i.e. in the range 0 thru 1023.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# If it's smaller than 10 there's room enough to provide one decimal place.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub number_to_scaled_string
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $number = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $scale = KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my @measurement = ('K', 'M', 'G', 'T', 'P', 'E'); # Measurement
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $uom = shift(@measurement);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $result;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
7595fad9bab86562dbe8d6580c4b310bbad949b7akolb my $save = $number;
7595fad9bab86562dbe8d6580c4b310bbad949b7akolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Get size in K.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $number /= KB;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb while (($number >= $scale) && $uom ne 'E') {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $uom = shift(@measurement);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $save = $number;
7595fad9bab86562dbe8d6580c4b310bbad949b7akolb $number /= $scale;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # check if we should output a decimal place after the point
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($save && (($save / $scale) < 10)) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = sprintf("%2.1f", $save / $scale);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = round($number);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ("$result$uom");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Convert memory size to the string representation
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub memory_to_string
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $number = shift;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Zero memory - just print 0
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ("0$unit_str") unless $number;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Return memory size scaled to human-readable form unless -u is
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # specified.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb #
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return (number_to_scaled_string($number)) unless $opt_u;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $scaled = $number / $units;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $result;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb if ($scaled < 0.1) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = sprintf("%2.1g", $scaled);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } elsif ($scaled < 10) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = sprintf("%2.1f", $scaled);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb } else {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $result = int($scaled + 0.5);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return ("$result$unit_str");
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# Read load averages from lgrp kstats Return hash reference indexed by lgroup ID
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb# for each lgroup which has load information.
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb#
c64027834c5ffc60c557c2b12555e0cd4d30320cakolbsub get_lav
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb{
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $load = {};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $ks = Sun::Solaris::Kstat->new(strip_strings => 1) or
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb warn(gettext("$cmdname: kstat_open() failed: %!\n")),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return $load;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lgrp_kstats = $ks->{lgrp} or
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb warn(gettext("$cmdname: can not read lgrp kstat\n)")),
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return $load;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Collect load for each lgroup
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb foreach my $i (keys %$lgrp_kstats) {
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb next unless $lgrp_kstats->{$i}->{"lgrp$i"};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $lav = $lgrp_kstats->{$i}->{"lgrp$i"}->{"load average"};
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb # Skip this lgroup if can't find its load average
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb next unless defined $lav;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb my $scale = $lgrp_kstats->{$i}->{"lgrp$i"}->{"loadscale"} ||
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb LGRP_LOADAVG_THREAD_MAX;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb $load->{$i} = sprintf (gettext("Load: %4.3g"), $lav / $scale);
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb }
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb return $load;
c64027834c5ffc60c557c2b12555e0cd4d30320cakolb}