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*af6a63acSGangadhar Mylapuram * Common Development and Distribution License (the "License").
6*af6a63acSGangadhar Mylapuram * 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*af6a63acSGangadhar Mylapuram * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate * poolbind - bind processes, tasks, and projects to pools, and query process
277c478bd9Sstevel@tonic-gate * pool bindings
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <libgen.h>
317c478bd9Sstevel@tonic-gate #include <pool.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <unistd.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <locale.h>
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include <sys/procset.h>
427c478bd9Sstevel@tonic-gate #include <sys/types.h>
437c478bd9Sstevel@tonic-gate #include <sys/stat.h>
447c478bd9Sstevel@tonic-gate #include <errno.h>
457c478bd9Sstevel@tonic-gate #include <project.h>
467c478bd9Sstevel@tonic-gate #include <zone.h>
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include "utils.h"
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN
517c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
527c478bd9Sstevel@tonic-gate #endif
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate #define eFLAG 0x1
557c478bd9Sstevel@tonic-gate #define iFLAG 0x2
567c478bd9Sstevel@tonic-gate #define pFLAG 0x4
577c478bd9Sstevel@tonic-gate #define qFLAG 0x8
587c478bd9Sstevel@tonic-gate #define QFLAG 0x10
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate static const char OPTS[] = "Qei:p:q";
617c478bd9Sstevel@tonic-gate static struct {
627c478bd9Sstevel@tonic-gate idtype_t idtype;
637c478bd9Sstevel@tonic-gate char *str;
647c478bd9Sstevel@tonic-gate } idtypes[] = {
657c478bd9Sstevel@tonic-gate { P_PID, "pid" },
667c478bd9Sstevel@tonic-gate { P_TASKID, "taskid" },
677c478bd9Sstevel@tonic-gate { P_PROJID, "projid" },
687c478bd9Sstevel@tonic-gate { P_PROJID, "project" },
697c478bd9Sstevel@tonic-gate { P_ZONEID, "zoneid" },
707c478bd9Sstevel@tonic-gate { -1, NULL }
717c478bd9Sstevel@tonic-gate };
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate int error = E_PO_SUCCESS;
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate void exec_cmd(char *, char *[]);
767c478bd9Sstevel@tonic-gate void process_ids(char *, uint_t, idtype_t, char *, int, char *[]);
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate void
usage(void)797c478bd9Sstevel@tonic-gate usage(void)
807c478bd9Sstevel@tonic-gate {
817c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
827c478bd9Sstevel@tonic-gate gettext("Usage:\n"
837c478bd9Sstevel@tonic-gate " poolbind -p pool_name -e command [arguments...]\n"
847c478bd9Sstevel@tonic-gate " poolbind -p pool_name "
857c478bd9Sstevel@tonic-gate "[-i pid | -i taskid | -i projid | -i zoneid] id ...\n"
867c478bd9Sstevel@tonic-gate " poolbind -q pid ...\n"
877c478bd9Sstevel@tonic-gate " poolbind -Q pid ... \n"));
887c478bd9Sstevel@tonic-gate exit(E_USAGE);
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate int
print_resource_binding(const char * type,pid_t pid)927c478bd9Sstevel@tonic-gate print_resource_binding(const char *type, pid_t pid)
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate char *resource_name;
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate if ((resource_name = pool_get_resource_binding(type, pid)) == NULL)
977c478bd9Sstevel@tonic-gate warn(gettext("getting '%s' binding for %d: %s\n"), type,
987c478bd9Sstevel@tonic-gate (int)pid, get_errstr());
997c478bd9Sstevel@tonic-gate else
1007c478bd9Sstevel@tonic-gate (void) printf("%d\t%s\t%s\n", (int)pid, type, resource_name);
1017c478bd9Sstevel@tonic-gate free(resource_name);
1027c478bd9Sstevel@tonic-gate return (PO_SUCCESS);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])1067c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate char c;
1097c478bd9Sstevel@tonic-gate int i;
1107c478bd9Sstevel@tonic-gate idtype_t idtype = P_PID;
1117c478bd9Sstevel@tonic-gate char *idstr = "pid";
1127c478bd9Sstevel@tonic-gate char *pool_name = NULL;
1137c478bd9Sstevel@tonic-gate uint_t flags = 0;
1147c478bd9Sstevel@tonic-gate int status;
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate (void) getpname(argv[0]);
1177c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
1187c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTS)) != EOF) {
1217c478bd9Sstevel@tonic-gate switch (c) {
1227c478bd9Sstevel@tonic-gate case 'Q':
1237c478bd9Sstevel@tonic-gate if (flags & (qFLAG | iFLAG | pFLAG))
1247c478bd9Sstevel@tonic-gate usage();
1257c478bd9Sstevel@tonic-gate flags |= QFLAG;
1267c478bd9Sstevel@tonic-gate break;
1277c478bd9Sstevel@tonic-gate case 'e':
1287c478bd9Sstevel@tonic-gate if (flags & (iFLAG | qFLAG | QFLAG))
1297c478bd9Sstevel@tonic-gate usage();
1307c478bd9Sstevel@tonic-gate flags |= eFLAG;
1317c478bd9Sstevel@tonic-gate break;
1327c478bd9Sstevel@tonic-gate case 'i':
1337c478bd9Sstevel@tonic-gate for (i = 0; idtypes[i].str != NULL; i++) {
1347c478bd9Sstevel@tonic-gate if (strcmp(optarg, idtypes[i].str) == 0) {
1357c478bd9Sstevel@tonic-gate idtype = idtypes[i].idtype;
1367c478bd9Sstevel@tonic-gate idstr = idtypes[i].str;
1377c478bd9Sstevel@tonic-gate break;
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate if ((flags & (iFLAG | qFLAG | QFLAG)) ||
1417c478bd9Sstevel@tonic-gate idtypes[i].str == NULL)
1427c478bd9Sstevel@tonic-gate usage();
1437c478bd9Sstevel@tonic-gate flags |= iFLAG;
1447c478bd9Sstevel@tonic-gate break;
1457c478bd9Sstevel@tonic-gate case 'p':
1467c478bd9Sstevel@tonic-gate if (flags & (pFLAG | qFLAG | QFLAG))
1477c478bd9Sstevel@tonic-gate usage();
1487c478bd9Sstevel@tonic-gate flags |= pFLAG;
1497c478bd9Sstevel@tonic-gate pool_name = optarg;
1507c478bd9Sstevel@tonic-gate break;
1517c478bd9Sstevel@tonic-gate case 'q':
1527c478bd9Sstevel@tonic-gate if (flags & (pFLAG | iFLAG | QFLAG))
1537c478bd9Sstevel@tonic-gate usage();
1547c478bd9Sstevel@tonic-gate flags |= qFLAG;
1557c478bd9Sstevel@tonic-gate break;
1567c478bd9Sstevel@tonic-gate case '?':
1577c478bd9Sstevel@tonic-gate default:
1587c478bd9Sstevel@tonic-gate usage();
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate argc -= optind;
1637c478bd9Sstevel@tonic-gate argv += optind;
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate if (flags & eFLAG && pool_name == NULL)
1667c478bd9Sstevel@tonic-gate usage();
1677c478bd9Sstevel@tonic-gate if (argc < 1 || (flags & (pFLAG | qFLAG | QFLAG)) == 0)
1687c478bd9Sstevel@tonic-gate usage();
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate * Check to see that the pools facility is enabled
1727c478bd9Sstevel@tonic-gate */
1737c478bd9Sstevel@tonic-gate if (pool_get_status(&status) != PO_SUCCESS)
1747c478bd9Sstevel@tonic-gate die((ERR_OPEN_DYNAMIC), get_errstr());
1757c478bd9Sstevel@tonic-gate if (status == POOL_DISABLED)
1767c478bd9Sstevel@tonic-gate die((ERR_OPEN_DYNAMIC), strerror(ENOTACTIVE));
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate if (flags & eFLAG)
1797c478bd9Sstevel@tonic-gate exec_cmd(pool_name, argv);
1807c478bd9Sstevel@tonic-gate /*NOTREACHED*/
1817c478bd9Sstevel@tonic-gate else
1827c478bd9Sstevel@tonic-gate process_ids(pool_name, flags, idtype, idstr, argc, argv);
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate return (error);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate void
exec_cmd(char * pool_name,char * argv[])1887c478bd9Sstevel@tonic-gate exec_cmd(char *pool_name, char *argv[])
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate if (pool_set_binding(pool_name, P_PID, getpid()) != PO_SUCCESS) {
1917c478bd9Sstevel@tonic-gate warn(gettext("binding to pool '%s': %s\n"), pool_name,
1927c478bd9Sstevel@tonic-gate get_errstr());
1937c478bd9Sstevel@tonic-gate error = E_ERROR;
1947c478bd9Sstevel@tonic-gate return;
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate
197*af6a63acSGangadhar Mylapuram if (execvp(argv[0], argv) == -1)
1987c478bd9Sstevel@tonic-gate die(gettext("exec of %s failed"), argv[0]);
1997c478bd9Sstevel@tonic-gate /*NOTREACHED*/
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate void
process_ids(char * pool_name,uint_t flags,idtype_t idtype,char * idstr,int argc,char * argv[])2037c478bd9Sstevel@tonic-gate process_ids(char *pool_name, uint_t flags, idtype_t idtype, char *idstr,
2047c478bd9Sstevel@tonic-gate int argc, char *argv[])
2057c478bd9Sstevel@tonic-gate {
2067c478bd9Sstevel@tonic-gate int i;
2077c478bd9Sstevel@tonic-gate id_t id;
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i++) {
2107c478bd9Sstevel@tonic-gate char *endp;
2117c478bd9Sstevel@tonic-gate char *poolname;
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate errno = 0;
2147c478bd9Sstevel@tonic-gate id = (id_t)strtol(argv[i], &endp, 10);
2157c478bd9Sstevel@tonic-gate if (errno != 0 ||
2167c478bd9Sstevel@tonic-gate (endp && endp != argv[i] + strlen(argv[i])) ||
2177c478bd9Sstevel@tonic-gate (idtype == P_ZONEID &&
2187c478bd9Sstevel@tonic-gate getzonenamebyid(id, NULL, 0) == -1)) {
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate * The string does not completely parse to
2217c478bd9Sstevel@tonic-gate * an integer, or it represents an invalid
2227c478bd9Sstevel@tonic-gate * zone id.
2237c478bd9Sstevel@tonic-gate */
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate * It must be a project or zone name.
2277c478bd9Sstevel@tonic-gate */
2287c478bd9Sstevel@tonic-gate if (idtype == P_ZONEID) {
2297c478bd9Sstevel@tonic-gate if (zone_get_id(argv[i], &id) != 0) {
2307c478bd9Sstevel@tonic-gate warn(gettext("invalid zone '%s'\n"),
2317c478bd9Sstevel@tonic-gate argv[i]);
2327c478bd9Sstevel@tonic-gate error = E_ERROR;
2337c478bd9Sstevel@tonic-gate continue;
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate /* make sure the zone is booted */
2367c478bd9Sstevel@tonic-gate if (id == -1) {
2377c478bd9Sstevel@tonic-gate warn(gettext("zone '%s' is not "
2387c478bd9Sstevel@tonic-gate "active\n"), argv[i]);
2397c478bd9Sstevel@tonic-gate error = E_ERROR;
2407c478bd9Sstevel@tonic-gate continue;
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate } else if (idtype == P_PROJID) {
2437c478bd9Sstevel@tonic-gate if ((id = getprojidbyname(argv[i])) < 0) {
2447c478bd9Sstevel@tonic-gate warn(gettext("failed to get project "
2457c478bd9Sstevel@tonic-gate "id for project: '%s'"), argv[i]);
2467c478bd9Sstevel@tonic-gate error = E_ERROR;
2477c478bd9Sstevel@tonic-gate continue;
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate } else {
2507c478bd9Sstevel@tonic-gate warn(gettext("invalid %s '%s'\n"),
2517c478bd9Sstevel@tonic-gate idstr, argv[i]);
2527c478bd9Sstevel@tonic-gate error = E_ERROR;
2537c478bd9Sstevel@tonic-gate continue;
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate if (flags & pFLAG) {
2587c478bd9Sstevel@tonic-gate if (pool_set_binding(pool_name, idtype, id) !=
2597c478bd9Sstevel@tonic-gate PO_SUCCESS) {
2607c478bd9Sstevel@tonic-gate warn(gettext("binding %s %ld to pool '%s': "
2617c478bd9Sstevel@tonic-gate "%s\n"), idstr, id, pool_name,
2627c478bd9Sstevel@tonic-gate get_errstr());
2637c478bd9Sstevel@tonic-gate error = E_ERROR;
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate continue;
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate if (flags & qFLAG) {
2697c478bd9Sstevel@tonic-gate if ((poolname = pool_get_binding(id)) == NULL) {
2707c478bd9Sstevel@tonic-gate warn(gettext("couldn't determine binding for "
2717c478bd9Sstevel@tonic-gate "pid %ld: %s\n"), id, get_errstr());
2727c478bd9Sstevel@tonic-gate error = E_ERROR;
2737c478bd9Sstevel@tonic-gate } else {
2747c478bd9Sstevel@tonic-gate (void) printf("%ld\t%s\n", id, poolname);
2757c478bd9Sstevel@tonic-gate free(poolname);
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate if (flags & QFLAG) {
2797c478bd9Sstevel@tonic-gate uint_t j, count;
2807c478bd9Sstevel@tonic-gate const char **resource_types;
2817c478bd9Sstevel@tonic-gate (void) pool_resource_type_list(NULL, &count);
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate if ((resource_types = malloc(count *
2847c478bd9Sstevel@tonic-gate sizeof (const char *))) == NULL) {
2857c478bd9Sstevel@tonic-gate warn(gettext("couldn't allocate query memory "
2867c478bd9Sstevel@tonic-gate "for pid %ld: %s\n"), id, get_errstr());
2877c478bd9Sstevel@tonic-gate error = E_ERROR;
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate (void) pool_resource_type_list(resource_types, &count);
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate for (j = 0; j < count; j++)
2927c478bd9Sstevel@tonic-gate (void) print_resource_binding(resource_types[j],
2937c478bd9Sstevel@tonic-gate (pid_t)id);
2947c478bd9Sstevel@tonic-gate free(resource_types);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate }
298