4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
30 #include <sys/procset.h>
31 #include <sys/processor.h>
42 static char *cmdname
; /* command name for messages */
44 static char verbose
; /* non-zero if the -v option has been given */
45 static char all_flag
; /* non-zero if the -a option has been given */
46 static char force
; /* non-zero if the -F option has been given */
47 static char log_open
; /* non-zero if openlog() has been called */
49 static struct utmpx ut
; /* structure for logging to /etc/wtmpx. */
51 static char *basename(char *);
56 (void) fprintf(stderr
,
57 "usage: \n\t%s [-F] -f|-n|-i|-s [-v] processor_id ...\n"
58 "\t%s -a -f|-n|-i [-v]\n", cmdname
, cmdname
);
62 * Find base name of filename.
69 if ((sp
= strrchr(cp
, '/')) != NULL
)
74 typedef struct _psr_action
{
81 static psr_action_t psr_action
[] = {
82 { P_ONLINE
, "on-line", "brought", "on" },
83 { P_OFFLINE
, "off-line", "taken", "off" },
84 { P_NOINTR
, "no-intr", "set to", "ni" },
85 { P_SPARE
, "spare", "marked", "spr" },
86 { P_FAULTED
, "faulted", "marked", "flt" },
89 static int psr_actions
= sizeof (psr_action
) / sizeof (psr_action_t
);
92 psr_action_lookup(int action
)
96 for (i
= 0; i
< psr_actions
; ++i
) {
97 if (psr_action
[i
].p_op
== action
) {
98 return (&psr_action
[i
]);
105 * Set processor state.
106 * Return non-zero if a processor was found.
107 * Print messages and update wtmp and the system log.
108 * If mustexist is set, it is an error if a processor isn't there.
112 psr_set_state(processorid_t cpu
, int action
, psr_action_t
*pac
, int mustexist
)
119 old_state
= p_online(cpu
, P_STATUS
);
121 if (errno
== EINVAL
&& !mustexist
)
122 return (0); /* no such processor */
123 err
= errno
; /* in case sprintf smashes errno */
124 (void) snprintf(buf
, sizeof (buf
), "%s: processor %d",
131 if (old_state
== P_FAULTED
&& action
!= P_FAULTED
&& !force
) {
132 (void) printf("%s: processor %d in faulted state; "
133 "add -F option to force change\n", cmdname
, cpu
);
137 old_state
= p_online(cpu
, force
? action
| P_FORCED
: action
);
139 if (errno
== EINVAL
&& !mustexist
)
140 return (0); /* no such processor */
142 (void) snprintf(buf
, sizeof (buf
), "%s: processor %d",
148 if (old_state
== action
) {
150 (void) printf("processor %d already %s.\n", cpu
,
152 return (1); /* no change */
155 (void) snprintf(buf
, sizeof (buf
), "processor %d %s %s.",
156 cpu
, pac
->p_action
, pac
->p_state
);
159 (void) printf("%s\n", buf
);
166 openlog(cmdname
, LOG_CONS
, LOG_USER
); /* open syslog */
167 (void) setlogmask(LOG_UPTO(LOG_INFO
));
169 ut
.ut_pid
= getpid();
170 ut
.ut_type
= USER_PROCESS
;
171 (void) strncpy(ut
.ut_user
, "psradm", sizeof (ut
.ut_user
) - 1);
174 syslog(LOG_INFO
, "%s", buf
);
179 (void) snprintf(ut
.ut_line
, sizeof (ut
.ut_line
), PSRADM_MSG
,
183 updwtmpx(WTMPX_FILE
, &ut
);
185 return (1); /* the processor exists and no errors occurred */
189 do_range(processorid_t first
, processorid_t last
, int action
,
197 for (cpu
= first
; cpu
<= last
; cpu
++) {
198 if ((rv
= psr_set_state(cpu
, action
, pac
, 0)) > 0)
203 if (!found_one
&& error
== 0) {
204 (void) fprintf(stderr
, "%s: no processors in range %d-%d\n",
205 cmdname
, first
, last
);
212 main(int argc
, char *argv
[])
217 processorid_t cpuid_max
;
222 cmdname
= basename(argv
[0]);
224 while ((c
= getopt(argc
, argv
, "afFinsv")) != EOF
) {
227 case 'a': /* applies to all possible CPUs */
239 if (action
!= 0 && action
!= c
) {
240 (void) fprintf(stderr
,
241 "%s: options -f, -n, -i, and -s are "
242 "mutually exclusive.\n", cmdname
);
275 * The -F option without other transition options
276 * puts processor(s) into faulted state.
281 (void) fprintf(stderr
,
282 "%s: option -f, -n, -s or -i must "
283 "be specified.\n", cmdname
);
288 pac
= psr_action_lookup(action
);
293 if (argc
!= optind
) {
297 cpuid_max
= (processorid_t
)sysconf(_SC_CPUID_MAX
);
298 for (cpu
= 0; cpu
<= cpuid_max
; cpu
++) {
299 if (psr_set_state(cpu
, action
, pac
, 0) < 0)
305 usage(); /* not enough arguments */
308 for (argv
+= optind
; argc
> 0; argv
++, argc
--) {
309 if (strchr(*argv
, '-') == NULL
) {
310 /* individual processor id */
311 cpu
= (processorid_t
)
312 strtol(*argv
, &errptr
, 10);
313 if (errptr
!= NULL
&& *errptr
!= '\0') {
314 (void) fprintf(stderr
,
315 "%s: invalid processor"
316 " ID %s\n", cmdname
, *argv
);
320 if (psr_set_state(cpu
, action
, pac
, 1) < 0)
323 /* range of processors */
324 processorid_t first
, last
;
326 first
= (processorid_t
)
327 strtol(*argv
, &errptr
, 10);
328 if (*errptr
++ != '-') {
329 (void) fprintf(stderr
,
330 "%s: invalid processor"
331 " range %s\n", cmdname
, *argv
);
335 last
= (processorid_t
)
336 strtol(errptr
, &errptr
, 10);
337 if ((errptr
!= NULL
&& *errptr
!= '\0') ||
338 last
< first
|| first
< 0) {
339 (void) fprintf(stderr
,
340 "%s: invalid processor"
341 " range %s\n", cmdname
, *argv
);
345 if (do_range(first
, last
, action
, pac
))