psrinfo.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <kstat.h>
#include <libintl.h>
#include <locale.h>
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SYS_TEST"
#endif
/* spare, power-off */
/*
* Possible states that a cpu may be in, and their corresponding
* localized versions.
*/
static struct {
const char *state; /* State returned in kstat. */
const char *lstate; /* Localized version of the state. */
} cpu_states[NCPUSTATES];
static const char cmdname[] = "psrinfo";
static int chip_count = 0;
static int max_chip_id;
static struct chip {
int visible;
int online;
int core_count;
char impl[128];
char brand[128];
} *chips;
static void
{
gettext("usage: \n\t%s [-v] [-p] [processor_id ...]\n"
exit(2);
}
int
{
int c;
int phys_view = 0;
int errors = 0;
char *errptr;
(void) textdomain(TEXT_DOMAIN);
switch (c) {
case 'v':
verbosity |= 2;
break;
case 's':
verbosity &= ~1;
break;
case 'p':
phys_view = 1;
break;
default:
}
}
if (verbosity == 2)
exit(1);
}
/*
* Build localized cpu state table.
*/
if (phys_view) {
/*
* Note that we assume that MAX_CHIPID is <= MAX_CPUID.
* If this becomes untrue, a new sysconf() would be warranted.
*/
perror("calloc");
exit(1);
}
}
/*
* In the physical view, we want to display all the core info or
* none, even when the user specifies a range of CPUIDs. So for
* "psrinfo -pv <range>" or "psrinfo -ps <range>", we inventory
* every cpu_info kstat, and *then* we go through the user
* specified processors merely flipping on their "visible"
* flags.
*/
/*
* No processors specified. Report on all of them.
* Or do a complete inventory in preparation for a
* specified list of physical processors. See note
* immediately above.
*/
argc == 0);
}
if (argc != 0) {
/*
* Report on specified processors.
*/
/* individual processor id */
char cpubuf[20];
cpubuf))
phys_view, 1);
else {
gettext("%s: processor %s: %s\n"),
errors = 2;
}
} else {
/* range of processors */
int found = 0;
if (verbosity == 0) {
"one processor if -s used"));
}
if (*errptr++ != '-') {
gettext("%s: invalid processor "
errors = 2;
continue;
}
gettext("%s: invalid processor "
errors = 2;
continue;
}
found = 1;
phys_view, 1);
}
}
if (!found) {
gettext("%s: no processors in "
"range %d-%d\n"), cmdname,
}
}
}
}
if (phys_view) {
int i;
switch (verbosity) {
case 0:
/*
* Print "1" if all the cores on this chip are
* online. "0" otherwise.
*/
for (i = 0; i <= max_chip_id; i++) {
if (!c->visible)
continue;
(void) printf("%d\n",
c->online == c->core_count);
exit(0);
}
break;
case 1:
/*
* Print the number of unique chips represented by
* all the cores specified on the command line
* (or, with no args, all the cores in the system).
*/
break;
case 3:
/*
* Print a report on each chip.
*/
for (i = 0; i <= max_chip_id; i++) {
int j;
if (!c->visible)
continue;
"processor has %d virtual %s ("),
c->core_count,
c->core_count == 1 ?
gettext("processor") :
gettext("processors"));
for (j = 0; j < c->core_count; j++) {
if (j > 0)
(void) printf(", ");
}
(void) printf(")\n");
/*
* If the "brand" has already been embedded
* at the front of the "impl" string, don't
* print it out again .. otherwise give it
* a fresh line to bask upon ..
*/
}
break;
}
}
return (errors);
}
#define GETLONGSTR(name) \
/*
* Utility function to retrieve the localized version of the cpu state string.
*/
static const char *
get_cpu_state(const char *state)
{
int i;
for (i = 0; i < NCPUSTATES; i++)
return (cpu_states[i].lstate);
return (gettext("(unknown)"));
}
static void
int visible)
{
gettext("%s: kstat_read() failed for cpu %d: %s\n"),
exit(1);
}
if (phys_view) {
kstat_named_t *k =
struct chip *c;
if (k == NULL) {
gettext("%s: Physical processor view "
"not supported\n"),
cmdname);
exit(1);
}
/*
* We've already inventoried this chip. And the user
* specified a range of CPUIDs. So, now we just
* need to note that this is one of the chips to
* display.
*/
c->visible++;
return;
}
if (c->core_count == 0) {
char *str;
sizeof (c->impl));
sizeof (c->brand));
chip_count++;
}
c->core_count++;
if (visible)
c->visible++;
return;
}
if (verbosity == 0) {
return;
}
if (verbosity == 1) {
return;
}
if (GETLONG("clock_MHz") != 0)
else
"processor.\n"));
else
}