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 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 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 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 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 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