usr/src/uts/common/os/pool.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 1336 059ab7fcc106
child 3247 e05001c14ea2
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1336
059ab7fcc106 6331878 pooladm -c reports invalid configuration when hostname begins with a number
gm149974
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
059ab7fcc106 6331878 pooladm -c reports invalid configuration when hostname begins with a number
gm149974
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
1336
059ab7fcc106 6331878 pooladm -c reports invalid configuration when hostname begins with a number
gm149974
parents: 0
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/pool.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/pool_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <sys/pool_pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/id_space.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/mutex.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/nvpair.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/fss.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/class.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/exacct.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/utsname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/procset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * RESOURCE POOLS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 * The resource pools facility brings together process-bindable resource into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 * a common abstraction called a pool. Processor sets and other entities can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * be configured, grouped, and labelled such that workload components can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * associated with a subset of a system's total resources.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * When disabled, the pools facility is "invisible".  All processes belong
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * to the same pool (pool_default), and processor sets can be managed through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 * the old pset() system call.  When enabled, processor sets can only be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 * managed via the pools facility.  New pools can be created and associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * with processor sets.  Processes can be bound to pools which have non-empty
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * resource sets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * Locking: pool_lock() protects global pools state and must be called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * before modifying the configuration, or when taking a snapshot of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 * configuration.  If pool_lock_intr() is used, the operation may be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 * interrupted by a signal or a request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 * To prevent processes from being rebound between pools while they are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 * the middle of an operation which affects resource set bindings, such
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 * operations must be surrounded by calls to pool_barrier_enter() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * pool_barrier_exit().  This mechanism guarantees that such processes will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 * be stopped either at the beginning or at the end of the barrier so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 * the rebind operation can atomically bind the process and its threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 * to new resource sets, and then let process run again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 * Lock ordering with respect to other locks is as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 * 	pool_lock() -> cpu_lock -> pidlock -> p_lock -> pool_barrier_lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * Most static and global variables defined in this file are protected
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * by calling pool_lock().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * The operation that binds tasks and projects to pools is atomic.  That is,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * either all processes in a given task or a project will be bound to a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 * new pool, or (in case of an error) they will be all left bound to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 * old pool. Processes in a given task or a given project can only be bound to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 * different pools if they were rebound individually one by one as single
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * processes.  Threads or LWPs of the same process do not have pool bindings,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * and are bound to the same resource sets associated with the resource pool
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * of that process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 * The following picture shows one possible pool configuration with three
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * pools and three processor sets.  Note that processor set "foo" is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 * associated with any pools and therefore cannot have any processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * bound to it.  Two pools (default and foo) are associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * same processor set (default).  Also, note that processes in Task 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 * are bound to different pools.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 *							       Processor Sets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 *								+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 *		       +--------------+========================>| default |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 *		      a|	      |				+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 *		      s|	      |				    ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 *		      s|	      |				+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 *		      o|	      |				|   foo   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 *		      c|	      |				+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 *		      i|	      |				    ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 *		      a|	      |				+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 *		      t|	      |			+------>|   bar   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 *		      e|	      |			|	+---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 *                    d|              |                 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 *                     |              |                 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 *	       +---------+      +---------+      +---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 *     Pools   | default |======|   foo   |======|   bar   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *	       +---------+      +---------+      +---------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 *	           @  @            @              @ @   @
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 *                b|  |            |              | |   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 *                o|  |            |              | |   |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 *                u|  +-----+      |      +-------+ |   +---+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *                n|        |      |      |         |       |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 *            ....d|........|......|......|.........|.......|....
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 *            :    |   ::   |      |      |    ::   |       |   :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 *            :  +---+ :: +---+  +---+  +---+  :: +---+   +---+ :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 *  Processes :  | p | :: | p |  | p |  | p |  :: | p |...| p | :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 *            :  +---+ :: +---+  +---+  +---+  :: +---+   +---+ :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 *            :........::......................::...............:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 *              Task 1            Task 2              Task N
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 *                 |                 |                  |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 *                 |                 |                  |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 *                 |  +-----------+  |             +-----------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 *                 +--| Project 1 |--+             | Project N |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 *                    +-----------+                +-----------+
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * This is just an illustration of relationships between processes, tasks,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 * projects, pools, and processor sets. New types of resource sets will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 * added in the future.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
pool_t		*pool_default;	/* default pool which always exists */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
int		pool_count;	/* number of pools created on this system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
int		pool_state;	/* pools state -- enabled/disabled */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
void		*pool_buf;	/* pre-commit snapshot of the pools state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
size_t		pool_bufsz;	/* size of pool_buf */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
static hrtime_t	pool_pool_mod;	/* last modification time for pools */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
static hrtime_t	pool_sys_mod;	/* last modification time for system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
static nvlist_t	*pool_sys_prop;	/* system properties */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
static id_space_t *pool_ids;	/* pool ID space */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
static list_t	pool_list;	/* doubly-linked list of pools */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
static kmutex_t		pool_mutex;		/* protects pool_busy_* */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
static kcondvar_t	pool_busy_cv;		/* waiting for "pool_lock" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
static kthread_t	*pool_busy_thread;	/* thread holding "pool_lock" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
static kmutex_t		pool_barrier_lock;	/* synch. with pool_barrier_* */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
static kcondvar_t	pool_barrier_cv;	/* synch. with pool_barrier_* */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
static int		pool_barrier_count;	/* synch. with pool_barrier_* */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
 * Boot-time pool initialization.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
pool_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	pool_ids = id_space_create("pool_ids", POOL_DEFAULT + 1, POOL_MAXID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	 * Initialize default pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	pool_default = kmem_zalloc(sizeof (pool_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	pool_default->pool_id = POOL_DEFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	list_create(&pool_list, sizeof (pool_t), offsetof(pool_t, pool_link));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	list_insert_head(&pool_list, pool_default);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	 * Initialize plugins for resource sets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	pool_pset_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	pool_count = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	p0.p_pool = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	global_zone->zone_pool = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	pool_default->pool_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 * Synchronization routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
 * pool_lock is only called from syscall-level routines (processor_bind(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
 * pset_*(), and /dev/pool ioctls).  The pool "lock" may be held for long
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
 * periods of time, including across sleeping operations, so we allow its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
 * acquisition to be interruptible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
 * The current thread that owns the "lock" is stored in the variable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
 * pool_busy_thread, both to let pool_lock_held() work and to aid debugging.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
pool_lock(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	mutex_enter(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	while (pool_busy_thread != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		cv_wait(&pool_busy_cv, &pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	pool_busy_thread = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	mutex_exit(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
pool_lock_intr(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	mutex_enter(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	while (pool_busy_thread != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
		if (cv_wait_sig(&pool_busy_cv, &pool_mutex) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
			cv_signal(&pool_busy_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
			mutex_exit(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	pool_busy_thread = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	mutex_exit(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
pool_lock_held(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	return (pool_busy_thread == curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
pool_unlock(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	mutex_enter(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	pool_busy_thread = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	cv_signal(&pool_busy_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	mutex_exit(&pool_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
 * Routines allowing fork(), exec(), exit(), and lwp_create() to synchronize
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
 * with pool_do_bind().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
 * Calls to pool_barrier_enter() and pool_barrier_exit() must bracket all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
 * operations which modify pool or pset associations.  They can be called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
 * while the process is multi-threaded.  In the common case, when current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
 * process is not being rebound (PBWAIT flag is not set), these functions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
 * will be just incrementing and decrementing reference counts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
pool_barrier_enter(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	proc_t *p = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	while (p->p_poolflag & PBWAIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
		cv_wait(&p->p_poolcv, &p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	p->p_poolcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
pool_barrier_exit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	proc_t *p = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	ASSERT(p->p_poolcnt > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	p->p_poolcnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	if (p->p_poolflag & PBWAIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
		mutex_enter(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		ASSERT(pool_barrier_count > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		pool_barrier_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		if (pool_barrier_count == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
			cv_signal(&pool_barrier_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		mutex_exit(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		while (p->p_poolflag & PBWAIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
			cv_wait(&p->p_poolcv, &p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
 * Enable pools facility.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
pool_enable(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	ASSERT(pool_count == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	ret = pool_pset_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
		return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	(void) nvlist_alloc(&pool_sys_prop, NV_UNIQUE_NAME, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	(void) nvlist_add_string(pool_sys_prop, "system.name",
1336
059ab7fcc106 6331878 pooladm -c reports invalid configuration when hostname begins with a number
gm149974
parents: 0
diff changeset
   292
	    "default");
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	(void) nvlist_add_string(pool_sys_prop, "system.comment", "");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	(void) nvlist_add_int64(pool_sys_prop, "system.version", 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	(void) nvlist_add_byte(pool_sys_prop, "system.bind-default", 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	(void) nvlist_alloc(&pool_default->pool_props,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	    NV_UNIQUE_NAME, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	(void) nvlist_add_string(pool_default->pool_props,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
	    "pool.name", "pool_default");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	(void) nvlist_add_string(pool_default->pool_props, "pool.comment", "");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	(void) nvlist_add_byte(pool_default->pool_props, "pool.default", 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	(void) nvlist_add_byte(pool_default->pool_props, "pool.active", 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	(void) nvlist_add_int64(pool_default->pool_props,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	    "pool.importance", 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	(void) nvlist_add_int64(pool_default->pool_props, "pool.sys_id",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	    pool_default->pool_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	pool_sys_mod = pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 * Disable pools facility.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
pool_disable(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	if (pool_count > 1)	/* must destroy all pools first */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	ret = pool_pset_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
		return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	if (pool_sys_prop != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
		nvlist_free(pool_sys_prop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		pool_sys_prop = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	if (pool_default->pool_props != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
		nvlist_free(pool_default->pool_props);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
		pool_default->pool_props = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
pool_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
pool_lookup_pool_by_name(char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	pool_t *pool = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	char *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	for (pool = list_head(&pool_list); pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
	    pool = list_next(&pool_list, pool)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		if (nvlist_lookup_string(pool->pool_props,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
		    "pool.name", &p) == 0 && strcmp(name, p) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
			return (pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
pool_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
pool_lookup_pool_by_id(poolid_t poolid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	pool_t *pool = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	for (pool = list_head(&pool_list); pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	    pool = list_next(&pool_list, pool)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		if (pool->pool_id == poolid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
			return (pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
 * Create new pool, associate it with default resource sets, and give
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
 * it a temporary name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
pool_pool_create(poolid_t *poolid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	char pool_name[40];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	pool = kmem_zalloc(sizeof (pool_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	pool->pool_id = *poolid = id_alloc(pool_ids);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	pool->pool_pset = pool_pset_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	pool_pset_default->pset_npools++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	list_insert_tail(&pool_list, pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	(void) nvlist_alloc(&pool->pool_props, NV_UNIQUE_NAME, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	(void) nvlist_add_int64(pool->pool_props, "pool.sys_id", pool->pool_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	(void) nvlist_add_byte(pool->pool_props, "pool.default", 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	(void) snprintf(pool_name, sizeof (pool_name), "pool_%lld",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	    pool_pool_mod);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	(void) nvlist_add_string(pool->pool_props, "pool.name", pool_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
	pool_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
struct destroy_zone_arg {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	pool_t *old;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	pool_t *new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 * Update pool pointers for zones that are currently bound to pool "old"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
 * to be bound to pool "new".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
pool_destroy_zone_cb(zone_t *zone, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	struct destroy_zone_arg *dza = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	if (zone_pool_get(zone) == dza->old)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
		zone_pool_set(zone, dza->new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
 * Destroy specified pool, and rebind all processes in it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
 * to the default pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
pool_pool_destroy(poolid_t poolid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	if (poolid == POOL_DEFAULT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	if ((pool = pool_lookup_pool_by_id(poolid)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	ret = pool_do_bind(pool_default, P_POOLID, poolid, POOL_BIND_ALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	if (ret == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
		struct destroy_zone_arg dzarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
		dzarg.old = pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		dzarg.new = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
		mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
		ret = zone_walk(pool_destroy_zone_cb, &dzarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
		mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
		ASSERT(ret == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		ASSERT(pool->pool_ref == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
		(void) nvlist_free(pool->pool_props);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
		id_free(pool_ids, pool->pool_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
		pool->pool_pset->pset_npools--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
		list_remove(&pool_list, pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
		pool_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
		pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
		kmem_free(pool, sizeof (pool_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
 * Create new pool or resource set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
pool_create(int class, int subclass, id_t *id)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	switch (class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	case PEC_POOL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
		ret = pool_pool_create((poolid_t *)id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	case PEC_RES_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
		case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
			ret = pool_pset_create((psetid_t *)id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	case PEC_RES_AGG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
		ret = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
 * Destroy an existing pool or resource set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
pool_destroy(int class, int subclass, id_t id)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	switch (class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	case PEC_POOL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		ret = pool_pool_destroy((poolid_t)id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	case PEC_RES_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
		case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
			ret = pool_pset_destroy((psetid_t)id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	case PEC_RES_AGG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		ret = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
 * Enable or disable pools.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
pool_status(int status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	int ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	if (pool_state == status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	switch (status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	case POOL_ENABLED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
		ret = pool_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
			return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		pool_state = POOL_ENABLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
	case POOL_DISABLED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		ret = pool_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
			return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		pool_state = POOL_DISABLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
 * Associate pool with resource set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
pool_assoc(poolid_t poolid, int idtype, id_t id)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		ret = pool_pset_assoc(poolid, (psetid_t)id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
 * Disassociate resource set from pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
pool_dissoc(poolid_t poolid, int idtype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
	switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
		ret = pool_pset_assoc(poolid, PS_NONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
		pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
 * Transfer specified quantity of resources between resource sets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
pool_transfer(int type, id_t src, id_t dst, uint64_t qty)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	int ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
 * Transfer resources specified by their IDs between resource sets.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
pool_xtransfer(int type, id_t src, id_t dst, uint_t size, id_t *ids)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	switch (type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
	case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		ret = pool_pset_xtransfer((psetid_t)src, (psetid_t)dst,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		    size, ids);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
 * Bind processes to pools.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
pool_bind(poolid_t poolid, idtype_t idtype, id_t id)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	if ((pool = pool_lookup_pool_by_id(poolid)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	case P_PID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	case P_TASKID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	case P_PROJID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	case P_ZONEID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
	return (pool_do_bind(pool, idtype, id, POOL_BIND_ALL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
 * Query pool binding of the specifed process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
pool_query_binding(idtype_t idtype, id_t id, id_t *poolid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	if (idtype != P_PID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		return (ENOTSUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		id = curproc->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	if ((p = prfind((pid_t)id)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
		mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	 * In local zones, lie about pool bindings of processes from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	 * the global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	if (!INGLOBALZONE(curproc) && INGLOBALZONE(p)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
		pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
		pool = zone_pool_get(curproc->p_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
		*poolid = pool->pool_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
		*poolid = p->p_pool->pool_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
static ea_object_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
pool_system_pack(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	ea_object_t *eo_system;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
	size_t bufsz = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
	char *buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	eo_system = ea_alloc_group(EXT_GROUP | EXC_LOCAL | EXD_GROUP_SYSTEM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	(void) ea_attach_item(eo_system, &pool_sys_mod, sizeof (hrtime_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	    EXC_LOCAL | EXD_SYSTEM_TSTAMP | EXT_UINT64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
	if (INGLOBALZONE(curproc))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
		(void) ea_attach_item(eo_system, &pool_pool_mod,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
		    sizeof (hrtime_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		    EXC_LOCAL | EXD_POOL_TSTAMP | EXT_UINT64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		(void) ea_attach_item(eo_system,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
		    &curproc->p_zone->zone_pool_mod,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		    sizeof (hrtime_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		    EXC_LOCAL | EXD_POOL_TSTAMP | EXT_UINT64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
	(void) ea_attach_item(eo_system, &pool_pset_mod, sizeof (hrtime_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	    EXC_LOCAL | EXD_PSET_TSTAMP | EXT_UINT64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	(void) ea_attach_item(eo_system, &pool_cpu_mod, sizeof (hrtime_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	    EXC_LOCAL | EXD_CPU_TSTAMP | EXT_UINT64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	(void) nvlist_pack(pool_sys_prop, &buf, &bufsz, NV_ENCODE_NATIVE, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	(void) ea_attach_item(eo_system, buf, bufsz,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	    EXC_LOCAL | EXD_SYSTEM_PROP | EXT_RAW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	kmem_free(buf, bufsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	return (eo_system);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
 * Pack information about pools and attach it to specified exacct group.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
pool_pool_pack(ea_object_t *eo_system)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
	ea_object_t *eo_pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
	size_t bufsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	char *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	pool_t *myzonepool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
	myzonepool = zone_pool_get(curproc->p_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	for (pool = list_head(&pool_list); pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	    pool = list_next(&pool_list, pool)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		if (!INGLOBALZONE(curproc) && myzonepool != pool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		bufsz = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
		eo_pool = ea_alloc_group(EXT_GROUP |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
		    EXC_LOCAL | EXD_GROUP_POOL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
		(void) ea_attach_item(eo_pool, &pool->pool_id, sizeof (id_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
		    EXC_LOCAL | EXD_POOL_POOLID | EXT_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
		(void) ea_attach_item(eo_pool, &pool->pool_pset->pset_id,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
		    sizeof (id_t), EXC_LOCAL | EXD_POOL_PSETID | EXT_UINT32);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		(void) nvlist_pack(pool->pool_props, &buf, &bufsz,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		    NV_ENCODE_NATIVE, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
		(void) ea_attach_item(eo_pool, buf, bufsz,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
		    EXC_LOCAL | EXD_POOL_PROP | EXT_RAW);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
		kmem_free(buf, bufsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
		(void) ea_attach_to_group(eo_system, eo_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
 * Pack the whole pool configuration in the specified buffer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
pool_pack_conf(void *kbuf, size_t kbufsz, size_t *asize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	ea_object_t *eo_system;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	size_t ksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	int ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	eo_system = pool_system_pack();		/* 1. pack system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	(void) pool_pool_pack(eo_system);	/* 2. pack all pools */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	(void) pool_pset_pack(eo_system);	/* 3. pack all psets */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	ksize = ea_pack_object(eo_system, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	if (kbuf == NULL || kbufsz == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
		*asize = ksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	else if (ksize > kbufsz)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
		ret = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
		*asize = ea_pack_object(eo_system, kbuf, kbufsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	ea_free_object(eo_system, EUP_ALLOC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
 * Start/end the commit transaction.  If commit transaction is currently
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
 * in progress, then all POOL_QUERY ioctls will return pools configuration
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
 * at the beginning of transaction.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
pool_commit(int state)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	ea_object_t *eo_system;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	int ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
	switch (state) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
		 * Beginning commit transation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
		if (pool_buf != NULL)		/* transaction in progress */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
			return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
		eo_system = pool_system_pack();		/* 1. pack system */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		(void) pool_pool_pack(eo_system);	/* 2. pack all pools */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		(void) pool_pset_pack(eo_system);	/* 3. pack all psets */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
		pool_bufsz = ea_pack_object(eo_system, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		pool_buf = kmem_alloc(pool_bufsz, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
		pool_bufsz = ea_pack_object(eo_system, pool_buf, pool_bufsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
		ea_free_object(eo_system, EUP_ALLOC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
		 * Finishing commit transaction.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
		if (pool_buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
			kmem_free(pool_buf, pool_bufsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
			pool_buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
			pool_bufsz = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
 * Check is the specified property is special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
static pool_property_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
pool_property_find(char *name, pool_property_t *list)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	pool_property_t *prop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
	for (prop = list; prop->pp_name != NULL; prop++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
		if (strcmp(prop->pp_name, name) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
			return (prop);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
static pool_property_t pool_prop_sys[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	{ "system.name",		DATA_TYPE_STRING,	PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	{ "system.comment",		DATA_TYPE_STRING,	PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	{ "system.version",		DATA_TYPE_UINT64,	PP_READ },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	{ "system.bind-default",	DATA_TYPE_BYTE,		PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	{ "system.allocate-method",	DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	{ "system.poold.log-level",	DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	{ "system.poold.log-location",	DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
	{ "system.poold.monitor-interval",	DATA_TYPE_UINT64,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
	{ "system.poold.history-file",	DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
	{ "system.poold.objectives",	DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
	{ NULL,				0,			0 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
static pool_property_t pool_prop_pool[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	{ "pool.sys_id",		DATA_TYPE_UINT64,	PP_READ },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	{ "pool.name",			DATA_TYPE_STRING,	PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	{ "pool.default",		DATA_TYPE_BYTE,		PP_READ },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	{ "pool.active",		DATA_TYPE_BYTE,		PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	{ "pool.importance",		DATA_TYPE_INT64,	PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	{ "pool.comment",		DATA_TYPE_STRING,	PP_RDWR },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	{ "pool.scheduler",		DATA_TYPE_STRING,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	    PP_RDWR | PP_OPTIONAL },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	{ NULL,				0,			0 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
 * Common routine to put new property on the specified list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
pool_propput_common(nvlist_t *nvlist, nvpair_t *pair, pool_property_t *props)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	pool_property_t *prop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	if ((prop = pool_property_find(nvpair_name(pair), props)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
		 * No read-only properties or properties with bad types
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
		if (!(prop->pp_perm & PP_WRITE) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
		    prop->pp_type != nvpair_type(pair))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	return (nvlist_add_nvpair(nvlist, pair));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
 * Common routine to remove property from the given list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
pool_proprm_common(nvlist_t *nvlist, char *name, pool_property_t *props)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	pool_property_t *prop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	if ((prop = pool_property_find(name, props)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
		if (!(prop->pp_perm & PP_OPTIONAL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
	return (nvlist_remove_all(nvlist, name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
pool_system_propput(nvpair_t *pair)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
	ret = pool_propput_common(pool_sys_prop, pair, pool_prop_sys);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
		pool_sys_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
pool_system_proprm(char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
	ret = pool_proprm_common(pool_sys_prop, name, pool_prop_sys);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
		pool_sys_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
pool_pool_propput(poolid_t poolid, nvpair_t *pair)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
	if ((pool = pool_lookup_pool_by_id(poolid)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
	ret = pool_propput_common(pool->pool_props, pair, pool_prop_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
		pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
pool_pool_proprm(poolid_t poolid, char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
	pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
	if ((pool = pool_lookup_pool_by_id(poolid)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
		return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
	ret = pool_proprm_common(pool->pool_props, name, pool_prop_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
		pool_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
pool_propput(int class, int subclass, id_t id, nvpair_t *pair)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
	switch (class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
	case PEC_SYSTEM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
		ret = pool_system_propput(pair);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	case PEC_POOL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
		ret = pool_pool_propput((poolid_t)id, pair);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	case PEC_RES_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
		case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
			ret = pool_pset_propput((psetid_t)id, pair);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	case PEC_RES_AGG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
		ret = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	case PEC_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
		case PCEC_CPU:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
			ret = pool_cpu_propput((processorid_t)id, pair);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
pool_proprm(int class, int subclass, id_t id, char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	switch (class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
	case PEC_SYSTEM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
		ret = pool_system_proprm(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
	case PEC_POOL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		ret = pool_pool_proprm((poolid_t)id, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
	case PEC_RES_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
		case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
			ret = pool_pset_proprm((psetid_t)id, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
	case PEC_RES_AGG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
		ret = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	case PEC_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
		case PCEC_CPU:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
			ret = pool_cpu_proprm((processorid_t)id, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
pool_propget(char *name, int class, int subclass, id_t id, nvlist_t **nvlp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	nvlist_t *nvl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
	if (pool_state == POOL_DISABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
		return (ENOTACTIVE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
	(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
	switch (class) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
	case PEC_SYSTEM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
	case PEC_POOL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	case PEC_RES_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		case PREC_PSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
			ret = pool_pset_propget((psetid_t)id, name, nvl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
	case PEC_RES_AGG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
		ret = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
	case PEC_COMP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
		switch (subclass) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
		case PCEC_CPU:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
			ret = pool_cpu_propget((processorid_t)id, name, nvl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
			ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		ret = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
		*nvlp = nvl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
		nvlist_free(nvl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
 * pool_bind_wake and pool_bind_wakeall are helper functions to undo PBWAITs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
 * in case of failure in pool_do_bind().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
pool_bind_wake(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
	ASSERT(p->p_poolflag & PBWAIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
	if (p->p_poolcnt > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
		mutex_enter(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
		pool_barrier_count -= p->p_poolcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
		mutex_exit(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
	p->p_poolflag &= ~PBWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	cv_signal(&p->p_poolcv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
pool_bind_wakeall(proc_t **procs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
	proc_t *p, **pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	for (pp = procs; (p = *pp) != NULL; pp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		pool_bind_wake(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
 * Return the scheduling class for this pool, or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
 * 	POOL_CLASS_UNSET if not set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
 * 	POOL_CLASS_INVAL if set to an invalid class ID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
id_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
pool_get_class(pool_t *pool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	char *name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	id_t cid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	if (nvlist_lookup_string(pool->pool_props, "pool.scheduler",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	    &name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
		if (getcidbyname(name, &cid) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
			return (cid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
			return (POOL_CLASS_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	return (POOL_CLASS_UNSET);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
 * Move process to the new scheduling class.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
pool_change_class(proc_t *p, id_t cid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	void *cldata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	id_t oldcid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	void **bufs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
	void **buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	int nlwp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
	 * Do not move kernel processes (such as zsched).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
	if (p->p_flag & SSYS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	 * This process is in the pool barrier, so it can't possibly be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
	 * adding new threads and we can use p_lwpcnt + p_zombcnt + 1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
	 * (for possible agent LWP which doesn't use pool barrier) as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
	 * our upper bound.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
	nlwp = p->p_lwpcnt + p->p_zombcnt + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
	 * Pre-allocate scheduling class specific buffers before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	 * grabbing p_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	bufs = kmem_zalloc(nlwp * sizeof (void *), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	for (i = 0, buf = bufs; i < nlwp; i++, buf++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
		ret = CL_ALLOC(buf, cid, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
		ASSERT(ret == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	 * Move threads one by one to the new scheduling class.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	 * This never fails because we have all the right
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
	 * privileges here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	ASSERT(p->p_poolflag & PBWAIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	buf = bufs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	t = p->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	ASSERT(t != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
		if (t->t_cid != cid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
			oldcid = t->t_cid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
			cldata = t->t_cldata;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
			ret = CL_ENTERCLASS(t, cid, NULL, NULL, *buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
			ASSERT(ret == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
			CL_EXITCLASS(oldcid, cldata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
			*buf++ = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
	} while ((t = t->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	 * Free unused scheduling class specific buffers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	for (i = 0, buf = bufs; i < nlwp; i++, buf++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
		if (*buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
			CL_FREE(cid, *buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
			*buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	kmem_free(bufs, nlwp * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
 * The meat of the bind operation.  The steps in pool_do_bind are:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
 * 1) Set PBWAIT in the p_poolflag of any process of interest, and add all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
 *    such processes to an array.  For any interesting process that has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
 *    threads inside the pool barrier set, increment a counter by the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
 *    count of such threads.  Once PBWAIT is set on a process, that process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
 *    will not disappear.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
 * 2) Wait for the counter from step 2 to drop to zero.  Any process which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
 *    calls pool_barrier_exit() and notices that PBWAIT has been set on it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
 *    will decrement that counter before going to sleep, and the process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
 *    calling pool_barrier_exit() which does the final decrement will wake us.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
 * 3) For each interesting process, perform a calculation on it to see if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
 *    the bind will actually succeed.  This uses the following three
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
 *    resource-set-specific functions:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
 *    - int set_bind_start(procs, pool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
 *      Determine whether the given array of processes can be bound to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
 *      resource set associated with the given pool.  If it can, take and hold
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
 *      any locks necessary to ensure that the operation will succeed, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
 *      make any necessary reservations in the target resource set.  If it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
 *      can't, return failure with no reservations made and no new locks held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
 *    - void set_bind_abort(procs, pool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
 *      set_bind_start() has completed successfully, but another resource set's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
 *      set_bind_start() has failed, and we haven't begun the bind yet.  Undo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
 *      any reservations made and drop any locks acquired by our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
 *      set_bind_start().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
 *    - void set_bind_finish(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
 *      The bind has completed successfully.  The processes have been released,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
 *      and the reservation acquired in set_bind_start() has been depleted as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
 *      the processes have finished their bindings.  Drop any locks acquired by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
 *      set_bind_start().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
 * 4) If we've decided that we can proceed with the bind, iterate through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
 *    the list of interesting processes, grab the necessary locks (which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
 *    may differ per resource set), perform the bind, and ASSERT that it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
 *    succeeds.  Once a process has been rebound, it can be awakened.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
 * The operations from step 4 must be kept in sync with anything which might
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
 * cause the bind operations (e.g., cpupart_bind_thread()) to fail, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
 * are thus located in the same source files as the associated bind operations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
pool_do_bind(pool_t *pool, idtype_t idtype, id_t id, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	extern uint_t nproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	klwp_t *lwp = ttolwp(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	proc_t **pp, **procs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	proc_t *prstart;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	int procs_count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	kproject_t *kpj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
	procset_t set;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
	int procs_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
	int rv = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	id_t cid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
	if ((cid = pool_get_class(pool)) == POOL_CLASS_INVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	if (idtype == P_ZONEID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
		zone = zone_find_by_id(id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
		if (zone == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
			return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
		if (zone_status_get(zone) > ZONE_IS_RUNNING) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
			zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
			return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
	if (idtype == P_PROJID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		kpj = project_hold_by_id(id, GLOBAL_ZONEID, PROJECT_HOLD_FIND);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
		if (kpj == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
			return (ESRCH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
		mutex_enter(&kpj->kpj_poolbind);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	if (idtype == P_PID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
		 * Fast-path for a single process case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
		procs_size = 2;	/* procs is NULL-terminated */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
		procs = kmem_zalloc(procs_size * sizeof (proc_t *), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
		mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		 * We will need enough slots for proc_t pointers for as many as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
		 * twice the number of currently running processes (assuming
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		 * that each one could be in fork() creating a new child).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
		for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
			procs_size = nproc * 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
			procs = kmem_zalloc(procs_size * sizeof (proc_t *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
			if (nproc * 2 <= procs_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
			 * If nproc has changed, try again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
			kmem_free(procs, procs_size * sizeof (proc_t *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	if (id == P_MYID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		id = getmyid(idtype);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	setprocset(&set, POP_AND, idtype, id, P_ALL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	 * Do a first scan, and select target processes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	if (idtype == P_PID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
		prstart = prfind(id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
		prstart = practive;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	for (p = prstart, pp = procs; p != NULL; p = p->p_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
		mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
		 * Skip processes that don't match our (id, idtype) set or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
		 * on the way of becoming zombies.  Skip kernel processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
		 * from the global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
		if (procinset(p, &set) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		    p->p_poolflag & PEXITED ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
		    ((p->p_flag & SSYS) && INGLOBALZONE(p))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
		if (!INGLOBALZONE(p)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
			switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
			case P_PID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
			case P_TASKID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
				 * Can't bind processes or tasks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
				 * in local zones to pools.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
				mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
				mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
				pool_bind_wakeall(procs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
				rv = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
			case P_PROJID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
				 * Only projects in the global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
				 * zone can be rebound.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
				mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
			case P_POOLID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
				 * When rebinding pools, processes can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
				 * in different zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
		p->p_poolflag |= PBWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		 * If some threads in this process are inside the pool
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
		 * barrier, add them to pool_barrier_count, as we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		 * to wait for all of them to exit the barrier.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
		if (p->p_poolcnt > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
			mutex_enter(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
			pool_barrier_count += p->p_poolcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
			mutex_exit(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		ASSERT(pp < &procs[procs_size]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
		*pp++ = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
		procs_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
		 * We just found our process, so if we're only rebinding a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		 * single process then get out of this loop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		if (idtype == P_PID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	*pp = NULL;	/* cap off the end of the array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
	 * Wait for relevant processes to stop before they try to enter the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	 * barrier or at the exit from the barrier.  Make sure that we do
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	 * not get stopped here while we're holding pool_lock.  If we were
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
	 * requested to stop, or got a signal then return EAGAIN to let the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
	 * library know that it needs to retry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
	mutex_enter(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
	lwp->lwp_nostop++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	while (pool_barrier_count > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
		(void) cv_wait_sig(&pool_barrier_cv, &pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
		if (pool_barrier_count > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
			 * We either got a signal or were requested to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
			 * stop by /proc.  Bail out with EAGAIN.  If we were
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
			 * requested to stop, we'll stop in post_syscall()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
			 * on our way back to userland.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
			mutex_exit(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
			pool_bind_wakeall(procs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
			lwp->lwp_nostop--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
			rv = EAGAIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
	lwp->lwp_nostop--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
	mutex_exit(&pool_barrier_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	if (idtype == P_PID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		goto skip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	 * Do another run, and drop processes that were inside the barrier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	 * in exit(), but when they have dropped to pool_barrier_exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	 * they have become of no interest to us.  Pick up child processes that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
	 * were created by fork() but didn't exist during our first scan.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
	 * Their parents are now stopped at pool_barrier_exit in cfork().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
	for (pp = procs; (p = *pp) != NULL; pp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
		if (p->p_poolflag & PEXITED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
			ASSERT(p->p_lwpcnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
			pool_bind_wake(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
			/* flip w/last non-NULL slot */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
			*pp = procs[procs_count - 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
			procs[procs_count - 1] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
			procs_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
			pp--;			/* try this slot again */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
		 * Look at the child and check if it should be rebound also.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
		 * We're holding pidlock, so it is safe to reference p_child.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
		if ((p = p->p_child) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
		mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
		 * Skip processes in local zones if we're not binding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
		 * zones to pools (P_ZONEID).  Skip kernel processes also.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
		if ((!INGLOBALZONE(p) && idtype != P_ZONEID) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
		    p->p_flag & SSYS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
		 * If the child process has been already created by fork(), has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
		 * not exited, and has not been added to the list already,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
		 * then add it now.  We will hit this process again (since we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
		 * stick it at the end of the procs list) but it will ignored
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
		 * because it will have the PBWAIT flag set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
		if (procinset(p, &set) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
		    !(p->p_poolflag & PEXITED) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
		    !(p->p_poolflag & PBWAIT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
			ASSERT(p->p_child == NULL); /* no child of a child */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
			procs[procs_count] = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
			procs[procs_count + 1] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
			procs_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
			p->p_poolflag |= PBWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
skip:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
	 * If there's no processes to rebind then return ESRCH, unless
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
	 * we're associating a pool with new resource set, destroying it,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	 * or binding a zone to a pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	if (procs_count == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
		if (idtype == P_POOLID || idtype == P_ZONEID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
			rv = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
			rv = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	 * All processes in the array should have PBWAIT set, and none should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	 * be in the critical section.  Even though p_poolflag is protected by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	 * the p_lock, these assertions should be stable across the dropping of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	 * p_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	for (pp = procs; (p = *pp) != NULL; pp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
		ASSERT(p->p_poolflag & PBWAIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
		ASSERT(p->p_poolcnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
		ASSERT(procinset(p, &set));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
	 * Do the check if processor set rebinding is going to succeed or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	if ((flags & POOL_BIND_PSET) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	    (rv = pset_bind_start(procs, pool)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
		pool_bind_wakeall(procs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
	 * At this point, all bind operations should succeed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	for (pp = procs; (p = *pp) != NULL; pp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
		if (flags & POOL_BIND_PSET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
			psetid_t psetid = pool->pool_pset->pset_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
			void *zonebuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
			void *projbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
			 * Pre-allocate one buffer for FSS (per-project
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
			 * buffer for a new pset) in case if this is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
			 * first thread from its current project getting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
			 * bound to this processor set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
			projbuf = fss_allocbuf(FSS_ONE_BUF, FSS_ALLOC_PROJ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
			zonebuf = fss_allocbuf(FSS_ONE_BUF, FSS_ALLOC_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
			pool_pset_bind(p, psetid, projbuf, zonebuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
			 * Free buffers pre-allocated above if it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
			 * wasn't actually used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
			fss_freebuf(projbuf, FSS_ALLOC_PROJ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
			fss_freebuf(zonebuf, FSS_ALLOC_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
		 * Now let's change the scheduling class of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
		 * process if our target pool has it defined.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
		if (cid != POOL_CLASS_UNSET)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
			pool_change_class(p, cid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		 * It is safe to reference p_pool here without holding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		 * p_lock because it cannot change underneath of us.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
		 * We're holding pool_lock here, so nobody else can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		 * moving this process between pools.  If process "p"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
		 * would be exiting, we're guaranteed that it would be blocked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
		 * at pool_barrier_enter() in exit().  Otherwise, it would've
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		 * been skipped by one of our scans of the practive list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
		 * as a process with PEXITED flag set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
		if (p->p_pool != pool) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
			ASSERT(p->p_pool->pool_ref > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
			atomic_add_32(&p->p_pool->pool_ref, -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
			p->p_pool = pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
			atomic_add_32(&p->p_pool->pool_ref, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		 * Okay, we've tortured this guy enough.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
		 * Let this poor process go now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
		pool_bind_wake(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	if (flags & POOL_BIND_PSET)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
		pset_bind_finish();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
out:	switch (idtype) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	case P_PROJID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
		ASSERT(kpj != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
		mutex_exit(&kpj->kpj_poolbind);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
		project_rele(kpj);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	case P_ZONEID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
		if (rv == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
			mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
			zone_pool_set(zone, pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
			mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
		zone->zone_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	kmem_free(procs, procs_size * sizeof (proc_t *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	ASSERT(pool_barrier_count == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	return (rv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
}