xref: /titanic_53/usr/src/cmd/psrset/psrset.c (revision fb9b0aa8c76ff829a7069d38161a2cecc656b091)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*fb9b0aa8SSurya Prakki  * Common Development and Distribution License (the "License").
6*fb9b0aa8SSurya Prakki  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*fb9b0aa8SSurya Prakki  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * psrset - create and manage processor sets
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/procset.h>
327c478bd9Sstevel@tonic-gate #include <sys/processor.h>
337c478bd9Sstevel@tonic-gate #include <sys/pset.h>
347c478bd9Sstevel@tonic-gate #include <fcntl.h>
357c478bd9Sstevel@tonic-gate #include <stdio.h>
367c478bd9Sstevel@tonic-gate #include <errno.h>
377c478bd9Sstevel@tonic-gate #include <dirent.h>
387c478bd9Sstevel@tonic-gate #include <locale.h>
397c478bd9Sstevel@tonic-gate #include <string.h>
407c478bd9Sstevel@tonic-gate #include <limits.h>
417c478bd9Sstevel@tonic-gate #include <procfs.h>
427c478bd9Sstevel@tonic-gate #include <libproc.h>
437c478bd9Sstevel@tonic-gate #include <stdarg.h>
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
467c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN 	"SYS_TEST"	/* Use this only if it wasn't */
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #define	MAX_PROCFS_PATH	80
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #define	ERR_OK		0		/* exit status for success */
527c478bd9Sstevel@tonic-gate #define	ERR_FAIL	1		/* exit status for errors */
537c478bd9Sstevel@tonic-gate #define	ERR_USAGE	2		/* exit status for usage errors */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate static char *progname;
567c478bd9Sstevel@tonic-gate static int errors;
577c478bd9Sstevel@tonic-gate static char cflag;
587c478bd9Sstevel@tonic-gate static char dflag;
597c478bd9Sstevel@tonic-gate static char aflag;
607c478bd9Sstevel@tonic-gate static char rflag;
617c478bd9Sstevel@tonic-gate static char iflag;
627c478bd9Sstevel@tonic-gate static char bflag;
637c478bd9Sstevel@tonic-gate static char uflag;
647c478bd9Sstevel@tonic-gate static char Uflag;
657c478bd9Sstevel@tonic-gate static char qflag;
667c478bd9Sstevel@tonic-gate static char Qflag;
677c478bd9Sstevel@tonic-gate static char pflag;
687c478bd9Sstevel@tonic-gate static char nflag;
697c478bd9Sstevel@tonic-gate static char fflag;
707c478bd9Sstevel@tonic-gate static char Fflag;
717c478bd9Sstevel@tonic-gate static char eflag;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate extern int pset_assign_forced(psetid_t, processorid_t, psetid_t *);
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
767c478bd9Sstevel@tonic-gate static void
777c478bd9Sstevel@tonic-gate warn(char *format, ...)
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate 	int err = errno;
807c478bd9Sstevel@tonic-gate 	va_list alist;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: ", progname);
837c478bd9Sstevel@tonic-gate 	va_start(alist, format);
847c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, format, alist);
857c478bd9Sstevel@tonic-gate 	va_end(alist);
867c478bd9Sstevel@tonic-gate 	if (strchr(format, '\n') == NULL)
877c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, ": %s\n", strerror(err));
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
917c478bd9Sstevel@tonic-gate static void
927c478bd9Sstevel@tonic-gate die(char *format, ...)
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 	int err = errno;
957c478bd9Sstevel@tonic-gate 	va_list alist;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: ", progname);
987c478bd9Sstevel@tonic-gate 	va_start(alist, format);
997c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, format, alist);
1007c478bd9Sstevel@tonic-gate 	va_end(alist);
1017c478bd9Sstevel@tonic-gate 	if (strchr(format, '\n') == NULL)
1027c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, ": %s\n", strerror(err));
1037c478bd9Sstevel@tonic-gate 	exit(ERR_FAIL);
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate static struct ps_prochandle *
1077c478bd9Sstevel@tonic-gate grab_proc(id_t pid)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	int ret;
1107c478bd9Sstevel@tonic-gate 	struct ps_prochandle *Pr;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	if ((Pr = Pgrab(pid, 0, &ret)) == NULL) {
1137c478bd9Sstevel@tonic-gate 		warn(gettext("cannot control process %d: %s\n"),
1147c478bd9Sstevel@tonic-gate 		    (int)pid, Pgrab_error(ret));
1157c478bd9Sstevel@tonic-gate 		errors = ERR_FAIL;
1167c478bd9Sstevel@tonic-gate 		return (NULL);
1177c478bd9Sstevel@tonic-gate 	}
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	return (Pr);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate static void
1237c478bd9Sstevel@tonic-gate rele_proc(struct ps_prochandle *Pr)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate 	if (Pr == NULL)
1267c478bd9Sstevel@tonic-gate 		return;
1277c478bd9Sstevel@tonic-gate 	Prelease(Pr, 0);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate static void
1317c478bd9Sstevel@tonic-gate bind_err(psetid_t pset, id_t pid, id_t lwpid, int err)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 	char    *msg;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	switch (pset) {
1367c478bd9Sstevel@tonic-gate 	case PS_NONE:
1377c478bd9Sstevel@tonic-gate 		msg = gettext("unbind");
1387c478bd9Sstevel@tonic-gate 		break;
1397c478bd9Sstevel@tonic-gate 	case PS_QUERY:
1407c478bd9Sstevel@tonic-gate 		msg = gettext("query");
1417c478bd9Sstevel@tonic-gate 		break;
1427c478bd9Sstevel@tonic-gate 	default:
1437c478bd9Sstevel@tonic-gate 		msg = gettext("bind");
1447c478bd9Sstevel@tonic-gate 		break;
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	errno = err;
1487c478bd9Sstevel@tonic-gate 	if (lwpid == -1)
1497c478bd9Sstevel@tonic-gate 		warn(gettext("cannot %s pid %d"), msg, pid);
1507c478bd9Sstevel@tonic-gate 	else
1517c478bd9Sstevel@tonic-gate 		warn(gettext("cannot %s lwpid %d/%d"), msg, pid, lwpid);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate  * Output for create.
1567c478bd9Sstevel@tonic-gate  */
1577c478bd9Sstevel@tonic-gate static void
1587c478bd9Sstevel@tonic-gate create_out(psetid_t pset)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate 	(void) printf("%s %d\n", gettext("created processor set"), pset);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * Output for assign.
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate static void
1677c478bd9Sstevel@tonic-gate assign_out(processorid_t cpu, psetid_t old, psetid_t new)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate 	if (old == PS_NONE) {
1707c478bd9Sstevel@tonic-gate 		if (new == PS_NONE)
1717c478bd9Sstevel@tonic-gate 			(void) printf(gettext("processor %d: was not assigned,"
1727c478bd9Sstevel@tonic-gate 			    " now not assigned\n"), cpu);
1737c478bd9Sstevel@tonic-gate 		else
1747c478bd9Sstevel@tonic-gate 			(void) printf(gettext("processor %d: was not assigned,"
1757c478bd9Sstevel@tonic-gate 			    " now %d\n"), cpu, new);
1767c478bd9Sstevel@tonic-gate 	} else {
1777c478bd9Sstevel@tonic-gate 		if (new == PS_NONE)
1787c478bd9Sstevel@tonic-gate 			(void) printf(gettext("processor %d: was %d, "
1797c478bd9Sstevel@tonic-gate 			    "now not assigned\n"), cpu, old);
1807c478bd9Sstevel@tonic-gate 		else
1817c478bd9Sstevel@tonic-gate 			(void) printf(gettext("processor %d: was %d, "
1827c478bd9Sstevel@tonic-gate 			    "now %d\n"), cpu, old, new);
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate  * Output for query.
1887c478bd9Sstevel@tonic-gate  */
1897c478bd9Sstevel@tonic-gate static void
1907c478bd9Sstevel@tonic-gate query_out(id_t pid, id_t lwpid, psetid_t pset)
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	char *proclwp;
1937c478bd9Sstevel@tonic-gate 	char pidstr[21];
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	if (lwpid == -1) {
1967c478bd9Sstevel@tonic-gate 		(void) snprintf(pidstr, 20, "%d", pid);
1977c478bd9Sstevel@tonic-gate 		proclwp = "process";
1987c478bd9Sstevel@tonic-gate 	} else {
1997c478bd9Sstevel@tonic-gate 		(void) snprintf(pidstr, 20, "%d/%d", pid, lwpid);
2007c478bd9Sstevel@tonic-gate 		proclwp = "lwp";
2017c478bd9Sstevel@tonic-gate 	}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	if (pset == PS_NONE)
2047c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s id %s: not bound\n"),
2057c478bd9Sstevel@tonic-gate 		    proclwp, pidstr);
2067c478bd9Sstevel@tonic-gate 	else
2077c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s id %s: %d\n"), proclwp, pidstr, pset);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate /*
2117c478bd9Sstevel@tonic-gate  * Output for info.
2127c478bd9Sstevel@tonic-gate  */
2137c478bd9Sstevel@tonic-gate static void
2147c478bd9Sstevel@tonic-gate info_out(psetid_t pset, int type, uint_t numcpus, processorid_t *cpus)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	int i;
2177c478bd9Sstevel@tonic-gate 	if (type == PS_SYSTEM)
2187c478bd9Sstevel@tonic-gate 		(void) printf(gettext("system processor set %d:"), pset);
2197c478bd9Sstevel@tonic-gate 	else
2207c478bd9Sstevel@tonic-gate 		(void) printf(gettext("user processor set %d:"), pset);
2217c478bd9Sstevel@tonic-gate 	if (numcpus == 0)
2227c478bd9Sstevel@tonic-gate 		(void) printf(gettext(" empty"));
2237c478bd9Sstevel@tonic-gate 	else if (numcpus > 1)
2247c478bd9Sstevel@tonic-gate 		(void) printf(gettext(" processors"));
2257c478bd9Sstevel@tonic-gate 	else
2267c478bd9Sstevel@tonic-gate 		(void) printf(gettext(" processor"));
2277c478bd9Sstevel@tonic-gate 	for (i = 0; i < numcpus; i++)
2287c478bd9Sstevel@tonic-gate 		(void) printf(" %d", cpus[i]);
2297c478bd9Sstevel@tonic-gate 	(void) printf("\n");
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate  * Output for print.
2347c478bd9Sstevel@tonic-gate  */
2357c478bd9Sstevel@tonic-gate static void
2367c478bd9Sstevel@tonic-gate print_out(processorid_t cpu, psetid_t pset)
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate 	if (pset == PS_NONE)
2397c478bd9Sstevel@tonic-gate 		(void) printf(gettext("processor %d: not assigned\n"), cpu);
2407c478bd9Sstevel@tonic-gate 	else
2417c478bd9Sstevel@tonic-gate 		(void) printf(gettext("processor %d: %d\n"), cpu, pset);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /*
2457c478bd9Sstevel@tonic-gate  * Output for bind.
2467c478bd9Sstevel@tonic-gate  */
2477c478bd9Sstevel@tonic-gate static void
2487c478bd9Sstevel@tonic-gate bind_out(id_t pid, id_t lwpid, psetid_t old, psetid_t new)
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate 	char *proclwp;
2517c478bd9Sstevel@tonic-gate 	char pidstr[21];
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	if (lwpid == -1) {
2547c478bd9Sstevel@tonic-gate 		(void) snprintf(pidstr, 20, "%d", pid);
2557c478bd9Sstevel@tonic-gate 		proclwp = "process";
2567c478bd9Sstevel@tonic-gate 	} else {
2577c478bd9Sstevel@tonic-gate 		(void) snprintf(pidstr, 20, "%d/%d", pid, lwpid);
2587c478bd9Sstevel@tonic-gate 		proclwp = "lwp";
2597c478bd9Sstevel@tonic-gate 	}
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	if (old == PS_NONE) {
2627c478bd9Sstevel@tonic-gate 		if (new == PS_NONE)
2637c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s id %s: was not bound, "
2647c478bd9Sstevel@tonic-gate 			    "now not bound\n"), proclwp, pidstr);
2657c478bd9Sstevel@tonic-gate 		else
2667c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s id %s: was not bound, "
2677c478bd9Sstevel@tonic-gate 			    "now %d\n"), proclwp, pidstr, new);
2687c478bd9Sstevel@tonic-gate 	} else {
2697c478bd9Sstevel@tonic-gate 		if (new == PS_NONE)
2707c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s id %s: was %d, "
2717c478bd9Sstevel@tonic-gate 			    "now not bound\n"), proclwp, pidstr, old);
2727c478bd9Sstevel@tonic-gate 		else
2737c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s id %s: was %d, "
2747c478bd9Sstevel@tonic-gate 			    "now %d\n"), proclwp, pidstr, old, new);
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate static void
279*fb9b0aa8SSurya Prakki bind_lwp(id_t pid, id_t lwpid, psetid_t pset)
2807c478bd9Sstevel@tonic-gate {
2817c478bd9Sstevel@tonic-gate 	psetid_t old_pset;
2827c478bd9Sstevel@tonic-gate 
283*fb9b0aa8SSurya Prakki 	if (pset_bind_lwp(pset, lwpid, pid, &old_pset) != 0) {
2847c478bd9Sstevel@tonic-gate 		bind_err(pset, pid, lwpid, errno);
2857c478bd9Sstevel@tonic-gate 		errors = ERR_FAIL;
286*fb9b0aa8SSurya Prakki 	}
287*fb9b0aa8SSurya Prakki 	if (errors != ERR_FAIL) {
2887c478bd9Sstevel@tonic-gate 		if (qflag)
2897c478bd9Sstevel@tonic-gate 			query_out(pid, lwpid, old_pset);
2907c478bd9Sstevel@tonic-gate 		else
2917c478bd9Sstevel@tonic-gate 			bind_out(pid, lwpid, old_pset, pset);
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate static int
2967c478bd9Sstevel@tonic-gate do_cpu(psetid_t pset, processorid_t cpu, int print, int mustexist)
2977c478bd9Sstevel@tonic-gate {
2987c478bd9Sstevel@tonic-gate 	psetid_t old_pset;
2997c478bd9Sstevel@tonic-gate 	int err;
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	if ((!Fflag && pset_assign(pset, cpu, &old_pset) != 0) ||
3027c478bd9Sstevel@tonic-gate 	    (Fflag && pset_assign_forced(pset, cpu, &old_pset) != 0)) {
3037c478bd9Sstevel@tonic-gate 		if (errno == EINVAL && !mustexist)
3047c478bd9Sstevel@tonic-gate 			return (EINVAL);
3057c478bd9Sstevel@tonic-gate 		err = errno;
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 		switch (pset) {
3087c478bd9Sstevel@tonic-gate 		case PS_NONE:
3097c478bd9Sstevel@tonic-gate 			warn(gettext("cannot remove processor %d"), cpu);
3107c478bd9Sstevel@tonic-gate 			break;
3117c478bd9Sstevel@tonic-gate 		case PS_QUERY:
3127c478bd9Sstevel@tonic-gate 			warn(gettext("cannot query processor %d"), cpu);
3137c478bd9Sstevel@tonic-gate 			break;
3147c478bd9Sstevel@tonic-gate 		default:
3157c478bd9Sstevel@tonic-gate 			warn(gettext("cannot assign processor %d"), cpu);
3167c478bd9Sstevel@tonic-gate 			break;
3177c478bd9Sstevel@tonic-gate 		}
3187c478bd9Sstevel@tonic-gate 		return (err);
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate 	if (print)
3217c478bd9Sstevel@tonic-gate 		print_out(cpu, old_pset);
3227c478bd9Sstevel@tonic-gate 	else
3237c478bd9Sstevel@tonic-gate 		assign_out(cpu, old_pset, pset);
3247c478bd9Sstevel@tonic-gate 	return (0);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate static int
3287c478bd9Sstevel@tonic-gate do_range(psetid_t pset, processorid_t first, processorid_t last, int print)
3297c478bd9Sstevel@tonic-gate {
3307c478bd9Sstevel@tonic-gate 	processorid_t cpu;
3317c478bd9Sstevel@tonic-gate 	int error = ERR_OK;
3327c478bd9Sstevel@tonic-gate 	int err;
3337c478bd9Sstevel@tonic-gate 	int found_one = 0;
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	for (cpu = first; cpu <= last; cpu++) {
3367c478bd9Sstevel@tonic-gate 		if ((err = do_cpu(pset, cpu, print, 0)) == 0)
3377c478bd9Sstevel@tonic-gate 			found_one = 1;
3387c478bd9Sstevel@tonic-gate 		else if (err != EINVAL)
3397c478bd9Sstevel@tonic-gate 			error = ERR_FAIL;
3407c478bd9Sstevel@tonic-gate 	}
3417c478bd9Sstevel@tonic-gate 	if (!found_one && error == ERR_OK) {
3427c478bd9Sstevel@tonic-gate 		warn(gettext("no processors in range %d-%d\n"), first, last);
3437c478bd9Sstevel@tonic-gate 		error = ERR_FAIL;
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate 	return (error);
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate static int
3497c478bd9Sstevel@tonic-gate do_info(psetid_t pset)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate 	int	type;
3527c478bd9Sstevel@tonic-gate 	uint_t	numcpus;
3537c478bd9Sstevel@tonic-gate 	processorid_t	*cpus;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	numcpus = (uint_t)sysconf(_SC_NPROCESSORS_MAX);
3567c478bd9Sstevel@tonic-gate 	cpus = (processorid_t *)
3577c478bd9Sstevel@tonic-gate 	    malloc(numcpus * sizeof (processorid_t));
3587c478bd9Sstevel@tonic-gate 	if (cpus == NULL) {
3597c478bd9Sstevel@tonic-gate 		warn(gettext("memory allocation failed"));
3607c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
3617c478bd9Sstevel@tonic-gate 	}
3627c478bd9Sstevel@tonic-gate 	if (pset_info(pset, &type, &numcpus, cpus) != 0) {
3637c478bd9Sstevel@tonic-gate 		warn(gettext("cannot get info for processor set %d"), pset);
3647c478bd9Sstevel@tonic-gate 		free(cpus);
3657c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate 	info_out(pset, type, numcpus, cpus);
3687c478bd9Sstevel@tonic-gate 	free(cpus);
3697c478bd9Sstevel@tonic-gate 	return (ERR_OK);
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate static int
3737c478bd9Sstevel@tonic-gate do_destroy(psetid_t pset)
3747c478bd9Sstevel@tonic-gate {
3757c478bd9Sstevel@tonic-gate 	if (pset_destroy(pset) != 0) {
3767c478bd9Sstevel@tonic-gate 		warn(gettext("could not remove processor set %d"), pset);
3777c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	(void) printf(gettext("removed processor set %d\n"), pset);
3807c478bd9Sstevel@tonic-gate 	return (ERR_OK);
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate static int
3847c478bd9Sstevel@tonic-gate do_intr(psetid_t pset, int flag)
3857c478bd9Sstevel@tonic-gate {
3867c478bd9Sstevel@tonic-gate 	uint_t i, numcpus;
3877c478bd9Sstevel@tonic-gate 	processorid_t *cpus;
3887c478bd9Sstevel@tonic-gate 	int error = ERR_OK;
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	numcpus = (uint_t)sysconf(_SC_NPROCESSORS_MAX);
3917c478bd9Sstevel@tonic-gate 	cpus = (processorid_t *)
3927c478bd9Sstevel@tonic-gate 	    malloc(numcpus * sizeof (processorid_t));
3937c478bd9Sstevel@tonic-gate 	if (cpus == NULL) {
3947c478bd9Sstevel@tonic-gate 		warn(gettext("memory allocation failed"));
3957c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
3967c478bd9Sstevel@tonic-gate 	}
3977c478bd9Sstevel@tonic-gate 	if (pset_info(pset, NULL, &numcpus, cpus) != 0) {
3987c478bd9Sstevel@tonic-gate 		warn(gettext(
3997c478bd9Sstevel@tonic-gate 		    "cannot set interrupt status for processor set %d"), pset);
4007c478bd9Sstevel@tonic-gate 		free(cpus);
4017c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	for (i = 0; i < numcpus; i++) {
4047c478bd9Sstevel@tonic-gate 		int status = p_online(cpus[i], P_STATUS);
4057c478bd9Sstevel@tonic-gate 		if (status != P_OFFLINE && status != P_POWEROFF &&
4067c478bd9Sstevel@tonic-gate 		    status != flag) {
4077c478bd9Sstevel@tonic-gate 			if (p_online(cpus[i], flag) == -1) {
4087c478bd9Sstevel@tonic-gate 				warn(gettext("processor %d"), cpus[i]);
4097c478bd9Sstevel@tonic-gate 				error = ERR_FAIL;
4107c478bd9Sstevel@tonic-gate 			}
4117c478bd9Sstevel@tonic-gate 		}
4127c478bd9Sstevel@tonic-gate 	}
4137c478bd9Sstevel@tonic-gate 	free(cpus);
4147c478bd9Sstevel@tonic-gate 	return (error);
4157c478bd9Sstevel@tonic-gate }
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate  * Query the type and CPUs for all active processor sets in the system.
4197c478bd9Sstevel@tonic-gate  */
4207c478bd9Sstevel@tonic-gate static int
4217c478bd9Sstevel@tonic-gate info_all(void)
4227c478bd9Sstevel@tonic-gate {
4237c478bd9Sstevel@tonic-gate 	psetid_t *psetlist;
4247c478bd9Sstevel@tonic-gate 	uint_t	npsets, oldnpsets;
4257c478bd9Sstevel@tonic-gate 	int	i;
4267c478bd9Sstevel@tonic-gate 	int	errors = ERR_OK;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	if (pset_list(NULL, &npsets) != 0) {
4297c478bd9Sstevel@tonic-gate 		warn(gettext("cannot get number of processor sets"));
4307c478bd9Sstevel@tonic-gate 		return (1);
4317c478bd9Sstevel@tonic-gate 	}
4327c478bd9Sstevel@tonic-gate 	for (;;) {
4337c478bd9Sstevel@tonic-gate 		psetlist = malloc(sizeof (psetid_t) * npsets);
4347c478bd9Sstevel@tonic-gate 		if (psetlist == NULL) {
4357c478bd9Sstevel@tonic-gate 			warn(gettext("memory allocation failed"));
4367c478bd9Sstevel@tonic-gate 			return (ERR_FAIL);
4377c478bd9Sstevel@tonic-gate 		}
4387c478bd9Sstevel@tonic-gate 		oldnpsets = npsets;
4397c478bd9Sstevel@tonic-gate 		if (pset_list(psetlist, &npsets) != 0) {
4407c478bd9Sstevel@tonic-gate 			warn(gettext("cannot get list of processor sets"));
4417c478bd9Sstevel@tonic-gate 			free(psetlist);
4427c478bd9Sstevel@tonic-gate 			return (ERR_FAIL);
4437c478bd9Sstevel@tonic-gate 		}
4447c478bd9Sstevel@tonic-gate 		if (npsets <= oldnpsets)
4457c478bd9Sstevel@tonic-gate 			break;
4467c478bd9Sstevel@tonic-gate 		free(psetlist);
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	for (i = 0; i < npsets; i++) {
4507c478bd9Sstevel@tonic-gate 		if (do_info(psetlist[i]))
4517c478bd9Sstevel@tonic-gate 			errors = ERR_FAIL;
4527c478bd9Sstevel@tonic-gate 	}
4537c478bd9Sstevel@tonic-gate 	free(psetlist);
4547c478bd9Sstevel@tonic-gate 	return (errors);
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate  * Query the processor set assignments for all CPUs in the system.
4597c478bd9Sstevel@tonic-gate  */
4607c478bd9Sstevel@tonic-gate static int
4617c478bd9Sstevel@tonic-gate print_all(void)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate 	psetid_t	pset;
4647c478bd9Sstevel@tonic-gate 	processorid_t cpuid, max_cpuid;
4657c478bd9Sstevel@tonic-gate 	int	errors = ERR_OK;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	max_cpuid = (processorid_t)sysconf(_SC_CPUID_MAX);
4687c478bd9Sstevel@tonic-gate 	for (cpuid = 0; cpuid <= max_cpuid; cpuid++) {
4697c478bd9Sstevel@tonic-gate 		if (pset_assign(PS_QUERY, cpuid, &pset) == 0) {
4707c478bd9Sstevel@tonic-gate 			if (pset != PS_NONE)
4717c478bd9Sstevel@tonic-gate 				print_out(cpuid, pset);
4727c478bd9Sstevel@tonic-gate 		} else if (errno != EINVAL) {
4737c478bd9Sstevel@tonic-gate 			warn(gettext("cannot query processor %d"), cpuid);
4747c478bd9Sstevel@tonic-gate 			errors = ERR_FAIL;
4757c478bd9Sstevel@tonic-gate 		}
4767c478bd9Sstevel@tonic-gate 	}
4777c478bd9Sstevel@tonic-gate 	return (errors);
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4817c478bd9Sstevel@tonic-gate static int
4827c478bd9Sstevel@tonic-gate query_all_proc(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, void *arg)
4837c478bd9Sstevel@tonic-gate {
4847c478bd9Sstevel@tonic-gate 	id_t pid = psinfo->pr_pid;
4857c478bd9Sstevel@tonic-gate 	psetid_t binding;
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	if (pset_bind(PS_QUERY, P_PID, pid, &binding) < 0) {
4887c478bd9Sstevel@tonic-gate 		/*
4897c478bd9Sstevel@tonic-gate 		 * Ignore search errors.  The process may have exited
4907c478bd9Sstevel@tonic-gate 		 * since we read the directory.
4917c478bd9Sstevel@tonic-gate 		 */
4927c478bd9Sstevel@tonic-gate 		if (errno == ESRCH)
4937c478bd9Sstevel@tonic-gate 			return (0);
4947c478bd9Sstevel@tonic-gate 		bind_err(PS_QUERY, pid, -1, errno);
4957c478bd9Sstevel@tonic-gate 		errors = ERR_FAIL;
4967c478bd9Sstevel@tonic-gate 		return (0);
4977c478bd9Sstevel@tonic-gate 	}
4987c478bd9Sstevel@tonic-gate 	if (binding != PS_NONE)
4997c478bd9Sstevel@tonic-gate 		query_out(pid, -1, binding);
5007c478bd9Sstevel@tonic-gate 	return (0);
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate static int
5047c478bd9Sstevel@tonic-gate query_all_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, void *arg)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate 	id_t pid = psinfo->pr_pid;
5077c478bd9Sstevel@tonic-gate 	id_t lwpid = lwpsinfo->pr_lwpid;
5087c478bd9Sstevel@tonic-gate 	psetid_t *cpuid = arg;
5097c478bd9Sstevel@tonic-gate 	psetid_t binding = lwpsinfo->pr_bindpset;
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 	if (psinfo->pr_nlwp == 1)
5127c478bd9Sstevel@tonic-gate 		lwpid = -1;	/* report process bindings if only 1 lwp */
5137c478bd9Sstevel@tonic-gate 	if ((cpuid != NULL && *cpuid == binding) ||
5147c478bd9Sstevel@tonic-gate 	    (cpuid == NULL && binding != PBIND_NONE))
5157c478bd9Sstevel@tonic-gate 		query_out(pid, lwpid, binding);
5167c478bd9Sstevel@tonic-gate 	return (0);
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate void
5207c478bd9Sstevel@tonic-gate exec_cmd(psetid_t pset, char **argv)
5217c478bd9Sstevel@tonic-gate {
5227c478bd9Sstevel@tonic-gate 	if (pset_bind(pset, P_PID, P_MYID, NULL) != 0) {
5237c478bd9Sstevel@tonic-gate 		warn(gettext("cannot exec in processor set %d"), pset);
5247c478bd9Sstevel@tonic-gate 		return;
5257c478bd9Sstevel@tonic-gate 	}
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	(void) execvp(argv[0], argv);
5287c478bd9Sstevel@tonic-gate 	warn(gettext("cannot exec command %s"), argv[0]);
5297c478bd9Sstevel@tonic-gate }
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate int
5327c478bd9Sstevel@tonic-gate usage(void)
5337c478bd9Sstevel@tonic-gate {
5347c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
5357c478bd9Sstevel@tonic-gate 	    "usage: \n"
5367c478bd9Sstevel@tonic-gate 	    "\t%1$s -c [-F] [processor_id ...]\n"
5377c478bd9Sstevel@tonic-gate 	    "\t%1$s -d processor_set_id ...\n"
5387c478bd9Sstevel@tonic-gate 	    "\t%1$s -n processor_set_id\n"
5397c478bd9Sstevel@tonic-gate 	    "\t%1$s -f processor_set_id\n"
5407c478bd9Sstevel@tonic-gate 	    "\t%1$s -e processor_set_id command [argument(s)...]\n"
5417c478bd9Sstevel@tonic-gate 	    "\t%1$s -a [-F] processor_set_id processor_id ...\n"
5427c478bd9Sstevel@tonic-gate 	    "\t%1$s -r [-F] processor_id ...\n"
5437c478bd9Sstevel@tonic-gate 	    "\t%1$s -p [processorid ...]\n"
5447c478bd9Sstevel@tonic-gate 	    "\t%1$s -b processor_set_id pid[/lwpids] ...\n"
5457c478bd9Sstevel@tonic-gate 	    "\t%1$s -u pid[/lwpids] ...\n"
5467c478bd9Sstevel@tonic-gate 	    "\t%1$s -q [pid[/lwpids] ...]\n"
5477c478bd9Sstevel@tonic-gate 	    "\t%1$s -U [processor_set_id] ...\n"
5487c478bd9Sstevel@tonic-gate 	    "\t%1$s -Q [processor_set_id] ...\n"
5497c478bd9Sstevel@tonic-gate 	    "\t%1$s [-i] [processor_set_id ...]\n"),
5507c478bd9Sstevel@tonic-gate 	    progname);
5517c478bd9Sstevel@tonic-gate 	return (ERR_USAGE);
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate /*
5557c478bd9Sstevel@tonic-gate  * Query, set, or clear bindings for the range of LWPs in the given process.
5567c478bd9Sstevel@tonic-gate  */
5577c478bd9Sstevel@tonic-gate static int
5587c478bd9Sstevel@tonic-gate do_lwps(id_t pid, const char *range, psetid_t pset)
5597c478bd9Sstevel@tonic-gate {
5607c478bd9Sstevel@tonic-gate 	char procfile[MAX_PROCFS_PATH];
5617c478bd9Sstevel@tonic-gate 	struct ps_prochandle *Pr;
5627c478bd9Sstevel@tonic-gate 	struct prheader header;
5637c478bd9Sstevel@tonic-gate 	struct lwpsinfo *lwp;
5647c478bd9Sstevel@tonic-gate 	char *lpsinfo, *ptr;
5657c478bd9Sstevel@tonic-gate 	psetid_t binding;
5667c478bd9Sstevel@tonic-gate 	int nent, size;
5677c478bd9Sstevel@tonic-gate 	int i, fd, found;
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	/*
5707c478bd9Sstevel@tonic-gate 	 * Report bindings for LWPs in process 'pid'.
5717c478bd9Sstevel@tonic-gate 	 */
5727c478bd9Sstevel@tonic-gate 	(void) snprintf(procfile, MAX_PROCFS_PATH,
5737c478bd9Sstevel@tonic-gate 	    "/proc/%d/lpsinfo", (int)pid);
5747c478bd9Sstevel@tonic-gate 	if ((fd = open(procfile, O_RDONLY)) < 0) {
5757c478bd9Sstevel@tonic-gate 		if (errno == ENOENT)
5767c478bd9Sstevel@tonic-gate 			errno = ESRCH;
5777c478bd9Sstevel@tonic-gate 		bind_err(pset, pid, -1, errno);
5787c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
5797c478bd9Sstevel@tonic-gate 	}
5807c478bd9Sstevel@tonic-gate 	if (pread(fd, &header, sizeof (header), 0) != sizeof (header)) {
5817c478bd9Sstevel@tonic-gate 		(void) close(fd);
5827c478bd9Sstevel@tonic-gate 		bind_err(pset, pid, -1, errno);
5837c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
5847c478bd9Sstevel@tonic-gate 	}
5857c478bd9Sstevel@tonic-gate 	nent = header.pr_nent;
5867c478bd9Sstevel@tonic-gate 	size = header.pr_entsize * nent;
5877c478bd9Sstevel@tonic-gate 	ptr = lpsinfo = malloc(size);
5887c478bd9Sstevel@tonic-gate 	if (lpsinfo == NULL) {
5897c478bd9Sstevel@tonic-gate 		bind_err(pset, pid, -1, errno);
5907c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
5917c478bd9Sstevel@tonic-gate 	}
5927c478bd9Sstevel@tonic-gate 	if (pread(fd, lpsinfo, size, sizeof (header)) != size) {
5937c478bd9Sstevel@tonic-gate 		bind_err(pset, pid, -1, errno);
5947c478bd9Sstevel@tonic-gate 		free(lpsinfo);
5957c478bd9Sstevel@tonic-gate 		(void) close(fd);
5967c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
5977c478bd9Sstevel@tonic-gate 	}
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	if ((bflag || uflag) && (Pr = grab_proc(pid)) == NULL) {
6007c478bd9Sstevel@tonic-gate 		free(lpsinfo);
6017c478bd9Sstevel@tonic-gate 		(void) close(fd);
6027c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
6037c478bd9Sstevel@tonic-gate 	}
6047c478bd9Sstevel@tonic-gate 	found = 0;
6057c478bd9Sstevel@tonic-gate 	for (i = 0; i < nent; i++, ptr += header.pr_entsize) {
6067c478bd9Sstevel@tonic-gate 		/*LINTED ALIGNMENT*/
6077c478bd9Sstevel@tonic-gate 		lwp = (lwpsinfo_t *)ptr;
6087c478bd9Sstevel@tonic-gate 		binding = lwp->pr_bindpset;
6097c478bd9Sstevel@tonic-gate 		if (!proc_lwp_in_set(range, lwp->pr_lwpid))
6107c478bd9Sstevel@tonic-gate 			continue;
6117c478bd9Sstevel@tonic-gate 		found++;
6127c478bd9Sstevel@tonic-gate 		if (bflag || uflag)
613*fb9b0aa8SSurya Prakki 			bind_lwp(pid, lwp->pr_lwpid, pset);
6147c478bd9Sstevel@tonic-gate 		else if (binding != PBIND_NONE)
6157c478bd9Sstevel@tonic-gate 			query_out(pid, lwp->pr_lwpid, binding);
6167c478bd9Sstevel@tonic-gate 	}
6177c478bd9Sstevel@tonic-gate 	if (bflag || uflag)
6187c478bd9Sstevel@tonic-gate 		rele_proc(Pr);
6197c478bd9Sstevel@tonic-gate 	free(lpsinfo);
6207c478bd9Sstevel@tonic-gate 	(void) close(fd);
6217c478bd9Sstevel@tonic-gate 	if (found == 0) {
6227c478bd9Sstevel@tonic-gate 		warn(gettext("cannot %s lwpid %d/%s: "
6237c478bd9Sstevel@tonic-gate 		    "No matching LWPs found\n"),
6247c478bd9Sstevel@tonic-gate 		    bflag ? "bind" : "query", pid, range);
6257c478bd9Sstevel@tonic-gate 		return (ERR_FAIL);
6267c478bd9Sstevel@tonic-gate 	}
6277c478bd9Sstevel@tonic-gate 	return (ERR_OK);
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate int
6317c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
6327c478bd9Sstevel@tonic-gate {
6337c478bd9Sstevel@tonic-gate 	extern int optind;
6347c478bd9Sstevel@tonic-gate 	int	c;
6357c478bd9Sstevel@tonic-gate 	id_t	pid;
6367c478bd9Sstevel@tonic-gate 	processorid_t	cpu;
6377c478bd9Sstevel@tonic-gate 	psetid_t	pset, old_pset;
6387c478bd9Sstevel@tonic-gate 	char	*errptr;
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 	progname = argv[0];	/* put actual command name in messages */
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");	/* setup localization */
6437c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "cdFarpibqQuUnfe")) != EOF) {
6467c478bd9Sstevel@tonic-gate 		switch (c) {
6477c478bd9Sstevel@tonic-gate 		case 'c':
6487c478bd9Sstevel@tonic-gate 			cflag = 1;
6497c478bd9Sstevel@tonic-gate 			break;
6507c478bd9Sstevel@tonic-gate 		case 'd':
6517c478bd9Sstevel@tonic-gate 			dflag = 1;
6527c478bd9Sstevel@tonic-gate 			break;
6537c478bd9Sstevel@tonic-gate 		case 'e':
6547c478bd9Sstevel@tonic-gate 			eflag = 1;
6557c478bd9Sstevel@tonic-gate 			break;
6567c478bd9Sstevel@tonic-gate 		case 'a':
6577c478bd9Sstevel@tonic-gate 			aflag = 1;
6587c478bd9Sstevel@tonic-gate 			break;
6597c478bd9Sstevel@tonic-gate 		case 'r':
6607c478bd9Sstevel@tonic-gate 			rflag = 1;
6617c478bd9Sstevel@tonic-gate 			pset = PS_NONE;
6627c478bd9Sstevel@tonic-gate 			break;
6637c478bd9Sstevel@tonic-gate 		case 'p':
6647c478bd9Sstevel@tonic-gate 			pflag = 1;
6657c478bd9Sstevel@tonic-gate 			pset = PS_QUERY;
6667c478bd9Sstevel@tonic-gate 			break;
6677c478bd9Sstevel@tonic-gate 		case 'i':
6687c478bd9Sstevel@tonic-gate 			iflag = 1;
6697c478bd9Sstevel@tonic-gate 			break;
6707c478bd9Sstevel@tonic-gate 		case 'b':
6717c478bd9Sstevel@tonic-gate 			bflag = 1;
6727c478bd9Sstevel@tonic-gate 			break;
6737c478bd9Sstevel@tonic-gate 		case 'u':
6747c478bd9Sstevel@tonic-gate 			uflag = 1;
6757c478bd9Sstevel@tonic-gate 			pset = PS_NONE;
6767c478bd9Sstevel@tonic-gate 			break;
6777c478bd9Sstevel@tonic-gate 		case 'U':
6787c478bd9Sstevel@tonic-gate 			Uflag = 1;
6797c478bd9Sstevel@tonic-gate 			break;
6807c478bd9Sstevel@tonic-gate 		case 'q':
6817c478bd9Sstevel@tonic-gate 			qflag = 1;
6827c478bd9Sstevel@tonic-gate 			pset = PS_QUERY;
6837c478bd9Sstevel@tonic-gate 			break;
6847c478bd9Sstevel@tonic-gate 		case 'Q':
6857c478bd9Sstevel@tonic-gate 			Qflag = 1;
6867c478bd9Sstevel@tonic-gate 			break;
6877c478bd9Sstevel@tonic-gate 		case 'f':
6887c478bd9Sstevel@tonic-gate 			fflag = 1;
6897c478bd9Sstevel@tonic-gate 			break;
6907c478bd9Sstevel@tonic-gate 		case 'F':
6917c478bd9Sstevel@tonic-gate 			Fflag = 1;
6927c478bd9Sstevel@tonic-gate 			break;
6937c478bd9Sstevel@tonic-gate 		case 'n':
6947c478bd9Sstevel@tonic-gate 			nflag = 1;
6957c478bd9Sstevel@tonic-gate 			break;
6967c478bd9Sstevel@tonic-gate 		default:
6977c478bd9Sstevel@tonic-gate 			return (usage());
6987c478bd9Sstevel@tonic-gate 		}
6997c478bd9Sstevel@tonic-gate 	}
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	/*
7027c478bd9Sstevel@tonic-gate 	 * Make sure that at most one of the options was specified.
7037c478bd9Sstevel@tonic-gate 	 */
7047c478bd9Sstevel@tonic-gate 	c = cflag + dflag + aflag + rflag + pflag +
7057c478bd9Sstevel@tonic-gate 	    iflag + bflag + uflag + Uflag +
7067c478bd9Sstevel@tonic-gate 	    qflag + Qflag + fflag + nflag + eflag;
7077c478bd9Sstevel@tonic-gate 	if (c < 1) {				/* nothing specified */
7087c478bd9Sstevel@tonic-gate 		iflag = 1;			/* default is to get info */
7097c478bd9Sstevel@tonic-gate 	} else if (c > 1) {
7107c478bd9Sstevel@tonic-gate 		warn(gettext("options are mutually exclusive\n"));
7117c478bd9Sstevel@tonic-gate 		return (usage());
7127c478bd9Sstevel@tonic-gate 	}
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 	if (Fflag && (cflag + aflag + rflag == 0))
7157c478bd9Sstevel@tonic-gate 		return (usage());
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 	errors = 0;
7187c478bd9Sstevel@tonic-gate 	argc -= optind;
7197c478bd9Sstevel@tonic-gate 	argv += optind;
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	if (argc == 0) {
7227c478bd9Sstevel@tonic-gate 		/*
7237c478bd9Sstevel@tonic-gate 		 * Handle single option cases.
7247c478bd9Sstevel@tonic-gate 		 */
7257c478bd9Sstevel@tonic-gate 		if (qflag) {
7267c478bd9Sstevel@tonic-gate 			(void) proc_walk(query_all_proc, NULL, PR_WALK_PROC);
7277c478bd9Sstevel@tonic-gate 			return (errors);
7287c478bd9Sstevel@tonic-gate 		}
7297c478bd9Sstevel@tonic-gate 		if (Qflag) {
7307c478bd9Sstevel@tonic-gate 			(void) proc_walk(query_all_lwp, NULL, PR_WALK_LWP);
7317c478bd9Sstevel@tonic-gate 			return (errors);
7327c478bd9Sstevel@tonic-gate 		}
7337c478bd9Sstevel@tonic-gate 		if (Uflag) {
7347c478bd9Sstevel@tonic-gate 			if (pset_bind(PS_NONE, P_ALL, 0, &old_pset) != 0)
7357c478bd9Sstevel@tonic-gate 				die(gettext("failed to unbind all LWPs"));
7367c478bd9Sstevel@tonic-gate 		}
7377c478bd9Sstevel@tonic-gate 		if (pflag)
7387c478bd9Sstevel@tonic-gate 			return (print_all());
7397c478bd9Sstevel@tonic-gate 		if (iflag)
7407c478bd9Sstevel@tonic-gate 			return (info_all());
7417c478bd9Sstevel@tonic-gate 	}
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	/*
7447c478bd9Sstevel@tonic-gate 	 * Get processor set id.
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 	if (aflag || bflag || fflag || nflag || eflag) {
7477c478bd9Sstevel@tonic-gate 		if (argc < 1) {
7487c478bd9Sstevel@tonic-gate 			/* must specify processor set */
7497c478bd9Sstevel@tonic-gate 			warn(gettext("must specify processor set\n"));
7507c478bd9Sstevel@tonic-gate 			return (usage());
7517c478bd9Sstevel@tonic-gate 		}
7527c478bd9Sstevel@tonic-gate 		pset = strtol(*argv, &errptr, 10);
7537c478bd9Sstevel@tonic-gate 		if (errptr != NULL && *errptr != '\0' || pset < 0) {
7547c478bd9Sstevel@tonic-gate 			warn(gettext("invalid processor set ID %s\n"), *argv);
7557c478bd9Sstevel@tonic-gate 			return (ERR_FAIL);
7567c478bd9Sstevel@tonic-gate 		}
7577c478bd9Sstevel@tonic-gate 		argv++;
7587c478bd9Sstevel@tonic-gate 		argc--;
7597c478bd9Sstevel@tonic-gate 	}
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	if (cflag) {
7627c478bd9Sstevel@tonic-gate 		if (pset_create(&pset) != 0) {
7637c478bd9Sstevel@tonic-gate 			warn(gettext("could not create processor set"));
7647c478bd9Sstevel@tonic-gate 			return (ERR_FAIL);
7657c478bd9Sstevel@tonic-gate 		} else {
7667c478bd9Sstevel@tonic-gate 			create_out(pset);
7677c478bd9Sstevel@tonic-gate 			if (argc == 0)
7687c478bd9Sstevel@tonic-gate 				return (ERR_OK);
7697c478bd9Sstevel@tonic-gate 		}
7707c478bd9Sstevel@tonic-gate 	} else if (iflag || dflag) {
7717c478bd9Sstevel@tonic-gate 		if (argc == 0) {
7727c478bd9Sstevel@tonic-gate 			warn(gettext("must specify at least one "
7737c478bd9Sstevel@tonic-gate 			    "processor set\n"));
7747c478bd9Sstevel@tonic-gate 			return (usage());
7757c478bd9Sstevel@tonic-gate 		}
7767c478bd9Sstevel@tonic-gate 		/*
7777c478bd9Sstevel@tonic-gate 		 * Go through listed processor sets.
7787c478bd9Sstevel@tonic-gate 		 */
7797c478bd9Sstevel@tonic-gate 		for (; argc > 0; argv++, argc--) {
7807c478bd9Sstevel@tonic-gate 			pset = (psetid_t)strtol(*argv, &errptr, 10);
7817c478bd9Sstevel@tonic-gate 			if (errptr != NULL && *errptr != '\0') {
7827c478bd9Sstevel@tonic-gate 				warn(gettext("invalid processor set ID %s\n"),
7837c478bd9Sstevel@tonic-gate 				    *argv);
7847c478bd9Sstevel@tonic-gate 				errors = ERR_FAIL;
7857c478bd9Sstevel@tonic-gate 				continue;
7867c478bd9Sstevel@tonic-gate 			}
7877c478bd9Sstevel@tonic-gate 			if (iflag) {
7887c478bd9Sstevel@tonic-gate 				errors = do_info(pset);
7897c478bd9Sstevel@tonic-gate 			} else {
7907c478bd9Sstevel@tonic-gate 				errors = do_destroy(pset);
7917c478bd9Sstevel@tonic-gate 			}
7927c478bd9Sstevel@tonic-gate 		}
7937c478bd9Sstevel@tonic-gate 	} else if (nflag) {
7947c478bd9Sstevel@tonic-gate 		errors = do_intr(pset, P_ONLINE);
7957c478bd9Sstevel@tonic-gate 	} else if (fflag) {
7967c478bd9Sstevel@tonic-gate 		errors = do_intr(pset, P_NOINTR);
7977c478bd9Sstevel@tonic-gate 	} else if (eflag) {
7987c478bd9Sstevel@tonic-gate 		if (argc == 0) {
7997c478bd9Sstevel@tonic-gate 			warn(gettext("must specify command\n"));
8007c478bd9Sstevel@tonic-gate 			return (usage());
8017c478bd9Sstevel@tonic-gate 		}
8027c478bd9Sstevel@tonic-gate 		exec_cmd(pset, argv);
8037c478bd9Sstevel@tonic-gate 		/* if returning, must have had an error */
8047c478bd9Sstevel@tonic-gate 		return (ERR_USAGE);
8057c478bd9Sstevel@tonic-gate 	}
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	if (cflag || aflag || rflag || pflag) {
8087c478bd9Sstevel@tonic-gate 		/*
8097c478bd9Sstevel@tonic-gate 		 * Perform function for each processor specified.
8107c478bd9Sstevel@tonic-gate 		 */
8117c478bd9Sstevel@tonic-gate 		if (argc == 0) {
8127c478bd9Sstevel@tonic-gate 			warn(gettext("must specify at least one processor\n"));
8137c478bd9Sstevel@tonic-gate 			return (usage());
8147c478bd9Sstevel@tonic-gate 		}
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 		/*
8177c478bd9Sstevel@tonic-gate 		 * Go through listed processors.
8187c478bd9Sstevel@tonic-gate 		 */
8197c478bd9Sstevel@tonic-gate 		for (; argc > 0; argv++, argc--) {
8207c478bd9Sstevel@tonic-gate 			if (strchr(*argv, '-') == NULL) {
8217c478bd9Sstevel@tonic-gate 				/* individual processor id */
8227c478bd9Sstevel@tonic-gate 				cpu = (processorid_t)strtol(*argv, &errptr, 10);
8237c478bd9Sstevel@tonic-gate 				if (errptr != NULL && *errptr != '\0') {
8247c478bd9Sstevel@tonic-gate 					warn(gettext("invalid processor "
8257c478bd9Sstevel@tonic-gate 					    "ID %s\n"), *argv);
8267c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
8277c478bd9Sstevel@tonic-gate 					continue;
8287c478bd9Sstevel@tonic-gate 				}
8297c478bd9Sstevel@tonic-gate 				if (do_cpu(pset, cpu, pflag, 1))
8307c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
8317c478bd9Sstevel@tonic-gate 			} else {
8327c478bd9Sstevel@tonic-gate 				/* range of processors */
8337c478bd9Sstevel@tonic-gate 				processorid_t first, last;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 				first = (processorid_t)
8367c478bd9Sstevel@tonic-gate 				    strtol(*argv, &errptr, 10);
8377c478bd9Sstevel@tonic-gate 				if (*errptr++ != '-') {
8387c478bd9Sstevel@tonic-gate 					warn(gettext(
8397c478bd9Sstevel@tonic-gate 					    "invalid processor range %s\n"),
8407c478bd9Sstevel@tonic-gate 					    *argv);
8417c478bd9Sstevel@tonic-gate 					errors = ERR_USAGE;
8427c478bd9Sstevel@tonic-gate 					continue;
8437c478bd9Sstevel@tonic-gate 				}
8447c478bd9Sstevel@tonic-gate 				last = (processorid_t)
8457c478bd9Sstevel@tonic-gate 				    strtol(errptr, &errptr, 10);
8467c478bd9Sstevel@tonic-gate 				if ((errptr != NULL && *errptr != '\0') ||
8477c478bd9Sstevel@tonic-gate 				    last < first || first < 0) {
8487c478bd9Sstevel@tonic-gate 					warn(gettext(
8497c478bd9Sstevel@tonic-gate 					    "invalid processor range %s\n"),
8507c478bd9Sstevel@tonic-gate 					    *argv);
8517c478bd9Sstevel@tonic-gate 					errors = ERR_USAGE;
8527c478bd9Sstevel@tonic-gate 					continue;
8537c478bd9Sstevel@tonic-gate 				}
8547c478bd9Sstevel@tonic-gate 				if (do_range(pset, first, last, pflag))
8557c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
8567c478bd9Sstevel@tonic-gate 			}
8577c478bd9Sstevel@tonic-gate 		}
8587c478bd9Sstevel@tonic-gate 	} else if (bflag || uflag || qflag) {
8597c478bd9Sstevel@tonic-gate 		/*
8607c478bd9Sstevel@tonic-gate 		 * Perform function for each pid/lwpid specified.
8617c478bd9Sstevel@tonic-gate 		 */
8627c478bd9Sstevel@tonic-gate 		if (argc == 0) {
8637c478bd9Sstevel@tonic-gate 			warn(gettext("must specify at least one pid\n"));
8647c478bd9Sstevel@tonic-gate 			return (usage());
8657c478bd9Sstevel@tonic-gate 		}
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 		/*
8687c478bd9Sstevel@tonic-gate 		 * Go through listed processes/lwp_ranges.
8697c478bd9Sstevel@tonic-gate 		 */
8707c478bd9Sstevel@tonic-gate 		for (; argc > 0; argv++, argc--) {
8717c478bd9Sstevel@tonic-gate 			pid = (id_t)strtol(*argv, &errptr, 10);
8727c478bd9Sstevel@tonic-gate 			if (errno != 0 ||
8737c478bd9Sstevel@tonic-gate 			    (errptr != NULL && *errptr != '\0' &&
8747c478bd9Sstevel@tonic-gate 			    *errptr != '/')) {
8757c478bd9Sstevel@tonic-gate 				warn(gettext("invalid process ID: %s\n"),
8767c478bd9Sstevel@tonic-gate 				    *argv);
8777c478bd9Sstevel@tonic-gate 				continue;
8787c478bd9Sstevel@tonic-gate 			}
8797c478bd9Sstevel@tonic-gate 			if (errptr != NULL && *errptr == '/') {
8807c478bd9Sstevel@tonic-gate 				int ret;
8817c478bd9Sstevel@tonic-gate 				/*
8827c478bd9Sstevel@tonic-gate 				 * Handle lwp range case
8837c478bd9Sstevel@tonic-gate 				 */
8847c478bd9Sstevel@tonic-gate 				const char *lwps = (const char *)(++errptr);
8857c478bd9Sstevel@tonic-gate 				if (*lwps == '\0' ||
8867c478bd9Sstevel@tonic-gate 				    proc_lwp_range_valid(lwps) != 0) {
8877c478bd9Sstevel@tonic-gate 					warn(gettext("invalid lwp range "
8887c478bd9Sstevel@tonic-gate 					    "for pid %d\n"), (int)pid);
8897c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
8907c478bd9Sstevel@tonic-gate 					continue;
8917c478bd9Sstevel@tonic-gate 				}
8927c478bd9Sstevel@tonic-gate 				if (!qflag)
8937c478bd9Sstevel@tonic-gate 					(void) proc_initstdio();
8947c478bd9Sstevel@tonic-gate 				ret = do_lwps(pid, lwps, pset);
8957c478bd9Sstevel@tonic-gate 				if (!qflag)
8967c478bd9Sstevel@tonic-gate 					(void) proc_finistdio();
8977c478bd9Sstevel@tonic-gate 				if (ret != ERR_OK)
8987c478bd9Sstevel@tonic-gate 					errors = ret;
8997c478bd9Sstevel@tonic-gate 			} else {
9007c478bd9Sstevel@tonic-gate 				/*
9017c478bd9Sstevel@tonic-gate 				 * Handle whole process case.
9027c478bd9Sstevel@tonic-gate 				 */
9037c478bd9Sstevel@tonic-gate 				if (pset_bind(pset, P_PID, pid,
9047c478bd9Sstevel@tonic-gate 				    &old_pset) < 0) {
9057c478bd9Sstevel@tonic-gate 					bind_err(pset, pid, -1, errno);
9067c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
9077c478bd9Sstevel@tonic-gate 					continue;
9087c478bd9Sstevel@tonic-gate 				}
9097c478bd9Sstevel@tonic-gate 				if (qflag)
9107c478bd9Sstevel@tonic-gate 					query_out(pid, -1, old_pset);
9117c478bd9Sstevel@tonic-gate 				else
9127c478bd9Sstevel@tonic-gate 					bind_out(pid, -1, old_pset, pset);
9137c478bd9Sstevel@tonic-gate 			}
9147c478bd9Sstevel@tonic-gate 		}
9157c478bd9Sstevel@tonic-gate 	}
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 	if (Qflag || Uflag) {
9187c478bd9Sstevel@tonic-gate 		/*
9197c478bd9Sstevel@tonic-gate 		 * Go through listed processor set IDs.
9207c478bd9Sstevel@tonic-gate 		 */
9217c478bd9Sstevel@tonic-gate 		for (; argc > 0; argv++, argc--) {
9227c478bd9Sstevel@tonic-gate 			errno = 0;
9237c478bd9Sstevel@tonic-gate 			pset = (id_t)strtol(*argv, &errptr, 10);
9247c478bd9Sstevel@tonic-gate 			if (errno != 0 ||
9257c478bd9Sstevel@tonic-gate 			    (errptr != NULL && *errptr != '\0')) {
9267c478bd9Sstevel@tonic-gate 				warn(gettext("invalid processor set ID\n"));
9277c478bd9Sstevel@tonic-gate 				continue;
9287c478bd9Sstevel@tonic-gate 			}
9297c478bd9Sstevel@tonic-gate 			if (Qflag) {
9307c478bd9Sstevel@tonic-gate 				(void) proc_walk(query_all_lwp,
9317c478bd9Sstevel@tonic-gate 				    &pset, PR_WALK_LWP);
9327c478bd9Sstevel@tonic-gate 				continue;
9337c478bd9Sstevel@tonic-gate 			}
9347c478bd9Sstevel@tonic-gate 			if (Uflag) {
9357c478bd9Sstevel@tonic-gate 				if (pset_bind(PS_NONE, P_PSETID, pset,
9367c478bd9Sstevel@tonic-gate 				    &old_pset) != 0) {
9377c478bd9Sstevel@tonic-gate 					warn(gettext("failed to unbind from "
9387c478bd9Sstevel@tonic-gate 					    "processor set %d"), (int)pset);
9397c478bd9Sstevel@tonic-gate 					errors = ERR_FAIL;
9407c478bd9Sstevel@tonic-gate 				}
9417c478bd9Sstevel@tonic-gate 				continue;
9427c478bd9Sstevel@tonic-gate 			}
9437c478bd9Sstevel@tonic-gate 		}
9447c478bd9Sstevel@tonic-gate 	}
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	return (errors);
9477c478bd9Sstevel@tonic-gate }
948