Print this page
6535 Add pbind -e
Reviewed by: Mohamed Khalfella <khalfella@gmail.com>
Reviewed by: Cody Mello <melloc@joyent.com>
Reviewed by: Albert Lee <trisk@omniti.com>
*** 18,33 ****
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
- #pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* pbind - bind a process to a processor (non-exclusively)
*/
#include <sys/types.h>
--- 18,32 ----
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
+ * Copyright 2015 Ryan Zezeski
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* pbind - bind a process to a processor (non-exclusively)
*/
#include <sys/types.h>
*** 52,61 ****
--- 51,61 ----
#define ERR_FAIL 1 /* exit status for errors */
#define ERR_USAGE 2 /* exit status for usage errors */
static char *progname;
static char bflag;
+ static char eflag;
static char qflag;
static char Qflag;
static char uflag;
static char Uflag;
static int errors;
*** 343,357 ****
--- 343,391 ----
(cpuid == NULL && binding != PBIND_NONE))
query_out(pid, lwpid, binding);
return (0);
}
+ /*
+ * Execute the cmd with args while bound to cpu. Does not return:
+ * either executes cmd successfully or dies trying.
+ */
+ static void
+ exec_cmd(processorid_t cpu, char *cmd, char **args)
+ {
+ if (processor_bind(P_PID, P_MYID, cpu, NULL) == -1) {
+ bind_err(cpu, getpid(), -1, errno);
+ exit(ERR_FAIL);
+ }
+
+ if (execvp(cmd, args) == -1)
+ die(gettext("failed to exec %s\n"), cmd);
+ }
+
+ /*
+ * Attempt to parse str as a CPU identifier. Return the identifier or
+ * die.
+ */
+ static processorid_t
+ parse_cpu(char *str)
+ {
+ processorid_t cpu;
+ char *endstr;
+
+ cpu = strtol(str, &endstr, 10);
+ if (endstr != NULL && *endstr != '\0' || cpu < 0)
+ die(gettext("invalid processor ID %s\n"), optarg);
+
+ return (cpu);
+ }
+
static int
usage(void)
{
(void) fprintf(stderr,
gettext("usage: \n\t%1$s -b processor_id pid[/lwpids] ...\n"
+ "\t%1$s -e processor_id cmd [args...]\n"
"\t%1$s -U [processor_id] ...\n"
"\t%1$s -Q [processor_id] ...\n"
"\t%1$s -u pid[/lwpids] ...\n"
"\t%1$s [-q] [pid[/lwpids] ...]\n"),
progname);
*** 370,390 ****
progname = argv[0]; /* put actual command name in messages */
(void) setlocale(LC_ALL, ""); /* setup localization */
(void) textdomain(TEXT_DOMAIN);
! while ((c = getopt(argc, argv, "b:qQuU")) != EOF) {
switch (c) {
case 'b':
bflag = 1;
! cpu = strtol(optarg, &endstr, 10);
! if (endstr != NULL && *endstr != '\0' || cpu < 0)
! die(gettext("invalid processor ID %s\n"),
! optarg);
break;
case 'q':
qflag = 1;
cpu = PBIND_QUERY;
break;
--- 404,426 ----
progname = argv[0]; /* put actual command name in messages */
(void) setlocale(LC_ALL, ""); /* setup localization */
(void) textdomain(TEXT_DOMAIN);
! while ((c = getopt(argc, argv, "b:e:qQuU")) != EOF) {
switch (c) {
case 'b':
bflag = 1;
! cpu = parse_cpu(optarg);
break;
+ case 'e':
+ eflag = 1;
+ cpu = parse_cpu(optarg);
+ break;
+
case 'q':
qflag = 1;
cpu = PBIND_QUERY;
break;
*** 407,425 ****
}
}
/*
! * Make sure that at most one of the options b, q, Q, u, or U
! * was specified.
*/
! c = bflag + qflag + Qflag + uflag + Uflag;
if (c < 1) { /* nothing specified */
qflag = 1; /* default to query */
cpu = PBIND_QUERY;
} else if (c > 1) {
! warn(gettext("options -b, -q, -Q, -u and -U "
"are mutually exclusive\n"));
return (usage());
}
errors = 0;
--- 443,461 ----
}
}
/*
! * Make sure that at most one of the options b, e, q, Q, u, or
! * U was specified.
*/
! c = bflag + eflag + qflag + Qflag + uflag + Uflag;
if (c < 1) { /* nothing specified */
qflag = 1; /* default to query */
cpu = PBIND_QUERY;
} else if (c > 1) {
! warn(gettext("options -b, -e, -q, -Q, -u and -U "
"are mutually exclusive\n"));
return (usage());
}
errors = 0;
*** 432,441 ****
--- 468,481 ----
if (argc == 0) {
if (bflag || uflag) {
warn(gettext("must specify at least one pid\n"));
return (usage());
}
+ if (eflag) {
+ warn(gettext("must specify command\n"));
+ return (usage());
+ }
if (Uflag) {
if (processor_bind(P_ALL, 0, PBIND_NONE, &old_cpu) != 0)
die(gettext("failed to unbind some LWPs"));
}
if (Qflag) {
*** 445,454 ****
--- 485,497 ----
(void) proc_walk(query_all_proc, NULL, PR_WALK_PROC);
return (errors);
}
}
+ if (eflag)
+ exec_cmd(cpu, argv[0], argv);
+
if (Qflag || Uflag) {
/*
* Go through listed processor IDs.
*/
for (; argc > 0; argv++, argc--) {