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