usr/src/uts/common/os/zone.c
author Casper H.S. Dik <Casper.Dik@Sun.COM>
Wed, 28 Apr 2010 10:01:37 +0200
changeset 12273 63678502e95e
parent 11861 a63258283f8f
child 12633 9f2cda0ed938
permissions -rw-r--r--
PSARC 2009/377 In-kernel pfexec implementation. PSARC 2009/378 Basic File Privileges PSARC 2010/072 RBAC update: user attrs from profiles 4912090 pfzsh(1) should exist 4912093 pfbash(1) should exist 4912096 pftcsh(1) should exist 6440298 Expand the basic privilege set in order to restrict file access 6859862 Move pfexec into the kernel 6919171 cred_t sidesteps kmem_debug; we need to be able to detect bad hold/free when they occur 6923721 The new SYS_SMB privilege is not backward compatible 6937562 autofs doesn't remove its door when the zone shuts down 6937727 Zones stuck on deathrow; netstack_zone keeps a credential reference to the zone 6940159 Implement PSARC 2010/072
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
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
     5
 * Common Development and Distribution License (the "License").
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
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
 */
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
    23
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
 * Zones
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 *   A zone is a named collection of processes, namespace constraints,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 *   and other system resources which comprise a secure and manageable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 *   application containment facility.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *   Zones (represented by the reference counted zone_t) are tracked in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 *   the kernel in the zonehash.  Elsewhere in the kernel, Zone IDs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 *   (zoneid_t) are used to track zone association.  Zone IDs are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 *   dynamically generated when the zone is created; if a persistent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *   identifier is needed (core files, accounting logs, audit trail,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 *   etc.), the zone name should be used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 *   Global Zone:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *   The global zone (zoneid 0) is automatically associated with all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *   system resources that have not been bound to a user-created zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 *   This means that even systems where zones are not in active use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *   have a global zone, and all processes, mounts, etc. are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *   associated with that zone.  The global zone is generally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 *   unconstrained in terms of privileges and access, though the usual
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 *   credential and privilege based restrictions apply.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 *   Zone States:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 *   The states in which a zone may be in and the transitions are as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 *   follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 *   ZONE_IS_UNINITIALIZED: primordial state for a zone. The partially
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 *   initialized zone is added to the list of active zones on the system but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 *   isn't accessible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 *
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
    61
 *   ZONE_IS_INITIALIZED: Initialization complete except the ZSD callbacks are
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
    62
 *   not yet completed. Not possible to enter the zone, but attributes can
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
    63
 *   be retrieved.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
    64
 *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 *   ZONE_IS_READY: zsched (the kernel dummy process for a zone) is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 *   ready.  The zone is made visible after the ZSD constructor callbacks are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 *   executed.  A zone remains in this state until it transitions into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 *   the ZONE_IS_BOOTING state as a result of a call to zone_boot().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 *   ZONE_IS_BOOTING: in this shortlived-state, zsched attempts to start
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 *   init.  Should that fail, the zone proceeds to the ZONE_IS_SHUTTING_DOWN
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 *   state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 *   ZONE_IS_RUNNING: The zone is open for business: zsched has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 *   successfully started init.   A zone remains in this state until
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 *   zone_shutdown() is called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 *   ZONE_IS_SHUTTING_DOWN: zone_shutdown() has been called, the system is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 *   killing all processes running in the zone. The zone remains
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 *   in this state until there are no more user processes running in the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 *   zone_create(), zone_enter(), and zone_destroy() on this zone will fail.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 *   Since zone_shutdown() is restartable, it may be called successfully
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 *   multiple times for the same zone_t.  Setting of the zone's state to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 *   ZONE_IS_SHUTTING_DOWN is synchronized with mounts, so VOP_MOUNT() may check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 *   the zone's status without worrying about it being a moving target.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 *   ZONE_IS_EMPTY: zone_shutdown() has been called, and there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 *   are no more user processes in the zone.  The zone remains in this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 *   state until there are no more kernel threads associated with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 *   zone.  zone_create(), zone_enter(), and zone_destroy() on this zone will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 *   fail.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 *   ZONE_IS_DOWN: All kernel threads doing work on behalf of the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 *   have exited.  zone_shutdown() returns.  Henceforth it is not possible to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 *   join the zone or create kernel threads therein.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 *   ZONE_IS_DYING: zone_destroy() has been called on the zone; zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 *   remains in this state until zsched exits.  Calls to zone_find_by_*()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 *   return NULL from now on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 *   ZONE_IS_DEAD: zsched has exited (zone_ntasks == 0).  There are no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 *   processes or threads doing work on behalf of the zone.  The zone is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 *   removed from the list of active zones.  zone_destroy() returns, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 *   the zone can be recreated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 *   ZONE_IS_FREE (internal state): zone_ref goes to 0, ZSD destructor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 *   callbacks are executed, and all memory associated with the zone is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 *   freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 *   Threads can wait for the zone to enter a requested state by using
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 *   zone_status_wait() or zone_status_timedwait() with the desired
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 *   state passed in as an argument.  Zone state transitions are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 *   uni-directional; it is not possible to move back to an earlier state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *   Zone-Specific Data:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 *   Subsystems needing to maintain zone-specific data can store that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 *   data using the ZSD mechanism.  This provides a zone-specific data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 *   store, similar to thread-specific data (see pthread_getspecific(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *   or the TSD code in uts/common/disp/thread.c.  Also, ZSD can be used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 *   to register callbacks to be invoked when a zone is created, shut
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 *   down, or destroyed.  This can be used to initialize zone-specific
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 *   data for new zones and to clean up when zones go away.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 *   Data Structures:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 *   The per-zone structure (zone_t) is reference counted, and freed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 *   when all references are released.  zone_hold and zone_rele can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 *   used to adjust the reference count.  In addition, reference counts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 *   associated with the cred_t structure are tracked separately using
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 *   zone_cred_hold and zone_cred_rele.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 *   Pointers to active zone_t's are stored in two hash tables; one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 *   for searching by id, the other for searching by name.  Lookups
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 *   can be performed on either basis, using zone_find_by_id and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 *   zone_find_by_name.  Both return zone_t pointers with the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 *   held, so zone_rele should be called when the pointer is no longer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 *   needed.  Zones can also be searched by path; zone_find_by_path
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 *   returns the zone with which a path name is associated (global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 *   zone if the path is not within some other zone's file system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 *   hierarchy).  This currently requires iterating through each zone,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 *   so it is slower than an id or name search via a hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 *   Locking:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 *   zonehash_lock: This is a top-level global lock used to protect the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 *       zone hash tables and lists.  Zones cannot be created or destroyed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 *       while this lock is held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 *   zone_status_lock: This is a global lock protecting zone state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 *       Zones cannot change state while this lock is held.  It also
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
 *       protects the list of kernel threads associated with a zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
 *   zone_lock: This is a per-zone lock used to protect several fields of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
 *       the zone_t (see <sys/zone.h> for details).  In addition, holding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
 *       this lock means that the zone cannot go away.
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   158
 *   zone_nlwps_lock: This is a per-zone lock used to protect the fields
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   159
 *	 related to the zone.max-lwps rctl.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   160
 *   zone_mem_lock: This is a per-zone lock used to protect the fields
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   161
 *	 related to the zone.max-locked-memory and zone.max-swap rctls.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
 *   zsd_key_lock: This is a global lock protecting the key state for ZSD.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
 *   zone_deathrow_lock: This is a global lock protecting the "deathrow"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 *       list (a list of zones in the ZONE_IS_DEAD state).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
 *   Ordering requirements:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
 *       pool_lock --> cpu_lock --> zonehash_lock --> zone_status_lock -->
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
 *       	zone_lock --> zsd_key_lock --> pidlock --> p_lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
 *
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   170
 *   When taking zone_mem_lock or zone_nlwps_lock, the lock ordering is:
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   171
 *	zonehash_lock --> a_lock --> pidlock --> p_lock --> zone_mem_lock
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   172
 *	zonehash_lock --> a_lock --> pidlock --> p_lock --> zone_mem_lock
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   173
 *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
 *   Blocking memory allocations are permitted while holding any of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
 *   zone locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
 *   System Call Interface:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
 *   The zone subsystem can be managed and queried from user level with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
 *   the following system calls (all subcodes of the primary "zone"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
 *   system call):
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
 *   - zone_create: creates a zone with selected attributes (name,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
   184
 *     root path, privileges, resource controls, ZFS datasets)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 *   - zone_enter: allows the current process to enter a zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
 *   - zone_getattr: reports attributes of a zone
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   187
 *   - zone_setattr: set attributes of a zone
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   188
 *   - zone_boot: set 'init' running for the zone
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
 *   - zone_list: lists all zones active in the system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
 *   - zone_lookup: looks up zone id based on name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
 *   - zone_shutdown: initiates shutdown process (see states above)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
 *   - zone_destroy: completes shutdown process (see states above)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
#include <sys/priv_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
#include <c2/audit.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
#include <sys/file.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
#include <sys/kmem.h>
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   202
#include <sys/kstat.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
#include <sys/mutex.h>
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
   204
#include <sys/note.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
#include <sys/pathname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
#include <sys/project.h>
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   208
#include <sys/sysevent.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
#include <sys/task.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
#include <sys/utsname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
#include <sys/vnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
#include <sys/vfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
#include <sys/systeminfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
#include <sys/cred_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
#include <sys/contract_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
#include <sys/contract/process_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
#include <sys/class.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
#include <sys/pool.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
#include <sys/pool_pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
#include <sys/pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
#include <sys/callb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
#include <sys/vmparam.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
#include <sys/corectl.h>
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
   228
#include <sys/ipc_impl.h>
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
   229
#include <sys/klpd.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
#include <sys/door.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
#include <sys/cpuvar.h>
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   233
#include <sys/sdt.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
#include <sys/uadmin.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
#include <sys/session.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
#include <sys/modhash.h>
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   239
#include <sys/sunddi.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
#include <sys/nvpair.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
#include <sys/rctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
#include <sys/fss.h>
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
   243
#include <sys/brand.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
#include <sys/zone.h>
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
   245
#include <net/if.h>
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
   246
#include <sys/cpucaps.h>
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   247
#include <vm/seg.h>
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   248
#include <sys/mac.h>
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   249
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   250
/* List of data link IDs which are accessible from the zone */
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   251
typedef struct zone_dl {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   252
	datalink_id_t	zdl_id;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   253
	list_node_t	zdl_linkage;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   254
} zone_dl_t;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   255
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
 * cv used to signal that all references to the zone have been released.  This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
 * needs to be global since there may be multiple waiters, and the first to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
 * wake up will free the zone_t, hence we cannot use zone->zone_cv.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
static kcondvar_t zone_destroy_cv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
 * Lock used to serialize access to zone_cv.  This could have been per-zone,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
 * but then we'd need another lock for zone_destroy_cv, and why bother?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
static kmutex_t zone_status_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
 * ZSD-related global variables.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
static kmutex_t zsd_key_lock;	/* protects the following two */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
 * The next caller of zone_key_create() will be assigned a key of ++zsd_keyval.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
static zone_key_t zsd_keyval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
 * Global list of registered keys.  We use this when a new zone is created.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
static list_t zsd_registered_keys;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
int zone_hash_size = 256;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
   282
static mod_hash_t *zonehashbyname, *zonehashbyid, *zonehashbylabel;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
static kmutex_t zonehash_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
static uint_t zonecount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
static id_space_t *zoneid_space;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
 * The global zone (aka zone0) is the all-seeing, all-knowing zone in which the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
 * kernel proper runs, and which manages all other zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
 * Although not declared as static, the variable "zone0" should not be used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
 * except for by code that needs to reference the global zone early on in boot,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
 * before it is fully initialized.  All other consumers should use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
 * 'global_zone'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
zone_t zone0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
zone_t *global_zone = NULL;	/* Set when the global zone is initialized */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
 * List of active zones, protected by zonehash_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
static list_t zone_active;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
 * List of destroyed zones that still have outstanding cred references.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
 * Used for debugging.  Uses a separate lock to avoid lock ordering
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 * problems in zone_free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
static list_t zone_deathrow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
static kmutex_t zone_deathrow_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
/* number of zones is limited by virtual interface limit in IP */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
uint_t maxzones = 8192;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   315
/* Event channel to sent zone state change notifications */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   316
evchan_t *zone_event_chan;
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   317
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   318
/*
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   319
 * This table holds the mapping from kernel zone states to
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   320
 * states visible in the state notification API.
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   321
 * The idea is that we only expose "obvious" states and
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   322
 * do not expose states which are just implementation details.
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   323
 */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   324
const char  *zone_status_table[] = {
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   325
	ZONE_EVENT_UNINITIALIZED,	/* uninitialized */
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   326
	ZONE_EVENT_INITIALIZED,		/* initialized */
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   327
	ZONE_EVENT_READY,		/* ready */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   328
	ZONE_EVENT_READY,		/* booting */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   329
	ZONE_EVENT_RUNNING,		/* running */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   330
	ZONE_EVENT_SHUTTING_DOWN,	/* shutting_down */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   331
	ZONE_EVENT_SHUTTING_DOWN,	/* empty */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   332
	ZONE_EVENT_SHUTTING_DOWN,	/* down */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   333
	ZONE_EVENT_SHUTTING_DOWN,	/* dying */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   334
	ZONE_EVENT_UNINITIALIZED,	/* dead */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   335
};
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
   336
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
 * This isn't static so lint doesn't complain.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
rctl_hndl_t rc_zone_cpu_shares;
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
   341
rctl_hndl_t rc_zone_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
   342
rctl_hndl_t rc_zone_max_swap;
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
   343
rctl_hndl_t rc_zone_cpu_cap;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
rctl_hndl_t rc_zone_nlwps;
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
   345
rctl_hndl_t rc_zone_shmmax;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
   346
rctl_hndl_t rc_zone_shmmni;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
   347
rctl_hndl_t rc_zone_semmni;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
   348
rctl_hndl_t rc_zone_msgmni;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
 * Synchronization primitives used to synchronize between mounts and zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
 * creation/destruction.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
static int mounts_in_progress;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
static kcondvar_t mount_cv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
static kmutex_t mount_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   357
const char * const zone_default_initname = "/sbin/init";
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
   358
static char * const zone_prefix = "/zone/";
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
static int zone_shutdown(zoneid_t zoneid);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   360
static int zone_add_datalink(zoneid_t, datalink_id_t);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   361
static int zone_remove_datalink(zoneid_t, datalink_id_t);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
   362
static int zone_list_datalink(zoneid_t, int *, datalink_id_t *);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   364
typedef boolean_t zsd_applyfn_t(kmutex_t *, boolean_t, zone_t *, zone_key_t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   365
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   366
static void zsd_apply_all_zones(zsd_applyfn_t *, zone_key_t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   367
static void zsd_apply_all_keys(zsd_applyfn_t *, zone_t *);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   368
static boolean_t zsd_apply_create(kmutex_t *, boolean_t, zone_t *, zone_key_t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   369
static boolean_t zsd_apply_shutdown(kmutex_t *, boolean_t, zone_t *,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   370
    zone_key_t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   371
static boolean_t zsd_apply_destroy(kmutex_t *, boolean_t, zone_t *, zone_key_t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   372
static boolean_t zsd_wait_for_creator(zone_t *, struct zsd_entry *,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   373
    kmutex_t *);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   374
static boolean_t zsd_wait_for_inprogress(zone_t *, struct zsd_entry *,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   375
    kmutex_t *);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   376
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
/*
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   378
 * Bump this number when you alter the zone syscall interfaces; this is
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   379
 * because we need to have support for previous API versions in libc
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   380
 * to support patching; libc calls into the kernel to determine this number.
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   381
 *
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   382
 * Version 1 of the API is the version originally shipped with Solaris 10
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   383
 * Version 2 alters the zone_create system call in order to support more
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   384
 *     arguments by moving the args into a structure; and to do better
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   385
 *     error reporting when zone_create() fails.
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   386
 * Version 3 alters the zone_create system call in order to support the
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   387
 *     import of ZFS datasets to zones.
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
   388
 * Version 4 alters the zone_create system call in order to support
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
   389
 *     Trusted Extensions.
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   390
 * Version 5 alters the zone_boot system call, and converts its old
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
   391
 *     bootargs parameter to be set by the zone_setattr API instead.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
   392
 * Version 6 adds the flag argument to zone_create.
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   393
 */
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
   394
static const int ZONE_SYSCALL_API_VERSION = 6;
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   395
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
   396
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
 * Certain filesystems (such as NFS and autofs) need to know which zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
 * the mount is being placed in.  Because of this, we need to be able to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
 * ensure that a zone isn't in the process of being created such that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
 * nfs_mount() thinks it is in the global zone, while by the time it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
 * gets added the list of mounted zones, it ends up on zoneA's mount
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
 * list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
 * The following functions: block_mounts()/resume_mounts() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
 * mount_in_progress()/mount_completed() are used by zones and the VFS
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
 * layer (respectively) to synchronize zone creation and new mounts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
 * The semantics are like a reader-reader lock such that there may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
 * either be multiple mounts (or zone creations, if that weren't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
 * serialized by zonehash_lock) in progress at the same time, but not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
 * both.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
 * We use cv's so the user can ctrl-C out of the operation if it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 * taking too long.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
 * The semantics are such that there is unfair bias towards the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
 * "current" operation.  This means that zone creations may starve if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 * there is a rapid succession of new mounts coming in to the system, or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 * there is a remote possibility that zones will be created at such a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 * rate that new mounts will not be able to proceed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
 * Prevent new mounts from progressing to the point of calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
 * VFS_MOUNT().  If there are already mounts in this "region", wait for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
 * them to complete.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
block_mounts(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	int retval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	 * Since it may block for a long time, block_mounts() shouldn't be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	 * called with zonehash_lock held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	ASSERT(MUTEX_NOT_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	mutex_enter(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	while (mounts_in_progress > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
		if (cv_wait_sig(&mount_cv, &mount_lock) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
			goto signaled;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	 * A negative value of mounts_in_progress indicates that mounts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	 * have been blocked by (-mounts_in_progress) different callers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	mounts_in_progress--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	retval = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
signaled:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	mutex_exit(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	return (retval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
 * The VFS layer may progress with new mounts as far as we're concerned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
 * Allow them to progress if we were the last obstacle.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
resume_mounts(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	mutex_enter(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	if (++mounts_in_progress == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		cv_broadcast(&mount_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	mutex_exit(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
 * The VFS layer is busy with a mount; zones should wait until all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
 * mounts are completed to progress.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
mount_in_progress(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	mutex_enter(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	while (mounts_in_progress < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
		cv_wait(&mount_cv, &mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	mounts_in_progress++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	mutex_exit(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
 * VFS is done with one mount; wake up any waiting block_mounts()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
 * callers if this is the last mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
mount_completed(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	mutex_enter(&mount_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	if (--mounts_in_progress == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		cv_broadcast(&mount_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	mutex_exit(&mount_lock);
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
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
 * ZSD routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
 * Zone Specific Data (ZSD) is modeled after Thread Specific Data as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
 * defined by the pthread_key_create() and related interfaces.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
 * Kernel subsystems may register one or more data items and/or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
 * callbacks to be executed when a zone is created, shutdown, or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
 * destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
 * Unlike the thread counterpart, destructor callbacks will be executed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
 * even if the data pointer is NULL and/or there are no constructor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
 * callbacks, so it is the responsibility of such callbacks to check for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
 * NULL data values if necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
 * The locking strategy and overall picture is as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
 * When someone calls zone_key_create(), a template ZSD entry is added to the
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   511
 * global list "zsd_registered_keys", protected by zsd_key_lock.  While
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   512
 * holding that lock all the existing zones are marked as
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   513
 * ZSD_CREATE_NEEDED and a copy of the ZSD entry added to the per-zone
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   514
 * zone_zsd list (protected by zone_lock). The global list is updated first
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   515
 * (under zone_key_lock) to make sure that newly created zones use the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   516
 * most recent list of keys. Then under zonehash_lock we walk the zones
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   517
 * and mark them.  Similar locking is used in zone_key_delete().
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
 *
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   519
 * The actual create, shutdown, and destroy callbacks are done without
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   520
 * holding any lock. And zsd_flags are used to ensure that the operations
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   521
 * completed so that when zone_key_create (and zone_create) is done, as well as
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   522
 * zone_key_delete (and zone_destroy) is done, all the necessary callbacks
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   523
 * are completed.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
 * When new zones are created constructor callbacks for all registered ZSD
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   526
 * entries will be called. That also uses the above two phases of marking
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   527
 * what needs to be done, and then running the callbacks without holding
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   528
 * any locks.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
 * The framework does not provide any locking around zone_getspecific() and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
 * zone_setspecific() apart from that needed for internal consistency, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
 * callers interested in atomic "test-and-set" semantics will need to provide
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
 * their own locking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
 * Helper function to find the zsd_entry associated with the key in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
 * given list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
static struct zsd_entry *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
zsd_find(list_t *l, zone_key_t key)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
	struct zsd_entry *zsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
	for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		if (zsd->zsd_key == key) {
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   547
			return (zsd);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   548
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   549
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   550
	return (NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   551
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   552
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   553
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   554
 * Helper function to find the zsd_entry associated with the key in the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   555
 * given list. Move it to the front of the list.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   556
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   557
static struct zsd_entry *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   558
zsd_find_mru(list_t *l, zone_key_t key)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   559
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   560
	struct zsd_entry *zsd;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   561
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   562
	for (zsd = list_head(l); zsd != NULL; zsd = list_next(l, zsd)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   563
		if (zsd->zsd_key == key) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
			 * Move to head of list to keep list in MRU order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
			if (zsd != list_head(l)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
				list_remove(l, zsd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
				list_insert_head(l, zsd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			return (zsd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   577
void
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   578
zone_key_create(zone_key_t *keyp, void *(*create)(zoneid_t),
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   579
    void (*shutdown)(zoneid_t, void *), void (*destroy)(zoneid_t, void *))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   580
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   581
	struct zsd_entry *zsdp;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   582
	struct zsd_entry *t;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   583
	struct zone *zone;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   584
	zone_key_t  key;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   585
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   586
	zsdp = kmem_zalloc(sizeof (*zsdp), KM_SLEEP);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   587
	zsdp->zsd_data = NULL;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   588
	zsdp->zsd_create = create;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   589
	zsdp->zsd_shutdown = shutdown;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   590
	zsdp->zsd_destroy = destroy;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   591
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   592
	/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   593
	 * Insert in global list of callbacks. Makes future zone creations
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   594
	 * see it.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   595
	 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   596
	mutex_enter(&zsd_key_lock);
10865
ff55368ffe7b 6747527 BAD TRAP: type=31 when accounting is turned ON for zones
Pramod Batni <Pramod.Batni@Sun.COM>
parents: 10616
diff changeset
   597
	key = zsdp->zsd_key = ++zsd_keyval;
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   598
	ASSERT(zsd_keyval != 0);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   599
	list_insert_tail(&zsd_registered_keys, zsdp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   600
	mutex_exit(&zsd_key_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   601
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   602
	/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   603
	 * Insert for all existing zones and mark them as needing
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   604
	 * a create callback.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   605
	 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   606
	mutex_enter(&zonehash_lock);	/* stop the world */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   607
	for (zone = list_head(&zone_active); zone != NULL;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   608
	    zone = list_next(&zone_active, zone)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   609
		zone_status_t status;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   610
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   611
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   612
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   613
		/* Skip zones that are on the way down or not yet up */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   614
		status = zone_status_get(zone);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   615
		if (status >= ZONE_IS_DOWN ||
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   616
		    status == ZONE_IS_UNINITIALIZED) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   617
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   618
			continue;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   619
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   620
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   621
		t = zsd_find_mru(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   622
		if (t != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   623
			/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   624
			 * A zsd_configure already inserted it after
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   625
			 * we dropped zsd_key_lock above.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   626
			 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   627
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   628
			continue;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   629
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   630
		t = kmem_zalloc(sizeof (*t), KM_SLEEP);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   631
		t->zsd_key = key;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   632
		t->zsd_create = create;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   633
		t->zsd_shutdown = shutdown;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   634
		t->zsd_destroy = destroy;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   635
		if (create != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   636
			t->zsd_flags = ZSD_CREATE_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   637
			DTRACE_PROBE2(zsd__create__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   638
			    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   639
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   640
		list_insert_tail(&zone->zone_zsd, t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   641
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   642
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   643
	mutex_exit(&zonehash_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   644
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   645
	if (create != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   646
		/* Now call the create callback for this key */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   647
		zsd_apply_all_zones(zsd_apply_create, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   648
	}
10865
ff55368ffe7b 6747527 BAD TRAP: type=31 when accounting is turned ON for zones
Pramod Batni <Pramod.Batni@Sun.COM>
parents: 10616
diff changeset
   649
	/*
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
   650
	 * It is safe for consumers to use the key now, make it
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
   651
	 * globally visible. Specifically zone_getspecific() will
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
   652
	 * always successfully return the zone specific data associated
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
   653
	 * with the key.
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
   654
	 */
10865
ff55368ffe7b 6747527 BAD TRAP: type=31 when accounting is turned ON for zones
Pramod Batni <Pramod.Batni@Sun.COM>
parents: 10616
diff changeset
   655
	*keyp = key;
ff55368ffe7b 6747527 BAD TRAP: type=31 when accounting is turned ON for zones
Pramod Batni <Pramod.Batni@Sun.COM>
parents: 10616
diff changeset
   656
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   657
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   658
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
 * Function called when a module is being unloaded, or otherwise wishes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
 * to unregister its ZSD key and callbacks.
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   662
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   663
 * Remove from the global list and determine the functions that need to
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   664
 * be called under a global lock. Then call the functions without
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   665
 * holding any locks. Finally free up the zone_zsd entries. (The apply
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   666
 * functions need to access the zone_zsd entries to find zsd_data etc.)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
zone_key_delete(zone_key_t key)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	struct zsd_entry *zsdp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	mutex_enter(&zsd_key_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   675
	zsdp = zsd_find_mru(&zsd_registered_keys, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   676
	if (zsdp == NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   677
		mutex_exit(&zsd_key_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   678
		return (-1);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   679
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	list_remove(&zsd_registered_keys, zsdp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	mutex_exit(&zsd_key_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   683
	mutex_enter(&zonehash_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	for (zone = list_head(&zone_active); zone != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	    zone = list_next(&zone_active, zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
		struct zsd_entry *del;
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   687
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   688
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   689
		del = zsd_find_mru(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   690
		if (del == NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   691
			/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   692
			 * Somebody else got here first e.g the zone going
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   693
			 * away.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   694
			 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   695
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   696
			continue;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   697
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   698
		ASSERT(del->zsd_shutdown == zsdp->zsd_shutdown);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   699
		ASSERT(del->zsd_destroy == zsdp->zsd_destroy);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   700
		if (del->zsd_shutdown != NULL &&
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   701
		    (del->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   702
			del->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   703
			DTRACE_PROBE2(zsd__shutdown__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   704
			    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   705
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   706
		if (del->zsd_destroy != NULL &&
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   707
		    (del->zsd_flags & ZSD_DESTROY_ALL) == 0) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   708
			del->zsd_flags |= ZSD_DESTROY_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   709
			DTRACE_PROBE2(zsd__destroy__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   710
			    zone_t *, zone, zone_key_t, key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	kmem_free(zsdp, sizeof (*zsdp));
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   716
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   717
	/* Now call the shutdown and destroy callback for this key */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   718
	zsd_apply_all_zones(zsd_apply_shutdown, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   719
	zsd_apply_all_zones(zsd_apply_destroy, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   720
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   721
	/* Now we can free up the zsdp structures in each zone */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   722
	mutex_enter(&zonehash_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	for (zone = list_head(&zone_active); zone != NULL;
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   724
	    zone = list_next(&zone_active, zone)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   725
		struct zsd_entry *del;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   726
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   727
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   728
		del = zsd_find(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   729
		if (del != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   730
			list_remove(&zone->zone_zsd, del);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   731
			ASSERT(!(del->zsd_flags & ZSD_ALL_INPROGRESS));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   732
			kmem_free(del, sizeof (*del));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   733
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
		mutex_exit(&zone->zone_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   735
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	mutex_exit(&zonehash_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   737
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   738
	return (0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
 * ZSD counterpart of pthread_setspecific().
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   743
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   744
 * Since all zsd callbacks, including those with no create function,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   745
 * have an entry in zone_zsd, if the key is registered it is part of
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   746
 * the zone_zsd list.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   747
 * Return an error if the key wasn't registerd.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
zone_setspecific(zone_key_t key, zone_t *zone, const void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	struct zsd_entry *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	mutex_enter(&zone->zone_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   755
	t = zsd_find_mru(&zone->zone_zsd, key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	if (t != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		 * Replace old value with new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
		t->zsd_data = (void *)data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	mutex_exit(&zone->zone_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   765
	return (-1);
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
 * ZSD counterpart of pthread_getspecific().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
zone_getspecific(zone_key_t key, zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	struct zsd_entry *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	void *data;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	mutex_enter(&zone->zone_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   778
	t = zsd_find_mru(&zone->zone_zsd, key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	data = (t == NULL ? NULL : t->zsd_data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	return (data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
 * Function used to initialize a zone's list of ZSD callbacks and data
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
 * when the zone is being created.  The callbacks are initialized from
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   787
 * the template list (zsd_registered_keys). The constructor callback is
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   788
 * executed later (once the zone exists and with locks dropped).
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
zone_zsd_configure(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	struct zsd_entry *zsdp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	struct zsd_entry *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	ASSERT(list_head(&zone->zone_zsd) == NULL);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   798
	mutex_enter(&zone->zone_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
	mutex_enter(&zsd_key_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
	for (zsdp = list_head(&zsd_registered_keys); zsdp != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
	    zsdp = list_next(&zsd_registered_keys, zsdp)) {
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   802
		/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   803
		 * Since this zone is ZONE_IS_UNCONFIGURED, zone_key_create
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   804
		 * should not have added anything to it.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   805
		 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   806
		ASSERT(zsd_find(&zone->zone_zsd, zsdp->zsd_key) == NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   807
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   808
		t = kmem_zalloc(sizeof (*t), KM_SLEEP);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   809
		t->zsd_key = zsdp->zsd_key;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   810
		t->zsd_create = zsdp->zsd_create;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   811
		t->zsd_shutdown = zsdp->zsd_shutdown;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   812
		t->zsd_destroy = zsdp->zsd_destroy;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		if (zsdp->zsd_create != NULL) {
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   814
			t->zsd_flags = ZSD_CREATE_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   815
			DTRACE_PROBE2(zsd__create__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   816
			    zone_t *, zone, zone_key_t, zsdp->zsd_key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		}
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   818
		list_insert_tail(&zone->zone_zsd, t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	mutex_exit(&zsd_key_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   821
	mutex_exit(&zone->zone_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
enum zsd_callback_type { ZSD_CREATE, ZSD_SHUTDOWN, ZSD_DESTROY };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
 * Helper function to execute shutdown or destructor callbacks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
zone_zsd_callbacks(zone_t *zone, enum zsd_callback_type ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	struct zsd_entry *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	ASSERT(ct == ZSD_SHUTDOWN || ct == ZSD_DESTROY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	ASSERT(ct != ZSD_SHUTDOWN || zone_status_get(zone) >= ZONE_IS_EMPTY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	ASSERT(ct != ZSD_DESTROY || zone_status_get(zone) >= ZONE_IS_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   838
	/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   839
	 * Run the callback solely based on what is registered for the zone
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   840
	 * in zone_zsd. The global list can change independently of this
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   841
	 * as keys are registered and unregistered and we don't register new
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   842
	 * callbacks for a zone that is in the process of going away.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   843
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	mutex_enter(&zone->zone_lock);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   845
	for (t = list_head(&zone->zone_zsd); t != NULL;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   846
	    t = list_next(&zone->zone_zsd, t)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   847
		zone_key_t key = t->zsd_key;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
		/* Skip if no callbacks registered */
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   850
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   851
		if (ct == ZSD_SHUTDOWN) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   852
			if (t->zsd_shutdown != NULL &&
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   853
			    (t->zsd_flags & ZSD_SHUTDOWN_ALL) == 0) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   854
				t->zsd_flags |= ZSD_SHUTDOWN_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   855
				DTRACE_PROBE2(zsd__shutdown__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   856
				    zone_t *, zone, zone_key_t, key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
		} else {
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   859
			if (t->zsd_destroy != NULL &&
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   860
			    (t->zsd_flags & ZSD_DESTROY_ALL) == 0) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   861
				t->zsd_flags |= ZSD_DESTROY_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   862
				DTRACE_PROBE2(zsd__destroy__needed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   863
				    zone_t *, zone, zone_key_t, key);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	}
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   867
	mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   868
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   869
	/* Now call the shutdown and destroy callback for this key */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   870
	zsd_apply_all_keys(zsd_apply_shutdown, zone);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   871
	zsd_apply_all_keys(zsd_apply_destroy, zone);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   872
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
 * Called when the zone is going away; free ZSD-related memory, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
 * destroy the zone_zsd list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
zone_free_zsd(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	struct zsd_entry *t, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	 * Free all the zsd_entry's we had on this zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	 */
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   887
	mutex_enter(&zone->zone_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
	for (t = list_head(&zone->zone_zsd); t != NULL; t = next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
		next = list_next(&zone->zone_zsd, t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		list_remove(&zone->zone_zsd, t);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   891
		ASSERT(!(t->zsd_flags & ZSD_ALL_INPROGRESS));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		kmem_free(t, sizeof (*t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	list_destroy(&zone->zone_zsd);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   895
	mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   896
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   897
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   898
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   899
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   900
 * Apply a function to all zones for particular key value.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   901
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   902
 * The applyfn has to drop zonehash_lock if it does some work, and
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   903
 * then reacquire it before it returns.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   904
 * When the lock is dropped we don't follow list_next even
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   905
 * if it is possible to do so without any hazards. This is
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   906
 * because we want the design to allow for the list of zones
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   907
 * to change in any arbitrary way during the time the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   908
 * lock was dropped.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   909
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   910
 * It is safe to restart the loop at list_head since the applyfn
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   911
 * changes the zsd_flags as it does work, so a subsequent
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   912
 * pass through will have no effect in applyfn, hence the loop will terminate
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   913
 * in at worst O(N^2).
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   914
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   915
static void
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   916
zsd_apply_all_zones(zsd_applyfn_t *applyfn, zone_key_t key)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   917
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   918
	zone_t *zone;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   919
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   920
	mutex_enter(&zonehash_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   921
	zone = list_head(&zone_active);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   922
	while (zone != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   923
		if ((applyfn)(&zonehash_lock, B_FALSE, zone, key)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   924
			/* Lock dropped - restart at head */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   925
			zone = list_head(&zone_active);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   926
		} else {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   927
			zone = list_next(&zone_active, zone);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   928
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   929
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   930
	mutex_exit(&zonehash_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   931
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   932
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   933
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   934
 * Apply a function to all keys for a particular zone.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   935
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   936
 * The applyfn has to drop zonehash_lock if it does some work, and
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   937
 * then reacquire it before it returns.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   938
 * When the lock is dropped we don't follow list_next even
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   939
 * if it is possible to do so without any hazards. This is
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   940
 * because we want the design to allow for the list of zsd callbacks
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   941
 * to change in any arbitrary way during the time the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   942
 * lock was dropped.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   943
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   944
 * It is safe to restart the loop at list_head since the applyfn
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   945
 * changes the zsd_flags as it does work, so a subsequent
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   946
 * pass through will have no effect in applyfn, hence the loop will terminate
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   947
 * in at worst O(N^2).
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   948
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   949
static void
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   950
zsd_apply_all_keys(zsd_applyfn_t *applyfn, zone_t *zone)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   951
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   952
	struct zsd_entry *t;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   953
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   954
	mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   955
	t = list_head(&zone->zone_zsd);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   956
	while (t != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   957
		if ((applyfn)(NULL, B_TRUE, zone, t->zsd_key)) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   958
			/* Lock dropped - restart at head */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   959
			t = list_head(&zone->zone_zsd);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   960
		} else {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   961
			t = list_next(&zone->zone_zsd, t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   962
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   963
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   964
	mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   965
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   966
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   967
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   968
 * Call the create function for the zone and key if CREATE_NEEDED
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   969
 * is set.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   970
 * If some other thread gets here first and sets CREATE_INPROGRESS, then
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   971
 * we wait for that thread to complete so that we can ensure that
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   972
 * all the callbacks are done when we've looped over all zones/keys.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   973
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   974
 * When we call the create function, we drop the global held by the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   975
 * caller, and return true to tell the caller it needs to re-evalute the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   976
 * state.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   977
 * If the caller holds zone_lock then zone_lock_held is set, and zone_lock
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   978
 * remains held on exit.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   979
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   980
static boolean_t
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   981
zsd_apply_create(kmutex_t *lockp, boolean_t zone_lock_held,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   982
    zone_t *zone, zone_key_t key)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   983
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   984
	void *result;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   985
	struct zsd_entry *t;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   986
	boolean_t dropped;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   987
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   988
	if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   989
		ASSERT(MUTEX_HELD(lockp));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   990
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   991
	if (zone_lock_held) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   992
		ASSERT(MUTEX_HELD(&zone->zone_lock));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   993
	} else {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   994
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   995
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   996
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   997
	t = zsd_find(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   998
	if (t == NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
   999
		/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1000
		 * Somebody else got here first e.g the zone going
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1001
		 * away.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1002
		 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1003
		if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1004
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1005
		return (B_FALSE);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1006
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1007
	dropped = B_FALSE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1008
	if (zsd_wait_for_inprogress(zone, t, lockp))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1009
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1010
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1011
	if (t->zsd_flags & ZSD_CREATE_NEEDED) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1012
		t->zsd_flags &= ~ZSD_CREATE_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1013
		t->zsd_flags |= ZSD_CREATE_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1014
		DTRACE_PROBE2(zsd__create__inprogress,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1015
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1016
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1017
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1018
			mutex_exit(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1019
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1020
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1021
		ASSERT(t->zsd_create != NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1022
		DTRACE_PROBE2(zsd__create__start,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1023
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1024
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1025
		result = (*t->zsd_create)(zone->zone_id);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1026
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1027
		DTRACE_PROBE2(zsd__create__end,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1028
		    zone_t *, zone, voidn *, result);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1029
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1030
		ASSERT(result != NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1031
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1032
			mutex_enter(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1033
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1034
		t->zsd_data = result;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1035
		t->zsd_flags &= ~ZSD_CREATE_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1036
		t->zsd_flags |= ZSD_CREATE_COMPLETED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1037
		cv_broadcast(&t->zsd_cv);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1038
		DTRACE_PROBE2(zsd__create__completed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1039
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1040
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1041
	if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1042
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1043
	return (dropped);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1044
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1045
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1046
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1047
 * Call the shutdown function for the zone and key if SHUTDOWN_NEEDED
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1048
 * is set.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1049
 * If some other thread gets here first and sets *_INPROGRESS, then
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1050
 * we wait for that thread to complete so that we can ensure that
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1051
 * all the callbacks are done when we've looped over all zones/keys.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1052
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1053
 * When we call the shutdown function, we drop the global held by the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1054
 * caller, and return true to tell the caller it needs to re-evalute the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1055
 * state.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1056
 * If the caller holds zone_lock then zone_lock_held is set, and zone_lock
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1057
 * remains held on exit.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1058
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1059
static boolean_t
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1060
zsd_apply_shutdown(kmutex_t *lockp, boolean_t zone_lock_held,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1061
    zone_t *zone, zone_key_t key)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1062
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1063
	struct zsd_entry *t;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1064
	void *data;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1065
	boolean_t dropped;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1066
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1067
	if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1068
		ASSERT(MUTEX_HELD(lockp));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1069
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1070
	if (zone_lock_held) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1071
		ASSERT(MUTEX_HELD(&zone->zone_lock));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1072
	} else {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1073
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1074
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1075
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1076
	t = zsd_find(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1077
	if (t == NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1078
		/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1079
		 * Somebody else got here first e.g the zone going
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1080
		 * away.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1081
		 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1082
		if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1083
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1084
		return (B_FALSE);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1085
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1086
	dropped = B_FALSE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1087
	if (zsd_wait_for_creator(zone, t, lockp))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1088
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1089
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1090
	if (zsd_wait_for_inprogress(zone, t, lockp))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1091
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1092
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1093
	if (t->zsd_flags & ZSD_SHUTDOWN_NEEDED) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1094
		t->zsd_flags &= ~ZSD_SHUTDOWN_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1095
		t->zsd_flags |= ZSD_SHUTDOWN_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1096
		DTRACE_PROBE2(zsd__shutdown__inprogress,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1097
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1098
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1099
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1100
			mutex_exit(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1101
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1102
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1103
		ASSERT(t->zsd_shutdown != NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1104
		data = t->zsd_data;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1105
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1106
		DTRACE_PROBE2(zsd__shutdown__start,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1107
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1108
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1109
		(t->zsd_shutdown)(zone->zone_id, data);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1110
		DTRACE_PROBE2(zsd__shutdown__end,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1111
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1112
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1113
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1114
			mutex_enter(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1115
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1116
		t->zsd_flags &= ~ZSD_SHUTDOWN_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1117
		t->zsd_flags |= ZSD_SHUTDOWN_COMPLETED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1118
		cv_broadcast(&t->zsd_cv);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1119
		DTRACE_PROBE2(zsd__shutdown__completed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1120
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1121
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1122
	if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1123
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1124
	return (dropped);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1125
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1126
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1127
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1128
 * Call the destroy function for the zone and key if DESTROY_NEEDED
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1129
 * is set.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1130
 * If some other thread gets here first and sets *_INPROGRESS, then
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1131
 * we wait for that thread to complete so that we can ensure that
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1132
 * all the callbacks are done when we've looped over all zones/keys.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1133
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1134
 * When we call the destroy function, we drop the global held by the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1135
 * caller, and return true to tell the caller it needs to re-evalute the
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1136
 * state.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1137
 * If the caller holds zone_lock then zone_lock_held is set, and zone_lock
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1138
 * remains held on exit.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1139
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1140
static boolean_t
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1141
zsd_apply_destroy(kmutex_t *lockp, boolean_t zone_lock_held,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1142
    zone_t *zone, zone_key_t key)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1143
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1144
	struct zsd_entry *t;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1145
	void *data;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1146
	boolean_t dropped;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1147
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1148
	if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1149
		ASSERT(MUTEX_HELD(lockp));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1150
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1151
	if (zone_lock_held) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1152
		ASSERT(MUTEX_HELD(&zone->zone_lock));
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1153
	} else {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1154
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1155
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1156
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1157
	t = zsd_find(&zone->zone_zsd, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1158
	if (t == NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1159
		/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1160
		 * Somebody else got here first e.g the zone going
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1161
		 * away.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1162
		 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1163
		if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1164
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1165
		return (B_FALSE);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1166
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1167
	dropped = B_FALSE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1168
	if (zsd_wait_for_creator(zone, t, lockp))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1169
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1170
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1171
	if (zsd_wait_for_inprogress(zone, t, lockp))
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1172
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1173
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1174
	if (t->zsd_flags & ZSD_DESTROY_NEEDED) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1175
		t->zsd_flags &= ~ZSD_DESTROY_NEEDED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1176
		t->zsd_flags |= ZSD_DESTROY_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1177
		DTRACE_PROBE2(zsd__destroy__inprogress,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1178
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1179
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1180
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1181
			mutex_exit(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1182
		dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1183
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1184
		ASSERT(t->zsd_destroy != NULL);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1185
		data = t->zsd_data;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1186
		DTRACE_PROBE2(zsd__destroy__start,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1187
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1188
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1189
		(t->zsd_destroy)(zone->zone_id, data);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1190
		DTRACE_PROBE2(zsd__destroy__end,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1191
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1192
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1193
		if (lockp != NULL)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1194
			mutex_enter(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1195
		mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1196
		t->zsd_data = NULL;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1197
		t->zsd_flags &= ~ZSD_DESTROY_INPROGRESS;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1198
		t->zsd_flags |= ZSD_DESTROY_COMPLETED;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1199
		cv_broadcast(&t->zsd_cv);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1200
		DTRACE_PROBE2(zsd__destroy__completed,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1201
		    zone_t *, zone, zone_key_t, key);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1202
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1203
	if (!zone_lock_held)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1204
		mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1205
	return (dropped);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1206
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1207
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1208
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1209
 * Wait for any CREATE_NEEDED flag to be cleared.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1210
 * Returns true if lockp was temporarily dropped while waiting.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1211
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1212
static boolean_t
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1213
zsd_wait_for_creator(zone_t *zone, struct zsd_entry *t, kmutex_t *lockp)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1214
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1215
	boolean_t dropped = B_FALSE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1216
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1217
	while (t->zsd_flags & ZSD_CREATE_NEEDED) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1218
		DTRACE_PROBE2(zsd__wait__for__creator,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1219
		    zone_t *, zone, struct zsd_entry *, t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1220
		if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1221
			dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1222
			mutex_exit(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1223
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1224
		cv_wait(&t->zsd_cv, &zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1225
		if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1226
			/* First drop zone_lock to preserve order */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1227
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1228
			mutex_enter(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1229
			mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1230
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1231
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1232
	return (dropped);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1233
}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1234
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1235
/*
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1236
 * Wait for any INPROGRESS flag to be cleared.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1237
 * Returns true if lockp was temporarily dropped while waiting.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1238
 */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1239
static boolean_t
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1240
zsd_wait_for_inprogress(zone_t *zone, struct zsd_entry *t, kmutex_t *lockp)
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1241
{
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1242
	boolean_t dropped = B_FALSE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1243
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1244
	while (t->zsd_flags & ZSD_ALL_INPROGRESS) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1245
		DTRACE_PROBE2(zsd__wait__for__inprogress,
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1246
		    zone_t *, zone, struct zsd_entry *, t);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1247
		if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1248
			dropped = B_TRUE;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1249
			mutex_exit(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1250
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1251
		cv_wait(&t->zsd_cv, &zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1252
		if (lockp != NULL) {
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1253
			/* First drop zone_lock to preserve order */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1254
			mutex_exit(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1255
			mutex_enter(lockp);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1256
			mutex_enter(&zone->zone_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1257
		}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1258
	}
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  1259
	return (dropped);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1263
 * Frees memory associated with the zone dataset list.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1264
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1265
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1266
zone_free_datasets(zone_t *zone)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1267
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1268
	zone_dataset_t *t, *next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1270
	for (t = list_head(&zone->zone_datasets); t != NULL; t = next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1271
		next = list_next(&zone->zone_datasets, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1272
		list_remove(&zone->zone_datasets, t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1273
		kmem_free(t->zd_dataset, strlen(t->zd_dataset) + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1274
		kmem_free(t, sizeof (*t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1275
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1276
	list_destroy(&zone->zone_datasets);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1277
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  1279
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
 * zone.cpu-shares resource control support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
static rctl_qty_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
zone_cpu_shares_usage(rctl_t *rctl, struct proc *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	return (p->p_zone->zone_shares);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
zone_cpu_shares_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
    rctl_qty_t nv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	ASSERT(e->rcep_t == RCENTITY_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
	if (e->rcep_p.zone == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
	e->rcep_p.zone->zone_shares = nv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
static rctl_ops_t zone_cpu_shares_ops = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	rcop_no_action,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	zone_cpu_shares_usage,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
	zone_cpu_shares_set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	rcop_no_test
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1311
/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1312
 * zone.cpu-cap resource control support.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1313
 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1314
/*ARGSUSED*/
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1315
static rctl_qty_t
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1316
zone_cpu_cap_get(rctl_t *rctl, struct proc *p)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1317
{
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1318
	ASSERT(MUTEX_HELD(&p->p_lock));
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1319
	return (cpucaps_zone_get(p->p_zone));
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1320
}
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1321
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1322
/*ARGSUSED*/
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1323
static int
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1324
zone_cpu_cap_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1325
    rctl_qty_t nv)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1326
{
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1327
	zone_t *zone = e->rcep_p.zone;
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1328
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1329
	ASSERT(MUTEX_HELD(&p->p_lock));
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1330
	ASSERT(e->rcep_t == RCENTITY_ZONE);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1331
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1332
	if (zone == NULL)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1333
		return (0);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1334
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1335
	/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1336
	 * set cap to the new value.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1337
	 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1338
	return (cpucaps_zone_set(zone, nv));
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1339
}
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1340
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1341
static rctl_ops_t zone_cpu_cap_ops = {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1342
	rcop_no_action,
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1343
	zone_cpu_cap_get,
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1344
	zone_cpu_cap_set,
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1345
	rcop_no_test
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1346
};
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1347
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
static rctl_qty_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
zone_lwps_usage(rctl_t *r, proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
	rctl_qty_t nlwps;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
	zone_t *zone = p->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
	mutex_enter(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	nlwps = zone->zone_nlwps;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
	mutex_exit(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
	return (nlwps);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
zone_lwps_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e, rctl_val_t *rcntl,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
    rctl_qty_t incr, uint_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	rctl_qty_t nlwps;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	ASSERT(e->rcep_t == RCENTITY_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
	if (e->rcep_p.zone == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	ASSERT(MUTEX_HELD(&(e->rcep_p.zone->zone_nlwps_lock)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	nlwps = e->rcep_p.zone->zone_nlwps;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
	if (nlwps + incr > rcntl->rcv_value)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
static int
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1386
zone_lwps_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e, rctl_qty_t nv)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1387
{
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	ASSERT(e->rcep_t == RCENTITY_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	if (e->rcep_p.zone == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
	e->rcep_p.zone->zone_nlwps_ctl = nv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
static rctl_ops_t zone_lwps_ops = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
	rcop_no_action,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	zone_lwps_usage,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
	zone_lwps_set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
	zone_lwps_test,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1403
/*ARGSUSED*/
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1404
static int
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1405
zone_shmmax_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e, rctl_val_t *rval,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1406
    rctl_qty_t incr, uint_t flags)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1407
{
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1408
	rctl_qty_t v;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1409
	ASSERT(MUTEX_HELD(&p->p_lock));
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1410
	ASSERT(e->rcep_t == RCENTITY_ZONE);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1411
	v = e->rcep_p.zone->zone_shmmax + incr;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1412
	if (v > rval->rcv_value)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1413
		return (1);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1414
	return (0);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1415
}
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1416
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1417
static rctl_ops_t zone_shmmax_ops = {
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1418
	rcop_no_action,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1419
	rcop_no_usage,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1420
	rcop_no_set,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1421
	zone_shmmax_test
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1422
};
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1423
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1424
/*ARGSUSED*/
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1425
static int
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1426
zone_shmmni_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e, rctl_val_t *rval,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1427
    rctl_qty_t incr, uint_t flags)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1428
{
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1429
	rctl_qty_t v;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1430
	ASSERT(MUTEX_HELD(&p->p_lock));
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1431
	ASSERT(e->rcep_t == RCENTITY_ZONE);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1432
	v = e->rcep_p.zone->zone_ipc.ipcq_shmmni + incr;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1433
	if (v > rval->rcv_value)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1434
		return (1);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1435
	return (0);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1436
}
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1437
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1438
static rctl_ops_t zone_shmmni_ops = {
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1439
	rcop_no_action,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1440
	rcop_no_usage,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1441
	rcop_no_set,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1442
	zone_shmmni_test
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1443
};
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1444
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1445
/*ARGSUSED*/
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1446
static int
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1447
zone_semmni_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e, rctl_val_t *rval,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1448
    rctl_qty_t incr, uint_t flags)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1449
{
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1450
	rctl_qty_t v;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1451
	ASSERT(MUTEX_HELD(&p->p_lock));
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1452
	ASSERT(e->rcep_t == RCENTITY_ZONE);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1453
	v = e->rcep_p.zone->zone_ipc.ipcq_semmni + incr;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1454
	if (v > rval->rcv_value)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1455
		return (1);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1456
	return (0);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1457
}
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1458
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1459
static rctl_ops_t zone_semmni_ops = {
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1460
	rcop_no_action,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1461
	rcop_no_usage,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1462
	rcop_no_set,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1463
	zone_semmni_test
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1464
};
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1465
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1466
/*ARGSUSED*/
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1467
static int
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1468
zone_msgmni_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e, rctl_val_t *rval,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1469
    rctl_qty_t incr, uint_t flags)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1470
{
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1471
	rctl_qty_t v;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1472
	ASSERT(MUTEX_HELD(&p->p_lock));
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1473
	ASSERT(e->rcep_t == RCENTITY_ZONE);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1474
	v = e->rcep_p.zone->zone_ipc.ipcq_msgmni + incr;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1475
	if (v > rval->rcv_value)
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1476
		return (1);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1477
	return (0);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1478
}
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1479
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1480
static rctl_ops_t zone_msgmni_ops = {
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1481
	rcop_no_action,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1482
	rcop_no_usage,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1483
	rcop_no_set,
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1484
	zone_msgmni_test
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1485
};
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1486
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1487
/*ARGSUSED*/
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1488
static rctl_qty_t
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1489
zone_locked_mem_usage(rctl_t *rctl, struct proc *p)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1490
{
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1491
	rctl_qty_t q;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1492
	ASSERT(MUTEX_HELD(&p->p_lock));
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1493
	mutex_enter(&p->p_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1494
	q = p->p_zone->zone_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1495
	mutex_exit(&p->p_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1496
	return (q);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1497
}
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1498
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1499
/*ARGSUSED*/
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1500
static int
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1501
zone_locked_mem_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1502
    rctl_val_t *rcntl, rctl_qty_t incr, uint_t flags)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1503
{
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1504
	rctl_qty_t q;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1505
	zone_t *z;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1506
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1507
	z = e->rcep_p.zone;
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1508
	ASSERT(MUTEX_HELD(&p->p_lock));
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1509
	ASSERT(MUTEX_HELD(&z->zone_mem_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1510
	q = z->zone_locked_mem;
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1511
	if (q + incr > rcntl->rcv_value)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1512
		return (1);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1513
	return (0);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1514
}
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1515
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1516
/*ARGSUSED*/
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1517
static int
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1518
zone_locked_mem_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1519
    rctl_qty_t nv)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1520
{
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1521
	ASSERT(MUTEX_HELD(&p->p_lock));
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1522
	ASSERT(e->rcep_t == RCENTITY_ZONE);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1523
	if (e->rcep_p.zone == NULL)
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1524
		return (0);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1525
	e->rcep_p.zone->zone_locked_mem_ctl = nv;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1526
	return (0);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1527
}
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1528
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1529
static rctl_ops_t zone_locked_mem_ops = {
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1530
	rcop_no_action,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1531
	zone_locked_mem_usage,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1532
	zone_locked_mem_set,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1533
	zone_locked_mem_test
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1534
};
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1535
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1536
/*ARGSUSED*/
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1537
static rctl_qty_t
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1538
zone_max_swap_usage(rctl_t *rctl, struct proc *p)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1539
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1540
	rctl_qty_t q;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1541
	zone_t *z = p->p_zone;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1542
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1543
	ASSERT(MUTEX_HELD(&p->p_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1544
	mutex_enter(&z->zone_mem_lock);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1545
	q = z->zone_max_swap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1546
	mutex_exit(&z->zone_mem_lock);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1547
	return (q);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1548
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1549
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1550
/*ARGSUSED*/
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1551
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1552
zone_max_swap_test(rctl_t *r, proc_t *p, rctl_entity_p_t *e,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1553
    rctl_val_t *rcntl, rctl_qty_t incr, uint_t flags)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1554
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1555
	rctl_qty_t q;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1556
	zone_t *z;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1557
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1558
	z = e->rcep_p.zone;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1559
	ASSERT(MUTEX_HELD(&p->p_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1560
	ASSERT(MUTEX_HELD(&z->zone_mem_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1561
	q = z->zone_max_swap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1562
	if (q + incr > rcntl->rcv_value)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1563
		return (1);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1564
	return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1565
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1566
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1567
/*ARGSUSED*/
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1568
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1569
zone_max_swap_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1570
    rctl_qty_t nv)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1571
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1572
	ASSERT(MUTEX_HELD(&p->p_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1573
	ASSERT(e->rcep_t == RCENTITY_ZONE);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1574
	if (e->rcep_p.zone == NULL)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1575
		return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1576
	e->rcep_p.zone->zone_max_swap_ctl = nv;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1577
	return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1578
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1579
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1580
static rctl_ops_t zone_max_swap_ops = {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1581
	rcop_no_action,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1582
	zone_max_swap_usage,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1583
	zone_max_swap_set,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1584
	zone_max_swap_test
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1585
};
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1586
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
 * Helper function to brand the zone with a unique ID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
zone_uniqid(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
	static uint64_t uniqid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	zone->zone_uniqid = uniqid++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
 * Returns a held pointer to the "kcred" for the specified zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
struct cred *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
zone_get_kcred(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	cred_t *cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	if ((zone = zone_find_by_id(zoneid)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	cr = zone->zone_kcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	crhold(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	return (cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1616
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1617
zone_lockedmem_kstat_update(kstat_t *ksp, int rw)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1618
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1619
	zone_t *zone = ksp->ks_private;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1620
	zone_kstat_t *zk = ksp->ks_data;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1621
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1622
	if (rw == KSTAT_WRITE)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1623
		return (EACCES);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1624
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1625
	zk->zk_usage.value.ui64 = zone->zone_locked_mem;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1626
	zk->zk_value.value.ui64 = zone->zone_locked_mem_ctl;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1627
	return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1628
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1629
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1630
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1631
zone_swapresv_kstat_update(kstat_t *ksp, int rw)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1632
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1633
	zone_t *zone = ksp->ks_private;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1634
	zone_kstat_t *zk = ksp->ks_data;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1635
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1636
	if (rw == KSTAT_WRITE)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1637
		return (EACCES);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1638
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1639
	zk->zk_usage.value.ui64 = zone->zone_max_swap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1640
	zk->zk_value.value.ui64 = zone->zone_max_swap_ctl;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1641
	return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1642
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1643
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1644
static void
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1645
zone_kstat_create(zone_t *zone)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1646
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1647
	kstat_t *ksp;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1648
	zone_kstat_t *zk;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1649
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1650
	ksp = rctl_kstat_create_zone(zone, "lockedmem", KSTAT_TYPE_NAMED,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1651
	    sizeof (zone_kstat_t) / sizeof (kstat_named_t),
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1652
	    KSTAT_FLAG_VIRTUAL);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1653
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1654
	if (ksp == NULL)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1655
		return;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1656
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1657
	zk = ksp->ks_data = kmem_alloc(sizeof (zone_kstat_t), KM_SLEEP);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1658
	ksp->ks_data_size += strlen(zone->zone_name) + 1;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1659
	kstat_named_init(&zk->zk_zonename, "zonename", KSTAT_DATA_STRING);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1660
	kstat_named_setstr(&zk->zk_zonename, zone->zone_name);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1661
	kstat_named_init(&zk->zk_usage, "usage", KSTAT_DATA_UINT64);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1662
	kstat_named_init(&zk->zk_value, "value", KSTAT_DATA_UINT64);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1663
	ksp->ks_update = zone_lockedmem_kstat_update;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1664
	ksp->ks_private = zone;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1665
	kstat_install(ksp);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1666
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1667
	zone->zone_lockedmem_kstat = ksp;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1668
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1669
	ksp = rctl_kstat_create_zone(zone, "swapresv", KSTAT_TYPE_NAMED,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1670
	    sizeof (zone_kstat_t) / sizeof (kstat_named_t),
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1671
	    KSTAT_FLAG_VIRTUAL);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1672
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1673
	if (ksp == NULL)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1674
		return;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1675
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1676
	zk = ksp->ks_data = kmem_alloc(sizeof (zone_kstat_t), KM_SLEEP);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1677
	ksp->ks_data_size += strlen(zone->zone_name) + 1;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1678
	kstat_named_init(&zk->zk_zonename, "zonename", KSTAT_DATA_STRING);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1679
	kstat_named_setstr(&zk->zk_zonename, zone->zone_name);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1680
	kstat_named_init(&zk->zk_usage, "usage", KSTAT_DATA_UINT64);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1681
	kstat_named_init(&zk->zk_value, "value", KSTAT_DATA_UINT64);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1682
	ksp->ks_update = zone_swapresv_kstat_update;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1683
	ksp->ks_private = zone;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1684
	kstat_install(ksp);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1685
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1686
	zone->zone_swapresv_kstat = ksp;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1687
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1688
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1689
static void
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1690
zone_kstat_delete(zone_t *zone)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1691
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1692
	void *data;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1693
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1694
	if (zone->zone_lockedmem_kstat != NULL) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1695
		data = zone->zone_lockedmem_kstat->ks_data;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1696
		kstat_delete(zone->zone_lockedmem_kstat);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1697
		kmem_free(data, sizeof (zone_kstat_t));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1698
	}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1699
	if (zone->zone_swapresv_kstat != NULL) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1700
		data = zone->zone_swapresv_kstat->ks_data;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1701
		kstat_delete(zone->zone_swapresv_kstat);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1702
		kmem_free(data, sizeof (zone_kstat_t));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1703
	}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1704
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1705
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
 * Called very early on in boot to initialize the ZSD list so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
 * zone_key_create() can be called before zone_init().  It also initializes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
 * portions of zone0 which may be used before zone_init() is called.  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
 * variable "global_zone" will be set when zone0 is fully initialized by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
 * zone_init().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
zone_zsd_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
	mutex_init(&zonehash_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	mutex_init(&zsd_key_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	list_create(&zsd_registered_keys, sizeof (struct zsd_entry),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
	    offsetof(struct zsd_entry, zsd_linkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
	list_create(&zone_active, sizeof (zone_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
	    offsetof(zone_t, zone_linkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
	list_create(&zone_deathrow, sizeof (zone_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
	    offsetof(zone_t, zone_linkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
	mutex_init(&zone0.zone_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	mutex_init(&zone0.zone_nlwps_lock, NULL, MUTEX_DEFAULT, NULL);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1727
	mutex_init(&zone0.zone_mem_lock, NULL, MUTEX_DEFAULT, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
	zone0.zone_shares = 1;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1729
	zone0.zone_nlwps = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	zone0.zone_nlwps_ctl = INT_MAX;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1731
	zone0.zone_locked_mem = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1732
	zone0.zone_locked_mem_ctl = UINT64_MAX;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1733
	ASSERT(zone0.zone_max_swap == 0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1734
	zone0.zone_max_swap_ctl = UINT64_MAX;
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1735
	zone0.zone_shmmax = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1736
	zone0.zone_ipc.ipcq_shmmni = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1737
	zone0.zone_ipc.ipcq_semmni = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1738
	zone0.zone_ipc.ipcq_msgmni = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
	zone0.zone_name = GLOBAL_ZONENAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
	zone0.zone_nodename = utsname.nodename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
	zone0.zone_domain = srpc_domain;
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  1742
	zone0.zone_hostid = HW_INVALID_HOSTID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
	zone0.zone_ref = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	zone0.zone_id = GLOBAL_ZONEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
	zone0.zone_status = ZONE_IS_RUNNING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
	zone0.zone_rootpath = "/";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
	zone0.zone_rootpathlen = 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
	zone0.zone_psetid = ZONE_PS_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
	zone0.zone_ncpus = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
	zone0.zone_ncpus_online = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
	zone0.zone_proc_initpid = 1;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  1752
	zone0.zone_initname = initname;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1753
	zone0.zone_lockedmem_kstat = NULL;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1754
	zone0.zone_swapresv_kstat = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
	list_create(&zone0.zone_zsd, sizeof (struct zsd_entry),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	    offsetof(struct zsd_entry, zsd_linkage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
	list_insert_head(&zone_active, &zone0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
	 * The root filesystem is not mounted yet, so zone_rootvp cannot be set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
	 * to anything meaningful.  It is assigned to be 'rootdir' in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
	 * vfs_mountroot().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
	zone0.zone_rootvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	zone0.zone_vfslist = NULL;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  1766
	zone0.zone_bootargs = initargs;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	zone0.zone_privset = kmem_alloc(sizeof (priv_set_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	 * The global zone has all privileges
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	priv_fillset(zone0.zone_privset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	 * Add p0 to the global zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	zone0.zone_zsched = &p0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	p0.p_zone = &zone0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1780
 * Compute a hash value based on the contents of the label and the DOI.  The
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1781
 * hash algorithm is somewhat arbitrary, but is based on the observation that
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1782
 * humans will likely pick labels that differ by amounts that work out to be
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1783
 * multiples of the number of hash chains, and thus stirring in some primes
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1784
 * should help.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1785
 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1786
static uint_t
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1787
hash_bylabel(void *hdata, mod_hash_key_t key)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1788
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1789
	const ts_label_t *lab = (ts_label_t *)key;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1790
	const uint32_t *up, *ue;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1791
	uint_t hash;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1792
	int i;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1793
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1794
	_NOTE(ARGUNUSED(hdata));
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1795
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1796
	hash = lab->tsl_doi + (lab->tsl_doi << 1);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1797
	/* we depend on alignment of label, but not representation */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1798
	up = (const uint32_t *)&lab->tsl_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1799
	ue = up + sizeof (lab->tsl_label) / sizeof (*up);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1800
	i = 1;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1801
	while (up < ue) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1802
		/* using 2^n + 1, 1 <= n <= 16 as source of many primes */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1803
		hash += *up + (*up << ((i % 16) + 1));
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1804
		up++;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1805
		i++;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1806
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1807
	return (hash);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1808
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1809
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1810
/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1811
 * All that mod_hash cares about here is zero (equal) versus non-zero (not
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1812
 * equal).  This may need to be changed if less than / greater than is ever
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1813
 * needed.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1814
 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1815
static int
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1816
hash_labelkey_cmp(mod_hash_key_t key1, mod_hash_key_t key2)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1817
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1818
	ts_label_t *lab1 = (ts_label_t *)key1;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1819
	ts_label_t *lab2 = (ts_label_t *)key2;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1820
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1821
	return (label_equal(lab1, lab2) ? 0 : 1);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1822
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1823
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1824
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
 * Called by main() to initialize the zones framework.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
zone_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
	rctl_dict_entry_t *rde;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	rctl_val_t *dval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
	rctl_set_t *set;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
	rctl_alloc_gp_t *gp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	rctl_entity_p_t e;
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1835
	int res;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
	ASSERT(curproc == &p0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	 * Create ID space for zone IDs.  ID 0 is reserved for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
	 * global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	zoneid_space = id_space_create("zoneid_space", 1, MAX_ZONEID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	 * Initialize generic zone resource controls, if any.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	rc_zone_cpu_shares = rctl_register("zone.cpu-shares",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
	    RCENTITY_ZONE, RCTL_GLOBAL_SIGNAL_NEVER | RCTL_GLOBAL_DENY_NEVER |
1996
1bd5128dcd61 6294710 rctladm incorrectly claims and reports it can log to syslog for project.cpu-shares
ml93401
parents: 1876
diff changeset
  1850
	    RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_COUNT | RCTL_GLOBAL_SYSLOG_NEVER,
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1851
	    FSS_MAXSHARES, FSS_MAXSHARES, &zone_cpu_shares_ops);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1852
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1853
	rc_zone_cpu_cap = rctl_register("zone.cpu-cap",
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1854
	    RCENTITY_ZONE, RCTL_GLOBAL_SIGNAL_NEVER | RCTL_GLOBAL_DENY_ALWAYS |
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1855
	    RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_COUNT |RCTL_GLOBAL_SYSLOG_NEVER |
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1856
	    RCTL_GLOBAL_INFINITE,
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  1857
	    MAXCAP, MAXCAP, &zone_cpu_cap_ops);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
	rc_zone_nlwps = rctl_register("zone.max-lwps", RCENTITY_ZONE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
	    RCTL_GLOBAL_NOACTION | RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_COUNT,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	    INT_MAX, INT_MAX, &zone_lwps_ops);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
	/*
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1863
	 * System V IPC resource controls
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1864
	 */
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1865
	rc_zone_msgmni = rctl_register("zone.max-msg-ids",
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1866
	    RCENTITY_ZONE, RCTL_GLOBAL_DENY_ALWAYS | RCTL_GLOBAL_NOBASIC |
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1867
	    RCTL_GLOBAL_COUNT, IPC_IDS_MAX, IPC_IDS_MAX, &zone_msgmni_ops);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1868
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1869
	rc_zone_semmni = rctl_register("zone.max-sem-ids",
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1870
	    RCENTITY_ZONE, RCTL_GLOBAL_DENY_ALWAYS | RCTL_GLOBAL_NOBASIC |
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1871
	    RCTL_GLOBAL_COUNT, IPC_IDS_MAX, IPC_IDS_MAX, &zone_semmni_ops);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1872
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1873
	rc_zone_shmmni = rctl_register("zone.max-shm-ids",
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1874
	    RCENTITY_ZONE, RCTL_GLOBAL_DENY_ALWAYS | RCTL_GLOBAL_NOBASIC |
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1875
	    RCTL_GLOBAL_COUNT, IPC_IDS_MAX, IPC_IDS_MAX, &zone_shmmni_ops);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1876
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1877
	rc_zone_shmmax = rctl_register("zone.max-shm-memory",
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1878
	    RCENTITY_ZONE, RCTL_GLOBAL_DENY_ALWAYS | RCTL_GLOBAL_NOBASIC |
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1879
	    RCTL_GLOBAL_BYTES, UINT64_MAX, UINT64_MAX, &zone_shmmax_ops);
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1880
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  1881
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
	 * Create a rctl_val with PRIVILEGED, NOACTION, value = 1.  Then attach
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
	 * this at the head of the rctl_dict_entry for ``zone.cpu-shares''.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
	dval = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
	bzero(dval, sizeof (rctl_val_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
	dval->rcv_value = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
	dval->rcv_privilege = RCPRIV_PRIVILEGED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
	dval->rcv_flagaction = RCTL_LOCAL_NOACTION;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
	dval->rcv_action_recip_pid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
	rde = rctl_dict_lookup("zone.cpu-shares");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
	(void) rctl_val_list_insert(&rde->rcd_default_value, dval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1895
	rc_zone_locked_mem = rctl_register("zone.max-locked-memory",
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1896
	    RCENTITY_ZONE, RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_BYTES |
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1897
	    RCTL_GLOBAL_DENY_ALWAYS, UINT64_MAX, UINT64_MAX,
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  1898
	    &zone_locked_mem_ops);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1899
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1900
	rc_zone_max_swap = rctl_register("zone.max-swap",
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1901
	    RCENTITY_ZONE, RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_BYTES |
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1902
	    RCTL_GLOBAL_DENY_ALWAYS, UINT64_MAX, UINT64_MAX,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1903
	    &zone_max_swap_ops);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1904
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
	 * Initialize the ``global zone''.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
	set = rctl_set_create();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
	gp = rctl_set_init_prealloc(RCENTITY_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
	mutex_enter(&p0.p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
	e.rcep_p.zone = &zone0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	e.rcep_t = RCENTITY_ZONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	zone0.zone_rctls = rctl_set_init(RCENTITY_ZONE, &p0, &e, set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
	    gp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
	zone0.zone_nlwps = p0.p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
	zone0.zone_ntasks = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	mutex_exit(&p0.p_lock);
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  1919
	zone0.zone_restart_init = B_TRUE;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  1920
	zone0.zone_brand = &native_brand;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	rctl_prealloc_destroy(gp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
	/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1923
	 * pool_default hasn't been initialized yet, so we let pool_init()
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1924
	 * take care of making sure the global zone is in the default pool.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	 */
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1926
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1927
	/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1928
	 * Initialize global zone kstats
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1929
	 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1930
	zone_kstat_create(&zone0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1931
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1932
	/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1933
	 * Initialize zone label.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1934
	 * mlp are initialized when tnzonecfg is loaded.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1935
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1936
	zone0.zone_slabel = l_admin_low;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1937
	rw_init(&zone0.zone_mlps.mlpl_rwlock, NULL, RW_DEFAULT, NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1938
	label_hold(l_admin_low);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1939
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  1940
	/*
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  1941
	 * Initialise the lock for the database structure used by mntfs.
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  1942
	 */
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  1943
	rw_init(&zone0.zone_mntfs_db_lock, NULL, RW_DEFAULT, NULL);
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  1944
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
	zone_uniqid(&zone0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	ASSERT(zone0.zone_uniqid == GLOBAL_ZONEUNIQID);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1948
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	zonehashbyid = mod_hash_create_idhash("zone_by_id", zone_hash_size,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	    mod_hash_null_valdtor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	zonehashbyname = mod_hash_create_strhash("zone_by_name",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	    zone_hash_size, mod_hash_null_valdtor);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1953
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1954
	 * maintain zonehashbylabel only for labeled systems
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1955
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1956
	if (is_system_labeled())
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1957
		zonehashbylabel = mod_hash_create_extended("zone_by_label",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1958
		    zone_hash_size, mod_hash_null_keydtor,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1959
		    mod_hash_null_valdtor, hash_bylabel, NULL,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1960
		    hash_labelkey_cmp, KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	zonecount = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
	(void) mod_hash_insert(zonehashbyid, (mod_hash_key_t)GLOBAL_ZONEID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	    (mod_hash_val_t)&zone0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
	(void) mod_hash_insert(zonehashbyname, (mod_hash_key_t)zone0.zone_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
	    (mod_hash_val_t)&zone0);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  1967
	if (is_system_labeled()) {
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  1968
		zone0.zone_flags |= ZF_HASHED_LABEL;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1969
		(void) mod_hash_insert(zonehashbylabel,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1970
		    (mod_hash_key_t)zone0.zone_slabel, (mod_hash_val_t)&zone0);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  1971
	}
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1972
	mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  1973
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
	 * We avoid setting zone_kcred until now, since kcred is initialized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
	 * sometime after zone_zsd_init() and before zone_init().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
	zone0.zone_kcred = kcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
	 * The global zone is fully initialized (except for zone_rootvp which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
	 * will be set when the root filesystem is mounted).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
	global_zone = &zone0;
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1984
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1985
	/*
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1986
	 * Setup an event channel to send zone status change notifications on
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1987
	 */
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1988
	res = sysevent_evc_bind(ZONE_EVENT_CHANNEL, &zone_event_chan,
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1989
	    EVCH_CREAT);
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1990
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1991
	if (res)
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  1992
		panic("Sysevent_evc_bind failed during zone setup.\n");
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  1993
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
zone_free(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
	ASSERT(zone != global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
	ASSERT(zone->zone_ntasks == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
	ASSERT(zone->zone_nlwps == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
	ASSERT(zone->zone_cred_ref == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
	ASSERT(zone->zone_kcred == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
	ASSERT(zone_status_get(zone) == ZONE_IS_DEAD ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
	    zone_status_get(zone) == ZONE_IS_UNINITIALIZED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2007
	/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2008
	 * Remove any zone caps.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2009
	 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2010
	cpucaps_zone_remove(zone);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2011
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2012
	ASSERT(zone->zone_cpucap == NULL);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  2013
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	/* remove from deathrow list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	if (zone_status_get(zone) == ZONE_IS_DEAD) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
		ASSERT(zone->zone_ref == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
		mutex_enter(&zone_deathrow_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
		list_remove(&zone_deathrow, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
		mutex_exit(&zone_deathrow_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	zone_free_zsd(zone);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  2023
	zone_free_datasets(zone);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  2024
	list_destroy(&zone->zone_dl_list);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
	if (zone->zone_rootvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
		VN_RELE(zone->zone_rootvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
	if (zone->zone_rootpath)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
		kmem_free(zone->zone_rootpath, zone->zone_rootpathlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
	if (zone->zone_name != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
		kmem_free(zone->zone_name, ZONENAME_MAX);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2032
	if (zone->zone_slabel != NULL)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2033
		label_rele(zone->zone_slabel);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
	if (zone->zone_nodename != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
		kmem_free(zone->zone_nodename, _SYS_NMLN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	if (zone->zone_domain != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
		kmem_free(zone->zone_domain, _SYS_NMLN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
	if (zone->zone_privset != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
		kmem_free(zone->zone_privset, sizeof (priv_set_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	if (zone->zone_rctls != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
		rctl_set_free(zone->zone_rctls);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	if (zone->zone_bootargs != NULL)
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2043
		kmem_free(zone->zone_bootargs, strlen(zone->zone_bootargs) + 1);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2044
	if (zone->zone_initname != NULL)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2045
		kmem_free(zone->zone_initname, strlen(zone->zone_initname) + 1);
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  2046
	if (zone->zone_pfexecd != NULL)
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  2047
		klpd_freelist(&zone->zone_pfexecd);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
	id_free(zoneid_space, zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	mutex_destroy(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
	cv_destroy(&zone->zone_cv);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2051
	rw_destroy(&zone->zone_mlps.mlpl_rwlock);
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  2052
	rw_destroy(&zone->zone_mntfs_db_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
	kmem_free(zone, sizeof (zone_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
 * See block comment at the top of this file for information about zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
 * status values.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
 * Convenience function for setting zone status.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
zone_status_set(zone_t *zone, zone_status_t status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
{
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2066
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2067
	nvlist_t *nvl = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
	ASSERT(MUTEX_HELD(&zone_status_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
	    status >= zone_status_get(zone));
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2071
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2072
	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) ||
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2073
	    nvlist_add_string(nvl, ZONE_CB_NAME, zone->zone_name) ||
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2074
	    nvlist_add_string(nvl, ZONE_CB_NEWSTATE,
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2075
	    zone_status_table[status]) ||
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2076
	    nvlist_add_string(nvl, ZONE_CB_OLDSTATE,
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2077
	    zone_status_table[zone->zone_status]) ||
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2078
	    nvlist_add_int32(nvl, ZONE_CB_ZONEID, zone->zone_id) ||
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2079
	    nvlist_add_uint64(nvl, ZONE_CB_TIMESTAMP, (uint64_t)gethrtime()) ||
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2080
	    sysevent_evc_publish(zone_event_chan, ZONE_EVENT_STATUS_CLASS,
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2081
	    ZONE_EVENT_STATUS_SUBCLASS, "sun.com", "kernel", nvl, EVCH_SLEEP)) {
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2082
#ifdef DEBUG
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2083
		(void) printf(
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2084
		    "Failed to allocate and send zone state change event.\n");
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2085
#endif
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2086
	}
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2087
	nvlist_free(nvl);
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2088
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
	zone->zone_status = status;
1166
1eedf65f1c9f PSARC/2005/607 Zone Events for Sun Cluster
dstaff
parents: 1075
diff changeset
  2090
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
	cv_broadcast(&zone->zone_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
 * Public function to retrieve the zone status.  The zone status may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
 * change after it is retrieved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
zone_status_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
zone_status_get(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
	return (zone->zone_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
zone_set_bootargs(zone_t *zone, const char *zone_bootargs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
{
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2107
	char *bootargs = kmem_zalloc(BOOTARGS_MAX, KM_SLEEP);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2108
	int err = 0;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2109
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2110
	ASSERT(zone != global_zone);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2111
	if ((err = copyinstr(zone_bootargs, bootargs, BOOTARGS_MAX, NULL)) != 0)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2112
		goto done;	/* EFAULT or ENAMETOOLONG */
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2113
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2114
	if (zone->zone_bootargs != NULL)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2115
		kmem_free(zone->zone_bootargs, strlen(zone->zone_bootargs) + 1);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2116
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2117
	zone->zone_bootargs = kmem_alloc(strlen(bootargs) + 1, KM_SLEEP);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2118
	(void) strcpy(zone->zone_bootargs, bootargs);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2119
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2120
done:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2121
	kmem_free(bootargs, BOOTARGS_MAX);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2122
	return (err);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2123
}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2124
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2125
static int
4141
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2126
zone_set_brand(zone_t *zone, const char *brand)
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2127
{
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2128
	struct brand_attr *attrp;
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2129
	brand_t *bp;
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2130
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2131
	attrp = kmem_alloc(sizeof (struct brand_attr), KM_SLEEP);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2132
	if (copyin(brand, attrp, sizeof (struct brand_attr)) != 0) {
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2133
		kmem_free(attrp, sizeof (struct brand_attr));
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2134
		return (EFAULT);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2135
	}
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2136
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2137
	bp = brand_register_zone(attrp);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2138
	kmem_free(attrp, sizeof (struct brand_attr));
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2139
	if (bp == NULL)
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2140
		return (EINVAL);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2141
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2142
	/*
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2143
	 * This is the only place where a zone can change it's brand.
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2144
	 * We already need to hold zone_status_lock to check the zone
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2145
	 * status, so we'll just use that lock to serialize zone
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2146
	 * branding requests as well.
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2147
	 */
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2148
	mutex_enter(&zone_status_lock);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2149
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2150
	/* Re-Branding is not allowed and the zone can't be booted yet */
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2151
	if ((ZONE_IS_BRANDED(zone)) ||
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2152
	    (zone_status_get(zone) >= ZONE_IS_BOOTING)) {
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2153
		mutex_exit(&zone_status_lock);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2154
		brand_unregister_zone(bp);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2155
		return (EINVAL);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2156
	}
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2157
4888
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  2158
	/* set up the brand specific data */
4141
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2159
	zone->zone_brand = bp;
4888
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  2160
	ZBROP(zone)->b_init_brand_data(zone);
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  2161
4141
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2162
	mutex_exit(&zone_status_lock);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2163
	return (0);
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2164
}
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2165
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  2166
static int
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2167
zone_set_initname(zone_t *zone, const char *zone_initname)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2168
{
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2169
	char initname[INITNAME_SZ];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	size_t len;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2171
	int err = 0;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2172
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2173
	ASSERT(zone != global_zone);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2174
	if ((err = copyinstr(zone_initname, initname, INITNAME_SZ, &len)) != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
		return (err);	/* EFAULT or ENAMETOOLONG */
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2176
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2177
	if (zone->zone_initname != NULL)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2178
		kmem_free(zone->zone_initname, strlen(zone->zone_initname) + 1);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2179
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2180
	zone->zone_initname = kmem_alloc(strlen(initname) + 1, KM_SLEEP);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  2181
	(void) strcpy(zone->zone_initname, initname);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2185
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2186
zone_set_phys_mcap(zone_t *zone, const uint64_t *zone_mcap)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2187
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2188
	uint64_t mcap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2189
	int err = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2190
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2191
	if ((err = copyin(zone_mcap, &mcap, sizeof (uint64_t))) == 0)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2192
		zone->zone_phys_mcap = mcap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2193
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2194
	return (err);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2195
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2196
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2197
static int
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2198
zone_set_sched_class(zone_t *zone, const char *new_class)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2199
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2200
	char sched_class[PC_CLNMSZ];
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2201
	id_t classid;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2202
	int err;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2203
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2204
	ASSERT(zone != global_zone);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2205
	if ((err = copyinstr(new_class, sched_class, PC_CLNMSZ, NULL)) != 0)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2206
		return (err);	/* EFAULT or ENAMETOOLONG */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2207
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
  2208
	if (getcid(sched_class, &classid) != 0 || CLASS_KERNEL(classid))
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2209
		return (set_errno(EINVAL));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2210
	zone->zone_defaultcid = classid;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2211
	ASSERT(zone->zone_defaultcid > 0 &&
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2212
	    zone->zone_defaultcid < loaded_classes);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2213
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2214
	return (0);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2215
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  2216
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
 * Block indefinitely waiting for (zone_status >= status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
zone_status_wait(zone_t *zone, zone_status_t status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
	while (zone->zone_status < status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
		cv_wait(&zone->zone_cv, &zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
 * Private CPR-safe version of zone_status_wait().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
zone_status_wait_cpr(zone_t *zone, zone_status_t status, char *str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
	callb_cpr_t cprinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
	CALLB_CPR_INIT(&cprinfo, &zone_status_lock, callb_generic_cpr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
	    str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
	while (zone->zone_status < status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
		CALLB_CPR_SAFE_BEGIN(&cprinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
		cv_wait(&zone->zone_cv, &zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
		CALLB_CPR_SAFE_END(&cprinfo, &zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
	 * zone_status_lock is implicitly released by the following.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
	CALLB_CPR_EXIT(&cprinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
 * Block until zone enters requested state or signal is received.  Return (0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
 * if signaled, non-zero otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
zone_status_wait_sig(zone_t *zone, zone_status_t status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
	while (zone->zone_status < status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
		if (!cv_wait_sig(&zone->zone_cv, &zone_status_lock)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
			mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
 * Block until the zone enters the requested state or the timeout expires,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
 * whichever happens first.  Return (-1) if operation timed out, time remaining
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
 * otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
clock_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
zone_status_timedwait(zone_t *zone, clock_t tim, zone_status_t status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
	clock_t timeleft = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
	while (zone->zone_status < status && timeleft != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		timeleft = cv_timedwait(&zone->zone_cv, &zone_status_lock, tim);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
	return (timeleft);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
 * Block until the zone enters the requested state, the current process is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
 * signaled,  or the timeout expires, whichever happens first.  Return (-1) if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
 * operation timed out, 0 if signaled, time remaining otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
clock_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
zone_status_timedwait_sig(zone_t *zone, clock_t tim, zone_status_t status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
{
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 10910
diff changeset
  2304
	clock_t timeleft = tim - ddi_get_lbolt();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	ASSERT(status > ZONE_MIN_STATE && status <= ZONE_MAX_STATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
	while (zone->zone_status < status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
		timeleft = cv_timedwait_sig(&zone->zone_cv, &zone_status_lock,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
		    tim);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
		if (timeleft <= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
	return (timeleft);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
 * Zones have two reference counts: one for references from credential
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
 * structures (zone_cred_ref), and one (zone_ref) for everything else.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
 * This is so we can allow a zone to be rebooted while there are still
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
 * outstanding cred references, since certain drivers cache dblks (which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
 * implicitly results in cached creds).  We wait for zone_ref to drop to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
 * 0 (actually 1), but not zone_cred_ref.  The zone structure itself is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
 * later freed when the zone_cred_ref drops to 0, though nothing other
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
 * than the zone id and privilege set should be accessed once the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
 * is "dead".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
 * A debugging flag, zone_wait_for_cred, can be set to a non-zero value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
 * to force halt/reboot to block waiting for the zone_cred_ref to drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
 * to 0.  This can be useful to flush out other sources of cached creds
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
 * that may be less innocuous than the driver case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
int zone_wait_for_cred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
zone_hold_locked(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
	ASSERT(MUTEX_HELD(&z->zone_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
	z->zone_ref++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
	ASSERT(z->zone_ref != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
zone_hold(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
	mutex_enter(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	zone_hold_locked(z);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
	mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
 * If the non-cred ref count drops to 1 and either the cred ref count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
 * is 0 or we aren't waiting for cred references, the zone is ready to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
 * be destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
#define	ZONE_IS_UNREF(zone)	((zone)->zone_ref == 1 && \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
	    (!zone_wait_for_cred || (zone)->zone_cred_ref == 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
zone_rele(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	boolean_t wakeup;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
	mutex_enter(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
	ASSERT(z->zone_ref != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
	z->zone_ref--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
	if (z->zone_ref == 0 && z->zone_cred_ref == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		/* no more refs, free the structure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
		mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
		zone_free(z);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
	/* signal zone_destroy so the zone can finish halting */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
	wakeup = (ZONE_IS_UNREF(z) && zone_status_get(z) >= ZONE_IS_DEAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
	mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
	if (wakeup) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
		 * Grabbing zonehash_lock here effectively synchronizes with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
		 * zone_destroy() to avoid missed signals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
		mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
		cv_broadcast(&zone_destroy_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
zone_cred_hold(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
	mutex_enter(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
	z->zone_cred_ref++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
	ASSERT(z->zone_cred_ref != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
	mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
zone_cred_rele(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
	boolean_t wakeup;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
	mutex_enter(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
	ASSERT(z->zone_cred_ref != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
	z->zone_cred_ref--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	if (z->zone_ref == 0 && z->zone_cred_ref == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
		/* no more refs, free the structure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
		mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
		zone_free(z);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
	 * If zone_destroy is waiting for the cred references to drain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
	 * out, and they have, signal it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
	wakeup = (zone_wait_for_cred && ZONE_IS_UNREF(z) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	    zone_status_get(z) >= ZONE_IS_DEAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
	mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	if (wakeup) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
		 * Grabbing zonehash_lock here effectively synchronizes with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
		 * zone_destroy() to avoid missed signals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
		mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
		cv_broadcast(&zone_destroy_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
zone_task_hold(zone_t *z)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
	mutex_enter(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
	z->zone_ntasks++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
	ASSERT(z->zone_ntasks != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	mutex_exit(&z->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
zone_task_rele(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	uint_t refcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	mutex_enter(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	ASSERT(zone->zone_ntasks != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	refcnt = --zone->zone_ntasks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	if (refcnt > 1)	{	/* Common case */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
	zone_hold_locked(zone);	/* so we can use the zone_t later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
	mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
	if (refcnt == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
		 * See if the zone is shutting down.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
		if (zone_status_get(zone) != ZONE_IS_SHUTTING_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
		 * Make sure the ntasks didn't change since we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
		 * dropped zone_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
		mutex_enter(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
		if (refcnt != zone->zone_ntasks) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
			mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
		 * No more user processes in the zone.  The zone is empty.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
		zone_status_set(zone, ZONE_IS_EMPTY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
	ASSERT(refcnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
	 * zsched has exited; the zone is dead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
	zone->zone_zsched = NULL;		/* paranoia */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	zone_status_set(zone, ZONE_IS_DEAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
zoneid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
getzoneid(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
	return (curproc->p_zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
 * Internal versions of zone_find_by_*().  These don't zone_hold() or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
 * check the validity of a zone's state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
static zone_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
zone_find_all_by_id(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
	mod_hash_val_t hv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	zone_t *zone = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
	if (mod_hash_find(zonehashbyid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
	    (mod_hash_key_t)(uintptr_t)zoneid, &hv) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
		zone = (zone_t *)hv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
	return (zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
static zone_t *
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2520
zone_find_all_by_label(const ts_label_t *label)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2521
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2522
	mod_hash_val_t hv;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2523
	zone_t *zone = NULL;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2524
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2525
	ASSERT(MUTEX_HELD(&zonehash_lock));
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2526
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2527
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2528
	 * zonehashbylabel is not maintained for unlabeled systems
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2529
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2530
	if (!is_system_labeled())
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2531
		return (NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2532
	if (mod_hash_find(zonehashbylabel, (mod_hash_key_t)label, &hv) == 0)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2533
		zone = (zone_t *)hv;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2534
	return (zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2535
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2536
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2537
static zone_t *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
zone_find_all_by_name(char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
	mod_hash_val_t hv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
	zone_t *zone = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
	if (mod_hash_find(zonehashbyname, (mod_hash_key_t)name, &hv) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
		zone = (zone_t *)hv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
	return (zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
 * Public interface for looking up a zone by zoneid.  Only returns the zone if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
 * it is fully initialized, and has not yet begun the zone_destroy() sequence.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
 * Caller must call zone_rele() once it is done with the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
 * The zone may begin the zone_destroy() sequence immediately after this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
 * function returns, but may be safely used until zone_rele() is called.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
zone_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
zone_find_by_id(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
	status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
	if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		 * For all practical purposes the zone doesn't exist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	zone_hold(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
	return (zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2583
 * Similar to zone_find_by_id, but using zone label as the key.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2584
 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2585
zone_t *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2586
zone_find_by_label(const ts_label_t *label)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2587
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2588
	zone_t *zone;
2110
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2589
	zone_status_t status;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2590
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2591
	mutex_enter(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2592
	if ((zone = zone_find_all_by_label(label)) == NULL) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2593
		mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2594
		return (NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2595
	}
2110
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2596
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2597
	status = zone_status_get(zone);
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2598
	if (status > ZONE_IS_DOWN) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2599
		/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2600
		 * For all practical purposes the zone doesn't exist.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2601
		 */
2110
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2602
		mutex_exit(&zonehash_lock);
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2603
		return (NULL);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2604
	}
2110
31cba59b38be 6403267 address remaining issues raised during TX code reviews
rica
parents: 1996
diff changeset
  2605
	zone_hold(zone);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2606
	mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2607
	return (zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2608
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2609
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  2610
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
 * Similar to zone_find_by_id, but using zone name as the key.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
zone_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
zone_find_by_name(char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
	if ((zone = zone_find_all_by_name(name)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
	status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
	if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
		 * For all practical purposes the zone doesn't exist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	zone_hold(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	return (zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
 * Similar to zone_find_by_id(), using the path as a key.  For instance,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
 * if there is a zone "foo" rooted at /foo/root, and the path argument
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
 * is "/foo/root/proc", it will return the held zone_t corresponding to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
 * zone "foo".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
 * zone_find_by_path() always returns a non-NULL value, since at the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
 * very least every path will be contained in the global zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
 * As with the other zone_find_by_*() functions, the caller is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
 * responsible for zone_rele()ing the return value of this function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
zone_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
zone_find_by_path(const char *path)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	zone_t *zret = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	if (path == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
		 * Call from rootconf().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
		zone_hold(global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
		return (global_zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	ASSERT(*path == '/');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
	for (zone = list_head(&zone_active); zone != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
	    zone = list_next(&zone_active, zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
		if (ZONE_PATH_VISIBLE(path, zone))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
			zret = zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
	ASSERT(zret != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
	status = zone_status_get(zret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
	if (status < ZONE_IS_READY || status > ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
		 * Zone practically doesn't exist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
		zret = global_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
	zone_hold(zret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
	return (zret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
 * Get the number of cpus visible to this zone.  The system-wide global
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
 * 'ncpus' is returned if pools are disabled, the caller is in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
 * global zone, or a NULL zone argument is passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
zone_ncpus_get(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
	int myncpus = zone == NULL ? 0 : zone->zone_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
	return (myncpus != 0 ? myncpus : ncpus);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
 * Get the number of online cpus visible to this zone.  The system-wide
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
 * global 'ncpus_online' is returned if pools are disabled, the caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
 * is in the global zone, or a NULL zone argument is passed in.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
zone_ncpus_online_get(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
	int myncpus_online = zone == NULL ? 0 : zone->zone_ncpus_online;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
	return (myncpus_online != 0 ? myncpus_online : ncpus_online);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
 * Return the pool to which the zone is currently bound.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
pool_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
zone_pool_get(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
	return (zone->zone_pool);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
 * Set the zone's pool pointer and update the zone's visibility to match
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
 * the resources in the new pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
zone_pool_set(zone_t *zone, pool_t *pool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
	ASSERT(pool_lock_held());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
	zone->zone_pool = pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
	zone_pset_set(zone, pool->pool_pset->pset_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
 * Return the cached value of the id of the processor set to which the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
 * zone is currently bound.  The value will be ZONE_PS_INVAL if the pools
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
 * facility is disabled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
psetid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
zone_pset_get(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
	return (zone->zone_psetid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
 * Set the cached value of the id of the processor set to which the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
 * is currently bound.  Also update the zone's visibility to match the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
 * resources in the new processor set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
zone_pset_set(zone_t *zone, psetid_t newpsetid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
	psetid_t oldpsetid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
	oldpsetid = zone_pset_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
	if (oldpsetid == newpsetid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
	 * Global zone sees all.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
	if (zone != global_zone) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
		zone->zone_psetid = newpsetid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
		if (newpsetid != ZONE_PS_INVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
			pool_pset_visibility_add(newpsetid, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
		if (oldpsetid != ZONE_PS_INVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
			pool_pset_visibility_remove(oldpsetid, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
	 * Disabling pools, so we should start using the global values
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
	 * for ncpus and ncpus_online.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
	if (newpsetid == ZONE_PS_INVAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
		zone->zone_ncpus = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
		zone->zone_ncpus_online = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
 * Walk the list of active zones and issue the provided callback for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
 * each of them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
 * Caller must not be holding any locks that may be acquired under
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
 * zonehash_lock.  See comment at the beginning of the file for a list of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
 * common locks and their interactions with zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
zone_walk(int (*cb)(zone_t *, void *), void *data)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
	int ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
	for (zone = list_head(&zone_active); zone != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
	    zone = list_next(&zone_active, zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
		 * Skip zones that shouldn't be externally visible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
		status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
		if (status < ZONE_IS_READY || status > ZONE_IS_DOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
		 * Bail immediately if any callback invocation returns a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2808
		 * non-zero value.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2809
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2810
		ret = (*cb)(zone, data);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2811
		if (ret != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
zone_set_root(zone_t *zone, const char *upath)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
	int trycount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
	int error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
	char *path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
	struct pathname upn, pn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
	size_t pathlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
	if ((error = pn_get((char *)upath, UIO_USERSPACE, &upn)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
		return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	pn_alloc(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
	/* prevent infinite loop */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
	trycount = 10;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
		if (--trycount <= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
			error = ESTALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
		if ((error = lookuppn(&upn, &pn, FOLLOW, NULLVPP, &vp)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
			 * VOP_ACCESS() may cover 'vp' with a new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
			 * filesystem, if 'vp' is an autoFS vnode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
			 * Get the new 'vp' if so.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
			 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4888
diff changeset
  2847
			if ((error =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4888
diff changeset
  2848
			    VOP_ACCESS(vp, VEXEC, 0, CRED(), NULL)) == 0 &&
4417
01a30d05049f 6481274 zone_set_root() should not directly access private vnode field vp->v_vfsmountedhere
eh208807
parents: 4246
diff changeset
  2849
			    (!vn_ismntpt(vp) ||
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
			    (error = traverse(&vp)) == 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
				pathlen = pn.pn_pathlen + 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
				path = kmem_alloc(pathlen, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
				(void) strncpy(path, pn.pn_path,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
				    pn.pn_pathlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
				path[pathlen - 2] = '/';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
				path[pathlen - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
				pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
				pn_free(&upn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
				/* Success! */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
			VN_RELE(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
		if (error != ESTALE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
	ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
	zone->zone_rootvp = vp;		/* we hold a reference to vp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
	zone->zone_rootpath = path;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
	zone->zone_rootpathlen = pathlen;
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  2873
	if (pathlen > 5 && strcmp(path + pathlen - 5, "/lu/") == 0)
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  2874
		zone->zone_flags |= ZF_IS_SCRATCH;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
	pn_free(&pn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
	pn_free(&upn);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
#define	isalnum(c)	(((c) >= '0' && (c) <= '9') || \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
			((c) >= 'a' && (c) <= 'z') || \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
			((c) >= 'A' && (c) <= 'Z'))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
zone_set_name(zone_t *zone, const char *uname)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
	char *kname = kmem_zalloc(ZONENAME_MAX, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
	int i, err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
	if ((err = copyinstr(uname, kname, ZONENAME_MAX, &len)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
		kmem_free(kname, ZONENAME_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
		return (err);	/* EFAULT or ENAMETOOLONG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
	/* must be less than ZONENAME_MAX */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
	if (len == ZONENAME_MAX && kname[ZONENAME_MAX - 1] != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
		kmem_free(kname, ZONENAME_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	 * Name must start with an alphanumeric and must contain only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
	 * alphanumerics, '-', '_' and '.'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
	if (!isalnum(kname[0])) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
		kmem_free(kname, ZONENAME_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2913
	for (i = 1; i < len - 1; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2914
		if (!isalnum(kname[i]) && kname[i] != '-' && kname[i] != '_' &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
		    kname[i] != '.') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
			kmem_free(kname, ZONENAME_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
	zone->zone_name = kname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
/*
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2926
 * Gets the 32-bit hostid of the specified zone as an unsigned int.  If 'zonep'
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2927
 * is NULL or it points to a zone with no hostid emulation, then the machine's
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2928
 * hostid (i.e., the global zone's hostid) is returned.  This function returns
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2929
 * zero if neither the zone nor the host machine (global zone) have hostids.  It
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2930
 * returns HW_INVALID_HOSTID if the function attempts to return the machine's
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2931
 * hostid and the machine's hostid is invalid.
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2932
 */
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2933
uint32_t
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2934
zone_get_hostid(zone_t *zonep)
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2935
{
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2936
	unsigned long machine_hostid;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2937
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2938
	if (zonep == NULL || zonep->zone_hostid == HW_INVALID_HOSTID) {
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2939
		if (ddi_strtoul(hw_serial, NULL, 10, &machine_hostid) != 0)
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2940
			return (HW_INVALID_HOSTID);
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2941
		return ((uint32_t)machine_hostid);
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2942
	}
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2943
	return (zonep->zone_hostid);
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2944
}
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2945
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  2946
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
 * Similar to thread_create(), but makes sure the thread is in the appropriate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
 * zone's zsched process (curproc->p_zone->zone_zsched) before returning.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
kthread_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
zthread_create(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
    caddr_t stk,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
    size_t stksize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
    void (*proc)(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
    void *arg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
    size_t len,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
    pri_t pri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
	zone_t *zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
	proc_t *pp = zone->zone_zsched;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2964
	zone_hold(zone);	/* Reference to be dropped when thread exits */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
	 * No-one should be trying to create threads if the zone is shutting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2968
	 * down and there aren't any kernel threads around.  See comment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
	 * in zthread_exit().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2971
	ASSERT(!(zone->zone_kthreads == NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
	    zone_status_get(zone) >= ZONE_IS_EMPTY));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
	 * Create a thread, but don't let it run until we've finished setting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
	 * things up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
	t = thread_create(stk, stksize, proc, arg, len, pp, TS_STOPPED, pri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
	ASSERT(t->t_forw == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
	if (zone->zone_kthreads == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
		t->t_forw = t->t_back = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
		kthread_t *tx = zone->zone_kthreads;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2985
		t->t_forw = tx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2986
		t->t_back = tx->t_back;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
		tx->t_back->t_forw = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2988
		tx->t_back = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2989
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2990
	zone->zone_kthreads = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2991
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
	t->t_proc_flag |= TP_ZTHREAD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
	project_rele(t->t_proj);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
	t->t_proj = project_hold(pp->p_task->tk_proj);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
	 * Setup complete, let it run.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
	thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
	t->t_schedflag |= TS_ALLSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
	setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
	thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
	return (t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
 * Similar to thread_exit().  Must be called by threads created via
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
 * zthread_exit().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
zthread_exit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	zone_t *zone = pp->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
	 * Reparent to p0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
	 */
1075
5ef61094f66a 6355953 assertion failed: cpu == CPU, file: ../../i86pc/vm/hat_i86.c, line: 925
josephb
parents: 816
diff changeset
  3027
	kpreempt_disable();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
	t->t_proc_flag &= ~TP_ZTHREAD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
	t->t_procp = &p0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
	hat_thread_exit(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
	mutex_exit(&pp->p_lock);
1075
5ef61094f66a 6355953 assertion failed: cpu == CPU, file: ../../i86pc/vm/hat_i86.c, line: 925
josephb
parents: 816
diff changeset
  3033
	kpreempt_enable();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
	if (t->t_back == t) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
		ASSERT(t->t_forw == t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
		 * If the zone is empty, once the thread count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
		 * goes to zero no further kernel threads can be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
		 * created.  This is because if the creator is a process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
		 * in the zone, then it must have exited before the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
		 * state could be set to ZONE_IS_EMPTY.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
		 * Otherwise, if the creator is a kernel thread in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
		 * zone, the thread count is non-zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
		 * This really means that non-zone kernel threads should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
		 * not create zone kernel threads.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
		zone->zone_kthreads = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
		if (zone_status_get(zone) == ZONE_IS_EMPTY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
			zone_status_set(zone, ZONE_IS_DOWN);
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3052
			/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3053
			 * Remove any CPU caps on this zone.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3054
			 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3055
			cpucaps_zone_remove(zone);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
		t->t_forw->t_back = t->t_back;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
		t->t_back->t_forw = t->t_forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
		if (zone->zone_kthreads == t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
			zone->zone_kthreads = t->t_forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
	thread_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
zone_chdir(vnode_t *vp, vnode_t **vpp, proc_t *pp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
	vnode_t *oldvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
	/* we're going to hold a reference here to the directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
	VN_HOLD(vp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
11861
a63258283f8f PSARC/2009/354 Always on / no reboot Solaris Audit
Marek Pospisil <Marek.Pospisil@Sun.COM>
parents: 11850
diff changeset
  3077
	/* update abs cwd/root path see c2/audit.c */
a63258283f8f PSARC/2009/354 Always on / no reboot Solaris Audit
Marek Pospisil <Marek.Pospisil@Sun.COM>
parents: 11850
diff changeset
  3078
	if (AU_AUDITING())
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
		audit_chdirec(vp, vpp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
	oldvp = *vpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
	*vpp = vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
	if (oldvp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		VN_RELE(oldvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
 * Convert an rctl value represented by an nvlist_t into an rctl_val_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
nvlist2rctlval(nvlist_t *nvl, rctl_val_t *rv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
	nvpair_t *nvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
	boolean_t priv_set = B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
	boolean_t limit_set = B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
	boolean_t action_set = B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
		const char *name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
		uint64_t ui64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
		name = nvpair_name(nvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
		if (nvpair_type(nvp) != DATA_TYPE_UINT64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
		(void) nvpair_value_uint64(nvp, &ui64);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
		if (strcmp(name, "privilege") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
			 * Currently only privileged values are allowed, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
			 * this may change in the future.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
			if (ui64 != RCPRIV_PRIVILEGED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
			rv->rcv_privilege = ui64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
			priv_set = B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
		} else if (strcmp(name, "limit") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
			rv->rcv_value = ui64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
			limit_set = B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
		} else if (strcmp(name, "action") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
			if (ui64 != RCTL_LOCAL_NOACTION &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
			    ui64 != RCTL_LOCAL_DENY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
				return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
			rv->rcv_flagaction = ui64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
			action_set = B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
	if (!(priv_set && limit_set && action_set))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	rv->rcv_action_signal = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
	rv->rcv_action_recipient = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
	rv->rcv_action_recip_pid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
	rv->rcv_firing_time = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3141
/*
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3142
 * Non-global zone version of start_init.
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3143
 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
void
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3145
zone_start_init(void)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	proc_t *p = ttoproc(curthread);
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3148
	zone_t *z = p->p_zone;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3149
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3150
	ASSERT(!INGLOBALZONE(curproc));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
	/*
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3153
	 * For all purposes (ZONE_ATTR_INITPID and restart_init),
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3154
	 * storing just the pid of init is sufficient.
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3155
	 */
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3156
	z->zone_proc_initpid = p->p_pid;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3157
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3158
	/*
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3159
	 * We maintain zone_boot_err so that we can return the cause of the
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3160
	 * failure back to the caller of the zone_boot syscall.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
	 */
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3162
	p->p_zone->zone_boot_err = start_init_common();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3164
	/*
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3165
	 * We will prevent booting zones from becoming running zones if the
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3166
	 * global zone is shutting down.
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3167
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
	mutex_enter(&zone_status_lock);
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3169
	if (z->zone_boot_err != 0 || zone_status_get(global_zone) >=
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  3170
	    ZONE_IS_SHUTTING_DOWN) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
		 * Make sure we are still in the booting state-- we could have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
		 * raced and already be shutting down, or even further along.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
		 */
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3175
		if (zone_status_get(z) == ZONE_IS_BOOTING) {
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3176
			zone_status_set(z, ZONE_IS_SHUTTING_DOWN);
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  3177
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
		/* It's gone bad, dispose of the process */
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3180
		if (proc_exit(CLD_EXITED, z->zone_boot_err) != 0) {
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
  3181
			mutex_enter(&p->p_lock);
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 0
diff changeset
  3182
			ASSERT(p->p_flag & SEXITLWPS);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
			lwp_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
	} else {
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3186
		if (zone_status_get(z) == ZONE_IS_BOOTING)
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3187
			zone_status_set(z, ZONE_IS_RUNNING);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
		/* cause the process to return to userland. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
		lwp_rtt();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
struct zsched_arg {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
	nvlist_t *nvlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
 * Per-zone "sched" workalike.  The similarity to "sched" doesn't have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
 * anything to do with scheduling, but rather with the fact that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
 * per-zone kernel threads are parented to zsched, just like regular
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
 * kernel threads are parented to sched (p0).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
 * zsched is also responsible for launching init for the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
zsched(void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
	struct zsched_arg *za = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
	proc_t *initp = proc_init;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
	zone_t *zone = za->zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
	cred_t *cr, *oldcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
	rctl_set_t *set;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
	rctl_alloc_gp_t *gp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
	contract_t *ct = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
	task_t *tk, *oldtk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
	rctl_entity_p_t e;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
	kproject_t *pj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
	nvlist_t *nvl = za->nvlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
	nvpair_t *nvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 3247
diff changeset
  3225
	bcopy("zsched", PTOU(pp)->u_psargs, sizeof ("zsched"));
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 3247
diff changeset
  3226
	bcopy("zsched", PTOU(pp)->u_comm, sizeof ("zsched"));
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 3247
diff changeset
  3227
	PTOU(pp)->u_argc = 0;
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 3247
diff changeset
  3228
	PTOU(pp)->u_argv = NULL;
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 3247
diff changeset
  3229
	PTOU(pp)->u_envp = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
	closeall(P_FINFO(pp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
	 * We are this zone's "zsched" process.  As the zone isn't generally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	 * visible yet we don't need to grab any locks before initializing its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
	 * zone_proc pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	zone_hold(zone);  /* this hold is released by zone_destroy() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
	zone->zone_zsched = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
	pp->p_zone = zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
	 * Disassociate process from its 'parent'; parent ourselves to init
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
	 * (pid 1) and change other values as needed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
	sess_create();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
	proc_detach(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	pp->p_ppid = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	pp->p_flag |= SZONETOP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	pp->p_ancpid = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	pp->p_parent = initp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
	pp->p_psibling = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
	if (initp->p_child)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
		initp->p_child->p_psibling = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	pp->p_sibling = initp->p_child;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
	initp->p_child = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
	/* Decrement what newproc() incremented. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
	upcount_dec(crgetruid(CRED()), GLOBAL_ZONEID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
	 * Our credentials are about to become kcred-like, so we don't care
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
	 * about the caller's ruid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
	upcount_inc(crgetruid(kcred), zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
	 * getting out of global zone, so decrement lwp counts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
	pj = pp->p_task->tk_proj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
	mutex_enter(&global_zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
	pj->kpj_nlwps -= pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
	global_zone->zone_nlwps -= pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
	mutex_exit(&global_zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
	/*
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3280
	 * Decrement locked memory counts on old zone and project.
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3281
	 */
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3282
	mutex_enter(&global_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3283
	global_zone->zone_locked_mem -= pp->p_locked_mem;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3284
	pj->kpj_data.kpd_locked_mem -= pp->p_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3285
	mutex_exit(&global_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3286
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3287
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
	 * Create and join a new task in project '0' of this zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
	 * We don't need to call holdlwps() since we know we're the only lwp in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
	 * this process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
	 * task_join() returns with p_lock held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
	tk = task_create(0, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
	oldtk = task_join(tk, 0);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3298
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3299
	pj = pp->p_task->tk_proj;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3300
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3301
	mutex_enter(&zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3302
	zone->zone_locked_mem += pp->p_locked_mem;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3303
	pj->kpj_data.kpd_locked_mem += pp->p_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3304
	mutex_exit(&zone->zone_mem_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
	 * add lwp counts to zsched's zone, and increment project's task count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
	 * due to the task created in the above tasksys_settaskid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
	 */
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3310
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
	mutex_enter(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
	pj->kpj_nlwps += pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
	pj->kpj_ntasks += 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
	zone->zone_nlwps += pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
	mutex_exit(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3317
	mutex_exit(&curproc->p_lock);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3318
	mutex_exit(&cpu_lock);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3319
	task_rele(oldtk);
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3320
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
	 * The process was created by a process in the global zone, hence the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
	 * credentials are wrong.  We might as well have kcred-ish credentials.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
	cr = zone->zone_kcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
	crhold(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
	mutex_enter(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
	oldcred = pp->p_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
	pp->p_cred = cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
	mutex_exit(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
	crfree(oldcred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
	 * Hold credentials again (for thread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
	crhold(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
	 * p_lwpcnt can't change since this is a kernel process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
	crset(pp, cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
	 * Chroot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
	zone_chdir(zone->zone_rootvp, &PTOU(pp)->u_cdir, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
	zone_chdir(zone->zone_rootvp, &PTOU(pp)->u_rdir, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
	 * Initialize zone's rctl set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
	set = rctl_set_create();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
	gp = rctl_set_init_prealloc(RCENTITY_ZONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
	e.rcep_p.zone = zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
	e.rcep_t = RCENTITY_ZONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
	zone->zone_rctls = rctl_set_init(RCENTITY_ZONE, pp, &e, set, gp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
	rctl_prealloc_destroy(gp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
	 * Apply the rctls passed in to zone_create().  This is basically a list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
	 * assignment: all of the old values are removed and the new ones
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
	 * inserted.  That is, if an empty list is passed in, all values are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
	 * removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
		rctl_dict_entry_t *rde;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
		rctl_hndl_t hndl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
		char *name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
		nvlist_t **nvlarray;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
		uint_t i, nelem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
		int error;	/* For ASSERT()s */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
		name = nvpair_name(nvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
		hndl = rctl_hndl_lookup(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
		ASSERT(hndl != -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
		rde = rctl_dict_lookup_hndl(hndl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
		ASSERT(rde != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
		for (; /* ever */; ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
			rctl_val_t oval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
			mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
			error = rctl_local_get(hndl, NULL, &oval, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
			mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
			ASSERT(error == 0);	/* Can't fail for RCTL_FIRST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
			ASSERT(oval.rcv_privilege != RCPRIV_BASIC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
			if (oval.rcv_privilege == RCPRIV_SYSTEM)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
			mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
			error = rctl_local_delete(hndl, &oval, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
			mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
			ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
		error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
		ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
		for (i = 0; i < nelem; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
			rctl_val_t *nvalp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
			nvalp = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
			error = nvlist2rctlval(nvlarray[i], nvalp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
			ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
			 * rctl_local_insert can fail if the value being
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
			 * inserted is a duplicate; this is OK.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
			mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
			if (rctl_local_insert(hndl, nvalp, pp) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
				kmem_cache_free(rctl_val_cache, nvalp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
			mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
	 * Tell the world that we're done setting up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
	 *
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3417
	 * At this point we want to set the zone status to ZONE_IS_INITIALIZED
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
	 * and atomically set the zone's processor set visibility.  Once
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
	 * we drop pool_lock() this zone will automatically get updated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
	 * to reflect any future changes to the pools configuration.
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3421
	 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3422
	 * Note that after we drop the locks below (zonehash_lock in
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3423
	 * particular) other operations such as a zone_getattr call can
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3424
	 * now proceed and observe the zone. That is the reason for doing a
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3425
	 * state transition to the INITIALIZED state.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
	pool_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
	zone_uniqid(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
	zone_zsd_configure(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
	if (pool_state == POOL_ENABLED)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
		zone_pset_set(zone, pool_default->pool_pset->pset_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
	ASSERT(zone_status_get(zone) == ZONE_IS_UNINITIALIZED);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3436
	zone_status_set(zone, ZONE_IS_INITIALIZED);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3442
	/* Now call the create callback for this key */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3443
	zsd_apply_all_keys(zsd_apply_create, zone);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3444
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3445
	/* The callbacks are complete. Mark ZONE_IS_READY */
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3446
	mutex_enter(&zone_status_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3447
	ASSERT(zone_status_get(zone) == ZONE_IS_INITIALIZED);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3448
	zone_status_set(zone, ZONE_IS_READY);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3449
	mutex_exit(&zone_status_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  3450
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
	 * Once we see the zone transition to the ZONE_IS_BOOTING state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	 * we launch init, and set the state to running.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	zone_status_wait_cpr(zone, ZONE_IS_BOOTING, "zsched");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
	if (zone_status_get(zone) == ZONE_IS_BOOTING) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
		id_t cid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
		 * Ok, this is a little complicated.  We need to grab the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
		 * zone's pool's scheduling class ID; note that by now, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
		 * are already bound to a pool if we need to be (zoneadmd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
		 * will have done that to us while we're in the READY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
		 * state).  *But* the scheduling class for the zone's 'init'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
		 * must be explicitly passed to newproc, which doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
		 * respect pool bindings.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
		 * We hold the pool_lock across the call to newproc() to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
		 * close the obvious race: the pool's scheduling class
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
		 * could change before we manage to create the LWP with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
		 * classid 'cid'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
		pool_lock();
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3475
		if (zone->zone_defaultcid > 0)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3476
			cid = zone->zone_defaultcid;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3477
		else
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3478
			cid = pool_get_class(zone->zone_pool);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
		if (cid == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
			cid = defaultcid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
		 * If this fails, zone_boot will ultimately fail.  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
		 * state of the zone will be set to SHUTTING_DOWN-- userland
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
		 * will have to tear down the zone, and fail, or try again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
		 */
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3487
		if ((zone->zone_boot_err = newproc(zone_start_init, NULL, cid,
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
  3488
		    minclsyspri - 1, &ct, 0)) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
			mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
			zone_status_set(zone, ZONE_IS_SHUTTING_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
			mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
	 * Wait for zone_destroy() to be called.  This is what we spend
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
	 * most of our life doing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
	zone_status_wait_cpr(zone, ZONE_IS_DYING, "zsched");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
	if (ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
		 * At this point the process contract should be empty.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
		 * (Though if it isn't, it's not the end of the world.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
		VERIFY(contract_abandon(ct, curproc, B_TRUE) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
	 * Allow kcred to be freed when all referring processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
	 * (including this one) go away.  We can't just do this in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
	 * zone_free because we need to wait for the zone_cred_ref to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
	 * drop to 0 before calling zone_free, and the existence of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
	 * zone_kcred will prevent that.  Thus, we call crfree here to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
	 * balance the crdup in zone_create.  The crhold calls earlier
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
	 * in zsched will be dropped when the thread and process exit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
	crfree(zone->zone_kcred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
	zone->zone_kcred = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
	exit(CLD_EXITED, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
 * Helper function to determine if there are any submounts of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
 * provided path.  Used to make sure the zone doesn't "inherit" any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
 * mounts from before it is created.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
static uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
zone_mount_count(const char *rootpath)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
	vfs_t *vfsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
	uint_t count = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
	size_t rootpathlen = strlen(rootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
	 * Holding zonehash_lock prevents race conditions with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
	 * vfs_list_add()/vfs_list_remove() since we serialize with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
	 * zone_find_by_path().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
	 * The rootpath must end with a '/'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
	ASSERT(rootpath[rootpathlen - 1] == '/');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
	 * This intentionally does not count the rootpath itself if that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
	 * happens to be a mount point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
	vfs_list_read_lock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
	vfsp = rootvfs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
		if (strncmp(rootpath, refstr_value(vfsp->vfs_mntpt),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
		    rootpathlen) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
			count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
		vfsp = vfsp->vfs_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
	} while (vfsp != rootvfs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
	vfs_list_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
	return (count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
 * Helper function to make sure that a zone created on 'rootpath'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
 * wouldn't end up containing other zones' rootpaths.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
static boolean_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
zone_is_nested(const char *rootpath)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
	size_t rootpathlen = strlen(rootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
	size_t len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
	ASSERT(MUTEX_HELD(&zonehash_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
8799
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3576
	/*
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3577
	 * zone_set_root() appended '/' and '\0' at the end of rootpath
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3578
	 */
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3579
	if ((rootpathlen <= 3) && (rootpath[0] == '/') &&
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3580
	    (rootpath[1] == '/') && (rootpath[2] == '\0'))
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3581
		return (B_TRUE);
bfcc15b6df34 5084037 zone_create(2) succeeds in creating new zone if global zone root path is passed.
Dhanaraj M <Dhanaraj.M@Sun.COM>
parents: 8662
diff changeset
  3582
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
	for (zone = list_head(&zone_active); zone != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
	    zone = list_next(&zone_active, zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
		if (zone == global_zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
		len = strlen(zone->zone_rootpath);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
		if (strncmp(rootpath, zone->zone_rootpath,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
		    MIN(rootpathlen, len)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
			return (B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
	return (B_FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
static int
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3596
zone_set_privset(zone_t *zone, const priv_set_t *zone_privs,
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3597
    size_t zone_privssz)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
	priv_set_t *privs = kmem_alloc(sizeof (priv_set_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3601
	if (zone_privssz < sizeof (priv_set_t))
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3602
		return (set_errno(ENOMEM));
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3603
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
	if (copyin(zone_privs, privs, sizeof (priv_set_t))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
		kmem_free(privs, sizeof (priv_set_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
		return (EFAULT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
	zone->zone_privset = privs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
 * We make creative use of nvlists to pass in rctls from userland.  The list is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
 * a list of the following structures:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
 * (name = rctl_name, value = nvpair_list_array)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
 * Where each element of the nvpair_list_array is of the form:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
 * [(name = "privilege", value = RCPRIV_PRIVILEGED),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
 * 	(name = "limit", value = uint64_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
 * 	(name = "action", value = (RCTL_LOCAL_NOACTION || RCTL_LOCAL_DENY))]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
parse_rctls(caddr_t ubuf, size_t buflen, nvlist_t **nvlp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
	nvpair_t *nvp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
	nvlist_t *nvl = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
	char *kbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
	rctl_val_t rv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
	*nvlp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
	if (buflen == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
	if ((kbuf = kmem_alloc(buflen, KM_NOSLEEP)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
		return (ENOMEM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
	if (copyin(ubuf, kbuf, buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
	if (nvlist_unpack(kbuf, buflen, &nvl, KM_SLEEP) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
		 * nvl may have been allocated/free'd, but the value set to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
		 * non-NULL, so we reset it here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
		nvl = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
		rctl_dict_entry_t *rde;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
		rctl_hndl_t hndl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
		nvlist_t **nvlarray;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
		uint_t i, nelem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
		char *name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
		name = nvpair_name(nvp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
		if (strncmp(nvpair_name(nvp), "zone.", sizeof ("zone.") - 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
		    != 0 || nvpair_type(nvp) != DATA_TYPE_NVLIST_ARRAY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
		if ((hndl = rctl_hndl_lookup(name)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
		rde = rctl_dict_lookup_hndl(hndl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
		error = nvpair_value_nvlist_array(nvp, &nvlarray, &nelem);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
		ASSERT(error == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
		for (i = 0; i < nelem; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
			if (error = nvlist2rctlval(nvlarray[i], &rv))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
		if (rctl_invalid_value(rde, &rv)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
			error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
	error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
	*nvlp = nvl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
	kmem_free(kbuf, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
	if (error && nvl != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
		nvlist_free(nvl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
zone_create_error(int er_error, int er_ext, int *er_out) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
	if (er_out != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
		if (copyout(&er_ext, er_out, sizeof (int))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
	return (set_errno(er_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3701
static int
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3702
zone_set_label(zone_t *zone, const bslabel_t *lab, uint32_t doi)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3703
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3704
	ts_label_t *tsl;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3705
	bslabel_t blab;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3706
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3707
	/* Get label from user */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3708
	if (copyin(lab, &blab, sizeof (blab)) != 0)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3709
		return (EFAULT);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3710
	tsl = labelalloc(&blab, doi, KM_NOSLEEP);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3711
	if (tsl == NULL)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3712
		return (ENOMEM);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3713
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3714
	zone->zone_slabel = tsl;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3715
	return (0);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3716
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3717
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3719
 * Parses a comma-separated list of ZFS datasets into a per-zone dictionary.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3720
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3721
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3722
parse_zfs(zone_t *zone, caddr_t ubuf, size_t buflen)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3723
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3724
	char *kbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3725
	char *dataset, *next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3726
	zone_dataset_t *zd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3727
	size_t len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3728
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3729
	if (ubuf == NULL || buflen == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3730
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3732
	if ((kbuf = kmem_alloc(buflen, KM_NOSLEEP)) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3733
		return (ENOMEM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3734
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3735
	if (copyin(ubuf, kbuf, buflen) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3736
		kmem_free(kbuf, buflen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3737
		return (EFAULT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3738
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3739
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3740
	dataset = next = kbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3741
	for (;;) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3742
		zd = kmem_alloc(sizeof (zone_dataset_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3743
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3744
		next = strchr(dataset, ',');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3745
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3746
		if (next == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3747
			len = strlen(dataset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3748
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3749
			len = next - dataset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3750
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3751
		zd->zd_dataset = kmem_alloc(len + 1, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3752
		bcopy(dataset, zd->zd_dataset, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3753
		zd->zd_dataset[len] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3754
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3755
		list_insert_head(&zone->zone_datasets, zd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3756
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3757
		if (next == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3758
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3759
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3760
		dataset = next + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3761
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3762
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3763
	kmem_free(kbuf, buflen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3764
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3765
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3766
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3767
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
 * System call to create/initialize a new zone named 'zone_name', rooted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
 * at 'zone_root', with a zone-wide privilege limit set of 'zone_privs',
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3770
 * and initialized with the zone-wide rctls described in 'rctlbuf', and
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3771
 * with labeling set by 'match', 'doi', and 'label'.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
 * If extended error is non-null, we may use it to return more detailed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
 * error information.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
static zoneid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
zone_create(const char *zone_name, const char *zone_root,
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3778
    const priv_set_t *zone_privs, size_t zone_privssz,
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3779
    caddr_t rctlbuf, size_t rctlbufsz,
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3780
    caddr_t zfsbuf, size_t zfsbufsz, int *extended_error,
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3781
    int match, uint32_t doi, const bslabel_t *label,
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3782
    int flags)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
	struct zsched_arg zarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
	nvlist_t *rctls = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
	zone_t *zone, *ztmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
	int error2 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
	char *str;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
	cred_t *zkcr;
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  3793
	boolean_t insert_label_hash;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
	if (secpolicy_zone_config(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
	/* can't boot zone from within chroot environment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
	if (PTOU(pp)->u_rdir != NULL && PTOU(pp)->u_rdir != rootdir)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
		return (zone_create_error(ENOTSUP, ZE_CHROOTED,
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3801
		    extended_error));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
	zone = kmem_zalloc(sizeof (zone_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
	zoneid = zone->zone_id = id_alloc(zoneid_space);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
	zone->zone_status = ZONE_IS_UNINITIALIZED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
	zone->zone_pool = pool_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
	zone->zone_pool_mod = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
	zone->zone_psetid = ZONE_PS_INVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
	zone->zone_ncpus = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
	zone->zone_ncpus_online = 0;
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3811
	zone->zone_restart_init = B_TRUE;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3812
	zone->zone_brand = &native_brand;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  3813
	zone->zone_initname = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
	mutex_init(&zone->zone_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
	mutex_init(&zone->zone_nlwps_lock, NULL, MUTEX_DEFAULT, NULL);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3816
	mutex_init(&zone->zone_mem_lock, NULL, MUTEX_DEFAULT, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
	cv_init(&zone->zone_cv, NULL, CV_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
	list_create(&zone->zone_zsd, sizeof (struct zsd_entry),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
	    offsetof(struct zsd_entry, zsd_linkage));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3820
	list_create(&zone->zone_datasets, sizeof (zone_dataset_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3821
	    offsetof(zone_dataset_t, zd_linkage));
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  3822
	list_create(&zone->zone_dl_list, sizeof (zone_dl_t),
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  3823
	    offsetof(zone_dl_t, zdl_linkage));
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3824
	rw_init(&zone->zone_mlps.mlpl_rwlock, NULL, RW_DEFAULT, NULL);
10910
951a65b3846b PSARC/2009/566 Provide minor private interface modifications to support mntfs
Robert Harris <Robert.Harris@Sun.COM>
parents: 10865
diff changeset
  3825
	rw_init(&zone->zone_mntfs_db_lock, NULL, RW_DEFAULT, NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3827
	if (flags & ZCF_NET_EXCL) {
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3828
		zone->zone_flags |= ZF_NET_EXCL;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3829
	}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  3830
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
	if ((error = zone_set_name(zone, zone_name)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3833
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
	if ((error = zone_set_root(zone, zone_root)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
	}
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  3840
	if ((error = zone_set_privset(zone, zone_privs, zone_privssz)) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3844
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
	/* initialize node name to be the same as zone name */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
	zone->zone_nodename = kmem_alloc(_SYS_NMLN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
	(void) strncpy(zone->zone_nodename, zone->zone_name, _SYS_NMLN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
	zone->zone_nodename[_SYS_NMLN - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
	zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
	zone->zone_domain[0] = '\0';
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  3852
	zone->zone_hostid = HW_INVALID_HOSTID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
	zone->zone_shares = 1;
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  3854
	zone->zone_shmmax = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  3855
	zone->zone_ipc.ipcq_shmmni = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  3856
	zone->zone_ipc.ipcq_semmni = 0;
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  3857
	zone->zone_ipc.ipcq_msgmni = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
	zone->zone_bootargs = NULL;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3859
	zone->zone_initname =
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3860
	    kmem_alloc(strlen(zone_default_initname) + 1, KM_SLEEP);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  3861
	(void) strcpy(zone->zone_initname, zone_default_initname);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3862
	zone->zone_nlwps = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3863
	zone->zone_nlwps_ctl = INT_MAX;
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3864
	zone->zone_locked_mem = 0;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  3865
	zone->zone_locked_mem_ctl = UINT64_MAX;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3866
	zone->zone_max_swap = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3867
	zone->zone_max_swap_ctl = UINT64_MAX;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3868
	zone0.zone_lockedmem_kstat = NULL;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  3869
	zone0.zone_swapresv_kstat = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
	 * Zsched initializes the rctls.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
	zone->zone_rctls = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
	if ((error = parse_rctls(rctlbuf, rctlbufsz, &rctls)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3881
	if ((error = parse_zfs(zone, zfsbuf, zfsbufsz)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3882
		zone_free(zone);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3883
		return (set_errno(error));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3884
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  3885
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
	/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3887
	 * Read in the trusted system parameters:
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3888
	 * match flag and sensitivity label.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3889
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3890
	zone->zone_match = match;
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  3891
	if (is_system_labeled() && !(zone->zone_flags & ZF_IS_SCRATCH)) {
4462
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3892
		/* Fail if requested to set doi to anything but system's doi */
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3893
		if (doi != 0 && doi != default_doi) {
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3894
			zone_free(zone);
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3895
			return (set_errno(EINVAL));
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3896
		}
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3897
		/* Always apply system's doi to the zone */
072b1d6f0ba2 CR 6507344 TX zones should not hard code DOI to 1
kp158701
parents: 4417
diff changeset
  3898
		error = zone_set_label(zone, label, default_doi);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3899
		if (error != 0) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3900
			zone_free(zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3901
			return (set_errno(error));
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3902
		}
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  3903
		insert_label_hash = B_TRUE;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3904
	} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3905
		/* all zones get an admin_low label if system is not labeled */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3906
		zone->zone_slabel = l_admin_low;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3907
		label_hold(l_admin_low);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  3908
		insert_label_hash = B_FALSE;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3909
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3910
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3911
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
	 * Stop all lwps since that's what normally happens as part of fork().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
	 * This needs to happen before we grab any locks to avoid deadlock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
	 * (another lwp in the process could be waiting for the held lock).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
	if (curthread != pp->p_agenttp && !holdlwps(SHOLDFORK)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
		if (rctls)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
			nvlist_free(rctls);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
	if (block_mounts() == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
		mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
		if (curthread != pp->p_agenttp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
			continuelwps(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
		zone_free(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
		if (rctls)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
			nvlist_free(rctls);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
		return (zone_create_error(error, 0, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
	 * Set up credential for kernel access.  After this, any errors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
	 * should go through the dance in errout rather than calling
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
	 * zone_free directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
	zone->zone_kcred = crdup(kcred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
	crsetzone(zone->zone_kcred, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
	priv_intersect(zone->zone_privset, &CR_PPRIV(zone->zone_kcred));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
	priv_intersect(zone->zone_privset, &CR_EPRIV(zone->zone_kcred));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
	priv_intersect(zone->zone_privset, &CR_IPRIV(zone->zone_kcred));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
	priv_intersect(zone->zone_privset, &CR_LPRIV(zone->zone_kcred));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
	 * Make sure zone doesn't already exist.
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3949
	 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3950
	 * If the system and zone are labeled,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3951
	 * make sure no other zone exists that has the same label.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
	 */
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3953
	if ((ztmp = zone_find_all_by_name(zone->zone_name)) != NULL ||
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  3954
	    (insert_label_hash &&
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  3955
	    (ztmp = zone_find_all_by_label(zone->zone_slabel)) != NULL)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
		zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
		status = zone_status_get(ztmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
		if (status == ZONE_IS_READY || status == ZONE_IS_RUNNING)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
			error = EEXIST;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
			error = EBUSY;
4791
4ee10afd3f9c 6504809 Misleading zoneadm message "zone_create failed: File exists"
ton
parents: 4664
diff changeset
  3963
4ee10afd3f9c 6504809 Misleading zoneadm message "zone_create failed: File exists"
ton
parents: 4664
diff changeset
  3964
		if (insert_label_hash)
4ee10afd3f9c 6504809 Misleading zoneadm message "zone_create failed: File exists"
ton
parents: 4664
diff changeset
  3965
			error2 = ZE_LABELINUSE;
4ee10afd3f9c 6504809 Misleading zoneadm message "zone_create failed: File exists"
ton
parents: 4664
diff changeset
  3966
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
	 * Don't allow zone creations which would cause one zone's rootpath to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
	 * be accessible from that of another (non-global) zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
	if (zone_is_nested(zone->zone_rootpath)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
		error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
	ASSERT(zonecount != 0);		/* check for leaks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
	if (zonecount + 1 > maxzones) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
		error = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
	if (zone_mount_count(zone->zone_rootpath) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
		error = EBUSY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
		error2 = ZE_AREMOUNTS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
	 * Zone is still incomplete, but we need to drop all locks while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
	 * zsched() initializes this zone's kernel process.  We
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
	 * optimistically add the zone to the hashtable and associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
	 * lists so a parallel zone_create() doesn't try to create the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
	 * same zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
	zonecount++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
	(void) mod_hash_insert(zonehashbyid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
	    (mod_hash_key_t)(uintptr_t)zone->zone_id,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
	    (mod_hash_val_t)(uintptr_t)zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
	str = kmem_alloc(strlen(zone->zone_name) + 1, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
	(void) strcpy(str, zone->zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
	(void) mod_hash_insert(zonehashbyname, (mod_hash_key_t)str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
	    (mod_hash_val_t)(uintptr_t)zone);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  4006
	if (insert_label_hash) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4007
		(void) mod_hash_insert(zonehashbylabel,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4008
		    (mod_hash_key_t)zone->zone_slabel, (mod_hash_val_t)zone);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  4009
		zone->zone_flags |= ZF_HASHED_LABEL;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4010
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4011
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
	 * Insert into active list.  At this point there are no 'hold's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
	 * on the zone, but everyone else knows not to use it, so we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
	 * continue to use it.  zsched() will do a zone_hold() if the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4016
	 * newproc() is successful.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4018
	list_insert_tail(&zone_active, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4019
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4021
	zarg.zone = zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
	zarg.nvlist = rctls;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
	 * The process, task, and project rctls are probably wrong;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
	 * we need an interface to get the default values of all rctls,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
	 * and initialize zsched appropriately.  I'm not sure that that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
	 * makes much of a difference, though.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
	 */
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
  4029
	error = newproc(zsched, (void *)&zarg, syscid, minclsyspri, NULL, 0);
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
  4030
	if (error != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
		 * We need to undo all globally visible state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
		mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
		list_remove(&zone_active, zone);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  4036
		if (zone->zone_flags & ZF_HASHED_LABEL) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4037
			ASSERT(zone->zone_slabel != NULL);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4038
			(void) mod_hash_destroy(zonehashbylabel,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4039
			    (mod_hash_key_t)zone->zone_slabel);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4040
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
		(void) mod_hash_destroy(zonehashbyname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4042
		    (mod_hash_key_t)(uintptr_t)zone->zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
		(void) mod_hash_destroy(zonehashbyid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
		    (mod_hash_key_t)(uintptr_t)zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4045
		ASSERT(zonecount > 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4046
		zonecount--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4047
		goto errout;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4048
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4049
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4050
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4051
	 * Zone creation can't fail from now on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4052
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4053
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4054
	/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4055
	 * Create zone kstats
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4056
	 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4057
	zone_kstat_create(zone);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4058
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4059
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
	 * Let the other lwps continue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
	if (curthread != pp->p_agenttp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4064
		continuelwps(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4066
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
	 * Wait for zsched to finish initializing the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4070
	zone_status_wait(zone, ZONE_IS_READY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4071
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
	 * The zone is fully visible, so we can let mounts progress.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4073
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
	resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
	if (rctls)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
		nvlist_free(rctls);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
	return (zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4080
errout:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4081
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4083
	 * Let the other lwps continue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
	if (curthread != pp->p_agenttp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
		continuelwps(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4089
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
	resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4091
	if (rctls)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4092
		nvlist_free(rctls);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
	 * There is currently one reference to the zone, a cred_ref from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
	 * zone_kcred.  To free the zone, we call crfree, which will call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
	 * zone_cred_rele, which will call zone_free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
	ASSERT(zone->zone_cred_ref == 1);	/* for zone_kcred */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
	ASSERT(zone->zone_kcred->cr_ref == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
	ASSERT(zone->zone_ref == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
	zkcr = zone->zone_kcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
	zone->zone_kcred = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
	crfree(zkcr);				/* triggers call to zone_free */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
	return (zone_create_error(error, error2, extended_error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
 * Cause the zone to boot.  This is pretty simple, since we let zoneadmd do
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4109
 * the heavy lifting.  initname is the path to the program to launch
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4110
 * at the "top" of the zone; if this is NULL, we use the system default,
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4111
 * which is stored at zone_default_initname.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
static int
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4114
zone_boot(zoneid_t zoneid)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4116
	int err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4117
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
	if (secpolicy_zone_config(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
	if (zoneid < MIN_USERZONEID || zoneid > MAX_ZONEID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4125
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4126
	 * Look for zone under hash lock to prevent races with calls to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4127
	 * zone_shutdown, zone_destroy, etc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4128
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4134
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4135
	if (zone_status_get(zone) != ZONE_IS_READY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4139
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4140
	zone_status_set(zone, ZONE_IS_BOOTING);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
	zone_hold(zone);	/* so we can use the zone_t later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
	if (zone_status_wait_sig(zone, ZONE_IS_RUNNING) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
		return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
	 * Boot (starting init) might have failed, in which case the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
	 * will go to the SHUTTING_DOWN state; an appropriate errno will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
	 * be placed in zone->zone_boot_err, and so we return that.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
	err = zone->zone_boot_err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
	return (err ? set_errno(err) : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
 * Kills all user processes in the zone, waiting for them all to exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
 * before returning.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4164
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
zone_empty(zone_t *zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
	int waitstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
	 * We need to drop zonehash_lock before killing all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
	 * processes, otherwise we'll deadlock with zone_find_*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4173
	 * which can be called from the exit path.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4174
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4175
	ASSERT(MUTEX_NOT_HELD(&zonehash_lock));
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 10910
diff changeset
  4176
	while ((waitstatus = zone_status_timedwait_sig(zone,
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 10910
diff changeset
  4177
	    ddi_get_lbolt() + hz, ZONE_IS_EMPTY)) == -1) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4178
		killall(zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4179
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4180
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4181
	 * return EINTR if we were signaled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4182
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4183
	if (waitstatus == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4184
		return (EINTR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4185
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4186
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4188
/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4189
 * This function implements the policy for zone visibility.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4190
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4191
 * In standard Solaris, a non-global zone can only see itself.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4192
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4193
 * In Trusted Extensions, a labeled zone can lookup any zone whose label
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4194
 * it dominates. For this test, the label of the global zone is treated as
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4195
 * admin_high so it is special-cased instead of being checked for dominance.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4196
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4197
 * Returns true if zone attributes are viewable, false otherwise.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4198
 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4199
static boolean_t
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4200
zone_list_access(zone_t *zone)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4201
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4202
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4203
	if (curproc->p_zone == global_zone ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4204
	    curproc->p_zone == zone) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4205
		return (B_TRUE);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  4206
	} else if (is_system_labeled() && !(zone->zone_flags & ZF_IS_SCRATCH)) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4207
		bslabel_t *curproc_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4208
		bslabel_t *zone_label;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4209
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4210
		curproc_label = label2bslabel(curproc->p_zone->zone_slabel);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4211
		zone_label = label2bslabel(zone->zone_slabel);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4212
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4213
		if (zone->zone_id != GLOBAL_ZONEID &&
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4214
		    bldominates(curproc_label, zone_label)) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4215
			return (B_TRUE);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4216
		} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4217
			return (B_FALSE);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4218
		}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4219
	} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4220
		return (B_FALSE);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4221
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4222
}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4223
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4224
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4225
 * Systemcall to start the zone's halt sequence.  By the time this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4226
 * function successfully returns, all user processes and kernel threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
 * executing in it will have exited, ZSD shutdown callbacks executed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4228
 * and the zone status set to ZONE_IS_DOWN.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4229
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4230
 * It is possible that the call will interrupt itself if the caller is the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4231
 * parent of any process running in the zone, and doesn't have SIGCHLD blocked.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4233
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
zone_shutdown(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
	if (secpolicy_zone_config(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
	if (zoneid < MIN_USERZONEID || zoneid > MAX_ZONEID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
	 * Block mounts so that VFS_MOUNT() can get an accurate view of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4247
	 * the zone's status with regards to ZONE_IS_SHUTTING down.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
	 * e.g. NFS can fail the mount if it determines that the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
	 * has already begun the shutdown sequence.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
	if (block_mounts() == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4253
		return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4254
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4255
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4256
	 * Look for zone under hash lock to prevent races with other
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
	 * calls to zone_shutdown and zone_destroy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4260
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
		resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4262
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4263
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4264
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4265
	status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4266
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4267
	 * Fail if the zone isn't fully initialized yet.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4268
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4269
	if (status < ZONE_IS_READY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4270
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4271
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4272
		resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4273
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4274
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4275
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4276
	 * If conditions required for zone_shutdown() to return have been met,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4277
	 * return success.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4278
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4279
	if (status >= ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4280
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4281
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4282
		resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4283
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4284
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4285
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4286
	 * If zone_shutdown() hasn't been called before, go through the motions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4287
	 * If it has, there's nothing to do but wait for the kernel threads to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4288
	 * drain.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4289
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4290
	if (status < ZONE_IS_EMPTY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4291
		uint_t ntasks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4293
		mutex_enter(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4294
		if ((ntasks = zone->zone_ntasks) != 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4295
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4296
			 * There's still stuff running.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4297
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4298
			zone_status_set(zone, ZONE_IS_SHUTTING_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4299
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4300
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4301
		if (ntasks == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4302
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4303
			 * The only way to create another task is through
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4304
			 * zone_enter(), which will block until we drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4305
			 * zonehash_lock.  The zone is empty.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4306
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4307
			if (zone->zone_kthreads == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4308
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4309
				 * Skip ahead to ZONE_IS_DOWN
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4310
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4311
				zone_status_set(zone, ZONE_IS_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4312
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4313
				zone_status_set(zone, ZONE_IS_EMPTY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4314
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4315
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4316
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4317
	zone_hold(zone);	/* so we can use the zone_t later */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4318
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4319
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4320
	resume_mounts();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4322
	if (error = zone_empty(zone)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4323
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4324
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4325
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
	 * After the zone status goes to ZONE_IS_DOWN this zone will no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
	 * longer be notified of changes to the pools configuration, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
	 * in order to not end up with a stale pool pointer, we point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4330
	 * ourselves at the default pool and remove all resource
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
	 * visibility.  This is especially important as the zone_t may
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
	 * languish on the deathrow for a very long time waiting for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
	 * cred's to drain out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4335
	 * This rebinding of the zone can happen multiple times
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
	 * (presumably due to interrupted or parallel systemcalls)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
	 * without any adverse effects.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
	if (pool_lock_intr() != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4340
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
		return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
	if (pool_state == POOL_ENABLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4344
		mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4345
		zone_pool_set(zone, pool_default);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
		 * The zone no longer needs to be able to see any cpus.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4349
		zone_pset_set(zone, ZONE_PS_INVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4350
		mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4352
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4354
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
	 * ZSD shutdown callbacks can be executed multiple times, hence
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4356
	 * it is safe to not be holding any locks across this call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4358
	zone_zsd_callbacks(zone, ZSD_SHUTDOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4360
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4361
	if (zone->zone_kthreads == NULL && zone_status_get(zone) < ZONE_IS_DOWN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4362
		zone_status_set(zone, ZONE_IS_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4363
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4365
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4366
	 * Wait for kernel threads to drain.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4367
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
	if (!zone_status_wait_sig(zone, ZONE_IS_DOWN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4370
		return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4371
	}
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4372
3671
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4373
	/*
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4374
	 * Zone can be become down/destroyable even if the above wait
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4375
	 * returns EINTR, so any code added here may never execute.
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4376
	 * (i.e. don't add code here)
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4377
	 */
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4378
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4379
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4380
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4381
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4383
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4384
 * Systemcall entry point to finalize the zone halt process.  The caller
2677
212d61b14a8b PSARC/2006/451 System V resource controls for Zones
ml93401
parents: 2267
diff changeset
  4385
 * must have already successfully called zone_shutdown().
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4386
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4387
 * Upon successful completion, the zone will have been fully destroyed:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4388
 * zsched will have exited, destructor callbacks executed, and the zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4389
 * removed from the list of active zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4390
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4391
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4392
zone_destroy(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4393
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
	uint64_t uniqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4395
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
	if (secpolicy_zone_config(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
	if (zoneid < MIN_USERZONEID || zoneid > MAX_ZONEID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4401
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4402
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4404
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4405
	 * Look for zone under hash lock to prevent races with other
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
	 * calls to zone_destroy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4407
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4410
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4411
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4413
	if (zone_mount_count(zone->zone_rootpath) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4414
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4415
		return (set_errno(EBUSY));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4416
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4417
	mutex_enter(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4418
	status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4419
	if (status < ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4420
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4421
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4422
		return (set_errno(EBUSY));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4423
	} else if (status == ZONE_IS_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4424
		zone_status_set(zone, ZONE_IS_DYING); /* Tell zsched to exit */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4425
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
	zone_hold(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
	 * wait for zsched to exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4432
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4433
	zone_status_wait(zone, ZONE_IS_DEAD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
	zone_zsd_callbacks(zone, ZSD_DESTROY);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4435
	zone->zone_netstack = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4436
	uniqid = zone->zone_uniqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
	zone = NULL;	/* potentially free'd */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4440
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4441
	for (; /* ever */; ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4442
		boolean_t unref;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4444
		if ((zone = zone_find_all_by_id(zoneid)) == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
		    zone->zone_uniqid != uniqid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4446
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4447
			 * The zone has gone away.  Necessary conditions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
			 * are met, so we return success.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4449
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
			mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
		mutex_enter(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
		unref = ZONE_IS_UNREF(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4455
		mutex_exit(&zone->zone_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4456
		if (unref) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4458
			 * There is only one reference to the zone -- that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
			 * added when the zone was added to the hashtables --
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
			 * and things will remain this way until we drop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
			 * zonehash_lock... we can go ahead and cleanup the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
			 * zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4463
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4464
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4465
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4467
		if (cv_wait_sig(&zone_destroy_cv, &zonehash_lock) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4468
			/* Signaled */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4469
			mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4470
			return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4475
	/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4476
	 * Remove CPU cap for this zone now since we're not going to
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4477
	 * fail below this point.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4478
	 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4479
	cpucaps_zone_remove(zone);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4480
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4481
	/* Get rid of the zone's kstats */
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4482
	zone_kstat_delete(zone);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4483
12273
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4484
	/* remove the pfexecd doors */
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4485
	if (zone->zone_pfexecd != NULL) {
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4486
		klpd_freelist(&zone->zone_pfexecd);
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4487
		zone->zone_pfexecd = NULL;
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4488
	}
63678502e95e PSARC 2009/377 In-kernel pfexec implementation.
Casper H.S. Dik <Casper.Dik@Sun.COM>
parents: 11861
diff changeset
  4489
4888
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  4490
	/* free brand specific data */
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  4491
	if (ZONE_IS_BRANDED(zone))
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  4492
		ZBROP(zone)->b_free_brand_data(zone);
51ac39c1472f 6574205 No support for abstract namespace UNIX sockets in lx brand library emulation
eh208807
parents: 4846
diff changeset
  4493
3671
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4494
	/* Say goodbye to brand framework. */
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4495
	brand_unregister_zone(zone->zone_brand);
48011e38989d 6500376 projdel from SUNWesu in SUNWCreq in s10/snv has missing dependency
sl108498
parents: 3448
diff changeset
  4496
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4497
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4498
	 * It is now safe to let the zone be recreated; remove it from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4499
	 * lists.  The memory will not be freed until the last cred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4500
	 * reference goes away.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4501
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4502
	ASSERT(zonecount > 1);	/* must be > 1; can't destroy global zone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4503
	zonecount--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4504
	/* remove from active list and hash tables */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4505
	list_remove(&zone_active, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4506
	(void) mod_hash_destroy(zonehashbyname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4507
	    (mod_hash_key_t)zone->zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4508
	(void) mod_hash_destroy(zonehashbyid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4509
	    (mod_hash_key_t)(uintptr_t)zone->zone_id);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  4510
	if (zone->zone_flags & ZF_HASHED_LABEL)
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4511
		(void) mod_hash_destroy(zonehashbylabel,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4512
		    (mod_hash_key_t)zone->zone_slabel);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4513
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4514
766
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4515
	/*
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4516
	 * Release the root vnode; we're not using it anymore.  Nor should any
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4517
	 * other thread that might access it exist.
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4518
	 */
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4519
	if (zone->zone_rootvp != NULL) {
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4520
		VN_RELE(zone->zone_rootvp);
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4521
		zone->zone_rootvp = NULL;
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4522
	}
c521de78a32f PSARC 2005/474 Zones Upgrade (Ashanti and Zulu)
carlsonj
parents: 390
diff changeset
  4523
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4524
	/* add to deathrow list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4525
	mutex_enter(&zone_deathrow_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4526
	list_insert_tail(&zone_deathrow, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4527
	mutex_exit(&zone_deathrow_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4529
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4530
	 * Drop last reference (which was added by zsched()), this will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4531
	 * free the zone unless there are outstanding cred references.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4532
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4533
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4534
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4535
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4537
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4538
 * Systemcall entry point for zone_getattr(2).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4539
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4540
static ssize_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4541
zone_getattr(zoneid_t zoneid, int attr, void *buf, size_t bufsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4542
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4543
	size_t size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4544
	int error = 0, err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4545
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4546
	char *zonepath;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4547
	char *outstr;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4548
	zone_status_t zone_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4549
	pid_t initpid;
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4550
	boolean_t global = (curzone == global_zone);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4551
	boolean_t inzone = (curzone->zone_id == zoneid);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4552
	ushort_t flags;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4554
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4555
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4556
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4557
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
	zone_status = zone_status_get(zone);
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  4560
	if (zone_status < ZONE_IS_INITIALIZED) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4561
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
	zone_hold(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4567
	/*
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4568
	 * If not in the global zone, don't show information about other zones,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4569
	 * unless the system is labeled and the local zone's label dominates
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4570
	 * the other zone.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4571
	 */
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4572
	if (!zone_list_access(zone)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4573
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4574
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4575
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4577
	switch (attr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4578
	case ZONE_ATTR_ROOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4579
		if (global) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4580
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4581
			 * Copy the path to trim the trailing "/" (except for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4582
			 * the global zone).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4583
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4584
			if (zone != global_zone)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4585
				size = zone->zone_rootpathlen - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4586
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4587
				size = zone->zone_rootpathlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4588
			zonepath = kmem_alloc(size, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4589
			bcopy(zone->zone_rootpath, zonepath, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4590
			zonepath[size - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4591
		} else {
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4592
			if (inzone || !is_system_labeled()) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4593
				/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4594
				 * Caller is not in the global zone.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4595
				 * if the query is on the current zone
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4596
				 * or the system is not labeled,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4597
				 * just return faked-up path for current zone.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4598
				 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4599
				zonepath = "/";
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4600
				size = 2;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4601
			} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4602
				/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4603
				 * Return related path for current zone.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4604
				 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4605
				int prefix_len = strlen(zone_prefix);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4606
				int zname_len = strlen(zone->zone_name);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4607
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4608
				size = prefix_len + zname_len + 1;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4609
				zonepath = kmem_alloc(size, KM_SLEEP);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4610
				bcopy(zone_prefix, zonepath, prefix_len);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4611
				bcopy(zone->zone_name, zonepath +
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4612
				    prefix_len, zname_len);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4613
				zonepath[size - 1] = '\0';
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4614
			}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4615
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4616
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4617
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4618
		if (buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4619
			err = copyoutstr(zonepath, buf, bufsize, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4620
			if (err != 0 && err != ENAMETOOLONG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4621
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4622
		}
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4623
		if (global || (is_system_labeled() && !inzone))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4624
			kmem_free(zonepath, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4625
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4627
	case ZONE_ATTR_NAME:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4628
		size = strlen(zone->zone_name) + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4629
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4630
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4631
		if (buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4632
			err = copyoutstr(zone->zone_name, buf, bufsize, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4633
			if (err != 0 && err != ENAMETOOLONG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4634
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4635
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4636
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4638
	case ZONE_ATTR_STATUS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4639
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4640
		 * Since we're not holding zonehash_lock, the zone status
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4641
		 * may be anything; leave it up to userland to sort it out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4642
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4643
		size = sizeof (zone_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4644
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4645
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4646
		zone_status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4647
		if (buf != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4648
		    copyout(&zone_status, buf, bufsize) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4649
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4650
		break;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4651
	case ZONE_ATTR_FLAGS:
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4652
		size = sizeof (zone->zone_flags);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4653
		if (bufsize > size)
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4654
			bufsize = size;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4655
		flags = zone->zone_flags;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4656
		if (buf != NULL &&
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4657
		    copyout(&flags, buf, bufsize) != 0)
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4658
			error = EFAULT;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  4659
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4660
	case ZONE_ATTR_PRIVSET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4661
		size = sizeof (priv_set_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4662
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4663
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4664
		if (buf != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4665
		    copyout(zone->zone_privset, buf, bufsize) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4666
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4667
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4668
	case ZONE_ATTR_UNIQID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4669
		size = sizeof (zone->zone_uniqid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4670
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4671
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4672
		if (buf != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4673
		    copyout(&zone->zone_uniqid, buf, bufsize) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4674
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4675
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4676
	case ZONE_ATTR_POOLID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4677
		{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4678
			pool_t *pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4679
			poolid_t poolid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4681
			if (pool_lock_intr() != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4682
				error = EINTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4683
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4684
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4685
			pool = zone_pool_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4686
			poolid = pool->pool_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4687
			pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4688
			size = sizeof (poolid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4689
			if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4690
				bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4691
			if (buf != NULL && copyout(&poolid, buf, size) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4692
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4693
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4694
		break;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4695
	case ZONE_ATTR_SLBL:
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4696
		size = sizeof (bslabel_t);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4697
		if (bufsize > size)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4698
			bufsize = size;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4699
		if (zone->zone_slabel == NULL)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4700
			error = EINVAL;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4701
		else if (buf != NULL &&
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4702
		    copyout(label2bslabel(zone->zone_slabel), buf,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4703
		    bufsize) != 0)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4704
			error = EFAULT;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  4705
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4706
	case ZONE_ATTR_INITPID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4707
		size = sizeof (initpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4708
		if (bufsize > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4709
			bufsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4710
		initpid = zone->zone_proc_initpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4711
		if (initpid == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4712
			error = ESRCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4713
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4714
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4715
		if (buf != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4716
		    copyout(&initpid, buf, bufsize) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4717
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4718
		break;
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4719
	case ZONE_ATTR_BRAND:
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4720
		size = strlen(zone->zone_brand->b_name) + 1;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4721
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4722
		if (bufsize > size)
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4723
			bufsize = size;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4724
		if (buf != NULL) {
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4725
			err = copyoutstr(zone->zone_brand->b_name, buf,
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4726
			    bufsize, NULL);
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4727
			if (err != 0 && err != ENAMETOOLONG)
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4728
				error = EFAULT;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4729
		}
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4730
		break;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4731
	case ZONE_ATTR_INITNAME:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4732
		size = strlen(zone->zone_initname) + 1;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4733
		if (bufsize > size)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4734
			bufsize = size;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4735
		if (buf != NULL) {
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4736
			err = copyoutstr(zone->zone_initname, buf, bufsize,
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4737
			    NULL);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4738
			if (err != 0 && err != ENAMETOOLONG)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4739
				error = EFAULT;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4740
		}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4741
		break;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4742
	case ZONE_ATTR_BOOTARGS:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4743
		if (zone->zone_bootargs == NULL)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4744
			outstr = "";
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4745
		else
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4746
			outstr = zone->zone_bootargs;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4747
		size = strlen(outstr) + 1;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4748
		if (bufsize > size)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4749
			bufsize = size;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4750
		if (buf != NULL) {
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4751
			err = copyoutstr(outstr, buf, bufsize, NULL);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4752
			if (err != 0 && err != ENAMETOOLONG)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4753
				error = EFAULT;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4754
		}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4755
		break;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4756
	case ZONE_ATTR_PHYS_MCAP:
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4757
		size = sizeof (zone->zone_phys_mcap);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4758
		if (bufsize > size)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4759
			bufsize = size;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4760
		if (buf != NULL &&
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4761
		    copyout(&zone->zone_phys_mcap, buf, bufsize) != 0)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4762
			error = EFAULT;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4763
		break;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4764
	case ZONE_ATTR_SCHED_CLASS:
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4765
		mutex_enter(&class_lock);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4766
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4767
		if (zone->zone_defaultcid >= loaded_classes)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4768
			outstr = "";
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4769
		else
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4770
			outstr = sclass[zone->zone_defaultcid].cl_name;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4771
		size = strlen(outstr) + 1;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4772
		if (bufsize > size)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4773
			bufsize = size;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4774
		if (buf != NULL) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4775
			err = copyoutstr(outstr, buf, bufsize, NULL);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4776
			if (err != 0 && err != ENAMETOOLONG)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4777
				error = EFAULT;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4778
		}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4779
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4780
		mutex_exit(&class_lock);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4781
		break;
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4782
	case ZONE_ATTR_HOSTID:
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4783
		if (zone->zone_hostid != HW_INVALID_HOSTID &&
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4784
		    bufsize == sizeof (zone->zone_hostid)) {
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4785
			size = sizeof (zone->zone_hostid);
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4786
			if (buf != NULL && copyout(&zone->zone_hostid, buf,
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4787
			    bufsize) != 0)
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4788
				error = EFAULT;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4789
		} else {
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4790
			error = EINVAL;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4791
		}
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4792
		break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4793
	default:
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4794
		if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4795
			size = bufsize;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4796
			error = ZBROP(zone)->b_getattr(zone, attr, buf, &size);
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4797
		} else {
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4798
			error = EINVAL;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4799
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4800
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4801
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4803
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4804
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4805
	return ((ssize_t)size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4806
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4808
/*
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4809
 * Systemcall entry point for zone_setattr(2).
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4810
 */
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4811
/*ARGSUSED*/
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4812
static int
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4813
zone_setattr(zoneid_t zoneid, int attr, void *buf, size_t bufsize)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4814
{
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4815
	zone_t *zone;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4816
	zone_status_t zone_status;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4817
	int err;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4818
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4819
	if (secpolicy_zone_config(CRED()) != 0)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4820
		return (set_errno(EPERM));
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4821
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4822
	/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4823
	 * Only the ZONE_ATTR_PHYS_MCAP attribute can be set on the
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4824
	 * global zone.
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4825
	 */
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4826
	if (zoneid == GLOBAL_ZONEID && attr != ZONE_ATTR_PHYS_MCAP) {
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4827
		return (set_errno(EINVAL));
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4828
	}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4829
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4830
	mutex_enter(&zonehash_lock);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4831
	if ((zone = zone_find_all_by_id(zoneid)) == NULL) {
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4832
		mutex_exit(&zonehash_lock);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4833
		return (set_errno(EINVAL));
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4834
	}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4835
	zone_hold(zone);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4836
	mutex_exit(&zonehash_lock);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4837
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4838
	/*
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4839
	 * At present most attributes can only be set on non-running,
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4840
	 * non-global zones.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4841
	 */
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4842
	zone_status = zone_status_get(zone);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4843
	if (attr != ZONE_ATTR_PHYS_MCAP && zone_status > ZONE_IS_READY)
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4844
		goto done;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4845
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4846
	switch (attr) {
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4847
	case ZONE_ATTR_INITNAME:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4848
		err = zone_set_initname(zone, (const char *)buf);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4849
		break;
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4850
	case ZONE_ATTR_BOOTARGS:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4851
		err = zone_set_bootargs(zone, (const char *)buf);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4852
		break;
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4853
	case ZONE_ATTR_BRAND:
4141
ddd21f3d4066 6545740 sparc brandz syscall wrappers only exist on DEBUG kernels
edp
parents: 3916
diff changeset
  4854
		err = zone_set_brand(zone, (const char *)buf);
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4855
		break;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4856
	case ZONE_ATTR_PHYS_MCAP:
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4857
		err = zone_set_phys_mcap(zone, (const uint64_t *)buf);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4858
		break;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4859
	case ZONE_ATTR_SCHED_CLASS:
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4860
		err = zone_set_sched_class(zone, (const char *)buf);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4861
		break;
8662
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4862
	case ZONE_ATTR_HOSTID:
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4863
		if (bufsize == sizeof (zone->zone_hostid)) {
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4864
			if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4865
				err = 0;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4866
			else
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4867
				err = EFAULT;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4868
		} else {
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4869
			err = EINVAL;
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4870
		}
18153249ee93 PSARC/2008/647 Configurable Hostids for Non-Global Zones
jv227347 <Jordan.Vaughan@Sun.com>
parents: 8364
diff changeset
  4871
		break;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4872
	default:
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4873
		if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone))
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4874
			err = ZBROP(zone)->b_setattr(zone, attr, buf, bufsize);
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4875
		else
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  4876
			err = EINVAL;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4877
	}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4878
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4879
done:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4880
	zone_rele(zone);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4881
	return (err != 0 ? set_errno(err) : 0);
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4882
}
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4883
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  4884
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4885
 * Return zero if the process has at least one vnode mapped in to its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4886
 * address space which shouldn't be allowed to change zones.
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4887
 *
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4888
 * Also return zero if the process has any shared mappings which reserve
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4889
 * swap.  This is because the counting for zone.max-swap does not allow swap
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4888
diff changeset
  4890
 * reservation to be shared between zones.  zone swap reservation is counted
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4891
 * on zone->zone_max_swap.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4892
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4893
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4894
as_can_change_zones(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4895
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4896
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4897
	struct seg *seg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4898
	struct as *as = pp->p_as;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4899
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4900
	int allow = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4901
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4902
	ASSERT(pp->p_as != &kas);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4903
	AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4904
	for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4905
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4906
		/*
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4907
		 * Cannot enter zone with shared anon memory which
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4908
		 * reserves swap.  See comment above.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4909
		 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4910
		if (seg_can_change_zones(seg) == B_FALSE) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4911
			allow = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4912
			break;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4913
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4914
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4915
		 * if we can't get a backing vnode for this segment then skip
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4916
		 * it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4917
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4918
		vp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4919
		if (SEGOP_GETVP(seg, seg->s_base, &vp) != 0 || vp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4920
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4921
		if (!vn_can_change_zones(vp)) { /* bail on first match */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4922
			allow = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4923
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4924
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4925
	}
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4926
	AS_LOCK_EXIT(as, &as->a_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4927
	return (allow);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4928
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4930
/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4931
 * Count swap reserved by curproc's address space
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4932
 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4933
static size_t
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4934
as_swresv(void)
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4935
{
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4936
	proc_t *pp = curproc;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4937
	struct seg *seg;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4938
	struct as *as = pp->p_as;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4939
	size_t swap = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4940
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4941
	ASSERT(pp->p_as != &kas);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4942
	ASSERT(AS_WRITE_HELD(as, &as->a_lock));
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4943
	for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg))
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4944
		swap += seg_swresv(seg);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4945
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4946
	return (swap);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4947
}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4948
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4949
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4950
 * Systemcall entry point for zone_enter().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4951
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4952
 * The current process is injected into said zone.  In the process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4953
 * it will change its project membership, privileges, rootdir/cwd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4954
 * zone-wide rctls, and pool association to match those of the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4955
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4956
 * The first zone_enter() called while the zone is in the ZONE_IS_READY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4957
 * state will transition it to ZONE_IS_RUNNING.  Processes may only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4958
 * enter a zone that is "ready" or "running".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4959
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4960
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4961
zone_enter(zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4962
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4963
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4964
	vnode_t *vp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4965
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4966
	contract_t *ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4967
	cont_process_t *ctp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4968
	task_t *tk, *oldtk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4969
	kproject_t *zone_proj0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4970
	cred_t *cr, *newcr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4971
	pool_t *oldpool, *newpool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4972
	sess_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4973
	uid_t uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4974
	zone_status_t status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4975
	int err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4976
	rctl_entity_p_t e;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  4977
	size_t swap;
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  4978
	kthread_id_t t;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4979
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4980
	if (secpolicy_zone_config(CRED()) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4981
		return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4982
	if (zoneid < MIN_USERZONEID || zoneid > MAX_ZONEID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4983
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4985
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4986
	 * Stop all lwps so we don't need to hold a lock to look at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4987
	 * curproc->p_zone.  This needs to happen before we grab any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4988
	 * locks to avoid deadlock (another lwp in the process could
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4989
	 * be waiting for the held lock).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4990
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4991
	if (curthread != pp->p_agenttp && !holdlwps(SHOLDFORK))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4992
		return (set_errno(EINTR));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4994
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4995
	 * Make sure we're not changing zones with files open or mapped in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4996
	 * to our address space which shouldn't be changing zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4997
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4998
	if (!files_can_change_zones()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4999
		err = EBADF;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5000
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5001
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5002
	if (!as_can_change_zones()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5003
		err = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5004
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5005
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5006
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5007
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5008
	if (pp->p_zone != global_zone) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5009
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5010
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5011
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5014
	zone = zone_find_all_by_id(zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5015
	if (zone == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5016
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5017
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5018
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5019
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5020
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5021
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5022
	 * To prevent processes in a zone from holding contracts on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5023
	 * extrazonal resources, and to avoid process contract
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5024
	 * memberships which span zones, contract holders and processes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5025
	 * which aren't the sole members of their encapsulating process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5026
	 * contracts are not allowed to zone_enter.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5027
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5028
	ctp = pp->p_ct_process;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5029
	ct = &ctp->conp_contract;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5030
	mutex_enter(&ct->ct_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5031
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5032
	if ((avl_numnodes(&pp->p_ct_held) != 0) || (ctp->conp_nmembers != 1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5033
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5034
		mutex_exit(&ct->ct_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5035
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5036
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5037
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5038
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5039
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5040
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5041
	 * Moreover, we don't allow processes whose encapsulating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5042
	 * process contracts have inherited extrazonal contracts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5043
	 * While it would be easier to eliminate all process contracts
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5044
	 * with inherited contracts, we need to be able to give a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5045
	 * restarted init (or other zone-penetrating process) its
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5046
	 * predecessor's contracts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5047
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5048
	if (ctp->conp_ninherited != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5049
		contract_t *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5050
		for (next = list_head(&ctp->conp_inherited); next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5051
		    next = list_next(&ctp->conp_inherited, next)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5052
			if (contract_getzuniqid(next) != zone->zone_uniqid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5053
				mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5054
				mutex_exit(&ct->ct_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5055
				mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5056
				err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5057
				goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5058
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5059
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5060
	}
6073
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5061
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5062
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5063
	mutex_exit(&ct->ct_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5065
	status = zone_status_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5066
	if (status < ZONE_IS_READY || status >= ZONE_IS_SHUTTING_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5067
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5068
		 * Can't join
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5069
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5070
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5071
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5072
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5073
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5075
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5076
	 * Make sure new priv set is within the permitted set for caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5077
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5078
	if (!priv_issubset(zone->zone_privset, &CR_OPPRIV(CRED()))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5079
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5080
		err = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5081
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5082
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5083
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5084
	 * We want to momentarily drop zonehash_lock while we optimistically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5085
	 * bind curproc to the pool it should be running in.  This is safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5086
	 * since the zone can't disappear (we have a hold on it).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5087
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5088
	zone_hold(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5089
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5091
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5092
	 * Grab pool_lock to keep the pools configuration from changing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5093
	 * and to stop ourselves from getting rebound to another pool
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5094
	 * until we join the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5095
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5096
	if (pool_lock_intr() != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5097
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5098
		err = EINTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5099
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5100
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5101
	ASSERT(secpolicy_pool(CRED()) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5102
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5103
	 * Bind ourselves to the pool currently associated with the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5104
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5105
	oldpool = curproc->p_pool;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5106
	newpool = zone_pool_get(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5107
	if (pool_state == POOL_ENABLED && newpool != oldpool &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5108
	    (err = pool_do_bind(newpool, P_PID, P_MYID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5109
	    POOL_BIND_ALL)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5110
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5111
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5112
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5113
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5115
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5116
	 * Grab cpu_lock now; we'll need it later when we call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5117
	 * task_join().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5118
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5119
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5120
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5121
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5122
	 * Make sure the zone hasn't moved on since we dropped zonehash_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5123
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5124
	if (zone_status_get(zone) >= ZONE_IS_SHUTTING_DOWN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5125
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5126
		 * Can't join anymore.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5127
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5128
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5129
		mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5130
		if (pool_state == POOL_ENABLED &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5131
		    newpool != oldpool)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5132
			(void) pool_do_bind(oldpool, P_PID, P_MYID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5133
			    POOL_BIND_ALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5134
		pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5135
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5136
		err = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5137
		goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5138
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5139
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5140
	/*
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5141
	 * a_lock must be held while transfering locked memory and swap
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5142
	 * reservation from the global zone to the non global zone because
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5143
	 * asynchronous faults on the processes' address space can lock
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5144
	 * memory and reserve swap via MCL_FUTURE and MAP_NORESERVE
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5145
	 * segments respectively.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5146
	 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5147
	AS_LOCK_ENTER(pp->as, &pp->p_as->a_lock, RW_WRITER);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5148
	swap = as_swresv();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5149
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5150
	zone_proj0 = zone->zone_zsched->p_task->tk_proj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5151
	/* verify that we do not exceed and task or lwp limits */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5152
	mutex_enter(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5153
	/* add new lwps to zone and zone's proj0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5154
	zone_proj0->kpj_nlwps += pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5155
	zone->zone_nlwps += pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5156
	/* add 1 task to zone's proj0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5157
	zone_proj0->kpj_ntasks += 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5158
	mutex_exit(&zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5159
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5160
	mutex_enter(&zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5161
	zone->zone_locked_mem += pp->p_locked_mem;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5162
	zone_proj0->kpj_data.kpd_locked_mem += pp->p_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5163
	zone->zone_max_swap += swap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5164
	mutex_exit(&zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5165
3916
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5166
	mutex_enter(&(zone_proj0->kpj_data.kpd_crypto_lock));
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5167
	zone_proj0->kpj_data.kpd_crypto_mem += pp->p_crypto_mem;
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5168
	mutex_exit(&(zone_proj0->kpj_data.kpd_crypto_lock));
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5169
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5170
	/* remove lwps from proc's old zone and old project */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5171
	mutex_enter(&pp->p_zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5172
	pp->p_zone->zone_nlwps -= pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5173
	pp->p_task->tk_proj->kpj_nlwps -= pp->p_lwpcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5174
	mutex_exit(&pp->p_zone->zone_nlwps_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5175
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5176
	mutex_enter(&pp->p_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5177
	pp->p_zone->zone_locked_mem -= pp->p_locked_mem;
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5178
	pp->p_task->tk_proj->kpj_data.kpd_locked_mem -= pp->p_locked_mem;
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5179
	pp->p_zone->zone_max_swap -= swap;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5180
	mutex_exit(&pp->p_zone->zone_mem_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5181
3916
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5182
	mutex_enter(&(pp->p_task->tk_proj->kpj_data.kpd_crypto_lock));
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5183
	pp->p_task->tk_proj->kpj_data.kpd_crypto_mem -= pp->p_crypto_mem;
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5184
	mutex_exit(&(pp->p_task->tk_proj->kpj_data.kpd_crypto_lock));
1761dbf695ed 6533554 crypto_buffer_check() is still expensive
krishna
parents: 3792
diff changeset
  5185
9121
f83e5a35a5da 6810086 panic in rctl_incr_swap() due to freed up proc structure
Vamsi Nagineni <Vamsi.Krishna@Sun.COM>
parents: 8905
diff changeset
  5186
	pp->p_flag |= SZONETOP;
f83e5a35a5da 6810086 panic in rctl_incr_swap() due to freed up proc structure
Vamsi Nagineni <Vamsi.Krishna@Sun.COM>
parents: 8905
diff changeset
  5187
	pp->p_zone = zone;
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5188
	mutex_exit(&pp->p_lock);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5189
	AS_LOCK_EXIT(pp->p_as, &pp->p_as->a_lock);
2768
3c77434a8dbb PSARC/2004/580 zone/project.max-locked-memory Resource Controls
sl108498
parents: 2712
diff changeset
  5190
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5191
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5192
	 * Joining the zone cannot fail from now on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5193
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5194
	 * This means that a lot of the following code can be commonized and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5195
	 * shared with zsched().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5196
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5198
	/*
6073
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5199
	 * If the process contract fmri was inherited, we need to
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5200
	 * flag this so that any contract status will not leak
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5201
	 * extra zone information, svc_fmri in this case
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5202
	 */
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5203
	if (ctp->conp_svc_ctid != ct->ct_id) {
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5204
		mutex_enter(&ct->ct_lock);
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5205
		ctp->conp_svc_zone_enter = ct->ct_id;
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5206
		mutex_exit(&ct->ct_lock);
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5207
	}
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5208
47f6aa7a8077 PSARC 2008/046 Process Contract Decorations
acruz
parents: 5895
diff changeset
  5209
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5210
	 * Reset the encapsulating process contract's zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5211
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5212
	ASSERT(ct->ct_mzuniqid == GLOBAL_ZONEUNIQID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5213
	contract_setzuniqid(ct, zone->zone_uniqid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5214
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5215
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5216
	 * Create a new task and associate the process with the project keyed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5217
	 * by (projid,zoneid).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5218
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5219
	 * We might as well be in project 0; the global zone's projid doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5220
	 * make much sense in a zone anyhow.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5221
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5222
	 * This also increments zone_ntasks, and returns with p_lock held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5223
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5224
	tk = task_create(0, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5225
	oldtk = task_join(tk, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5226
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5228
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5229
	 * call RCTLOP_SET functions on this proc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5230
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5231
	e.rcep_p.zone = zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5232
	e.rcep_t = RCENTITY_ZONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5233
	(void) rctl_set_dup(NULL, NULL, pp, &e, zone->zone_rctls, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5234
	    RCD_CALLBACK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5235
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5237
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5238
	 * We don't need to hold any of zsched's locks here; not only do we know
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5239
	 * the process and zone aren't going away, we know its session isn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5240
	 * changing either.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5241
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5242
	 * By joining zsched's session here, we mimic the behavior in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5243
	 * global zone of init's sid being the pid of sched.  We extend this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5244
	 * to all zlogin-like zone_enter()'ing processes as well.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5245
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5246
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5247
	sp = zone->zone_zsched->p_sessp;
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  5248
	sess_hold(zone->zone_zsched);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5249
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5250
	pgexit(pp);
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2677
diff changeset
  5251
	sess_rele(pp->p_sessp, B_TRUE);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5252
	pp->p_sessp = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5253
	pgjoin(pp, zone->zone_zsched->p_pidp);
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5254
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5255
	/*
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5256
	 * If any threads are scheduled to be placed on zone wait queue they
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5257
	 * should abandon the idea since the wait queue is changing.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5258
	 * We need to be holding pidlock & p_lock to do this.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5259
	 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5260
	if ((t = pp->p_tlist) != NULL) {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5261
		do {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5262
			thread_lock(t);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5263
			/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5264
			 * Kick this thread so that he doesn't sit
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5265
			 * on a wrong wait queue.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5266
			 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5267
			if (ISWAITING(t))
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5268
				setrun_locked(t);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5269
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5270
			if (t->t_schedflag & TS_ANYWAITQ)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5271
				t->t_schedflag &= ~ TS_ANYWAITQ;
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5272
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5273
			thread_unlock(t);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5274
		} while ((t = t->t_forw) != pp->p_tlist);
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5275
	}
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5276
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 3671
diff changeset
  5277
	/*
3247
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5278
	 * If there is a default scheduling class for the zone and it is not
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5279
	 * the class we are currently in, change all of the threads in the
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5280
	 * process to the new class.  We need to be holding pidlock & p_lock
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5281
	 * when we call parmsset so this is a good place to do it.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5282
	 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5283
	if (zone->zone_defaultcid > 0 &&
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5284
	    zone->zone_defaultcid != curthread->t_cid) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5285
		pcparms_t pcparms;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5286
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5287
		pcparms.pc_cid = zone->zone_defaultcid;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5288
		pcparms.pc_clparms[0] = 0;
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5289
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5290
		/*
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5291
		 * If setting the class fails, we still want to enter the zone.
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5292
		 */
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5293
		if ((t = pp->p_tlist) != NULL) {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5294
			do {
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5295
				(void) parmsset(&pcparms, t);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5296
			} while ((t = t->t_forw) != pp->p_tlist);
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5297
		}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5298
	}
e05001c14ea2 PSARC 2006/496 Improved Zones/RM Integration
gjelinek
parents: 2768
diff changeset
  5299
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5300
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5301
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5303
	mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5304
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5305
	 * We're firmly in the zone; let pools progress.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5306
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5307
	pool_unlock();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5308
	task_rele(oldtk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5309
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5310
	 * We don't need to retain a hold on the zone since we already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5311
	 * incremented zone_ntasks, so the zone isn't going anywhere.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5312
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5313
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5315
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5316
	 * Chroot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5317
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5318
	vp = zone->zone_rootvp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5319
	zone_chdir(vp, &PTOU(pp)->u_cdir, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5320
	zone_chdir(vp, &PTOU(pp)->u_rdir, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5322
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5323
	 * Change process credentials
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5324
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5325
	newcr = cralloc();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5326
	mutex_enter(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5327
	cr = pp->p_cred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5328
	crcopy_to(cr, newcr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5329
	crsetzone(newcr, zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5330
	pp->p_cred = newcr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5332
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5333
	 * Restrict all process privilege sets to zone limit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5334
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5335
	priv_intersect(zone->zone_privset, &CR_PPRIV(newcr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5336
	priv_intersect(zone->zone_privset, &CR_EPRIV(newcr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5337
	priv_intersect(zone->zone_privset, &CR_IPRIV(newcr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5338
	priv_intersect(zone->zone_privset, &CR_LPRIV(newcr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5339
	mutex_exit(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5340
	crset(pp, newcr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5342
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5343
	 * Adjust upcount to reflect zone entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5344
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5345
	uid = crgetruid(newcr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5346
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5347
	upcount_dec(uid, GLOBAL_ZONEID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5348
	upcount_inc(uid, zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5349
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5351
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5352
	 * Set up core file path and content.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5353
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5354
	set_core_defaults();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5355
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5356
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5357
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5358
	 * Let the other lwps continue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5359
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5360
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5361
	if (curthread != pp->p_agenttp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5362
		continuelwps(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5363
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5365
	return (err != 0 ? set_errno(err) : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5366
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5368
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5369
 * Systemcall entry point for zone_list(2).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5370
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5371
 * Processes running in a (non-global) zone only see themselves.
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5372
 * On labeled systems, they see all zones whose label they dominate.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5373
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5374
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5375
zone_list(zoneid_t *zoneidlist, uint_t *numzones)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5376
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5377
	zoneid_t *zoneids;
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5378
	zone_t *zone, *myzone;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5379
	uint_t user_nzones, real_nzones;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5380
	uint_t domi_nzones;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5381
	int error;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5383
	if (copyin(numzones, &user_nzones, sizeof (uint_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5384
		return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5385
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5386
	myzone = curproc->p_zone;
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5387
	if (myzone != global_zone) {
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5388
		bslabel_t *mybslab;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5389
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5390
		if (!is_system_labeled()) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5391
			/* just return current zone */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5392
			real_nzones = domi_nzones = 1;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5393
			zoneids = kmem_alloc(sizeof (zoneid_t), KM_SLEEP);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5394
			zoneids[0] = myzone->zone_id;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5395
		} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5396
			/* return all zones that are dominated */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5397
			mutex_enter(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5398
			real_nzones = zonecount;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5399
			domi_nzones = 0;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5400
			if (real_nzones > 0) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5401
				zoneids = kmem_alloc(real_nzones *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5402
				    sizeof (zoneid_t), KM_SLEEP);
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5403
				mybslab = label2bslabel(myzone->zone_slabel);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5404
				for (zone = list_head(&zone_active);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5405
				    zone != NULL;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5406
				    zone = list_next(&zone_active, zone)) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5407
					if (zone->zone_id == GLOBAL_ZONEID)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5408
						continue;
1769
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5409
					if (zone != myzone &&
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5410
					    (zone->zone_flags & ZF_IS_SCRATCH))
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5411
						continue;
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5412
					/*
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5413
					 * Note that a label always dominates
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5414
					 * itself, so myzone is always included
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5415
					 * in the list.
338500d67d4f 6404654 zoneadm mount command fails on labeled systems
carlsonj
parents: 1676
diff changeset
  5416
					 */
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5417
					if (bldominates(mybslab,
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5418
					    label2bslabel(zone->zone_slabel))) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5419
						zoneids[domi_nzones++] =
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5420
						    zone->zone_id;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5421
					}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5422
				}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5423
			}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5424
			mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5425
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5426
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5427
		mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5428
		real_nzones = zonecount;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5429
		domi_nzones = 0;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5430
		if (real_nzones > 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5431
			zoneids = kmem_alloc(real_nzones * sizeof (zoneid_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5432
			    KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5433
			for (zone = list_head(&zone_active); zone != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5434
			    zone = list_next(&zone_active, zone))
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5435
				zoneids[domi_nzones++] = zone->zone_id;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5436
			ASSERT(domi_nzones == real_nzones);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5437
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5438
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5439
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5440
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5441
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5442
	 * If user has allocated space for fewer entries than we found, then
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5443
	 * return only up to his limit.  Either way, tell him exactly how many
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5444
	 * we found.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5445
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5446
	if (domi_nzones < user_nzones)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5447
		user_nzones = domi_nzones;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5448
	error = 0;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5449
	if (copyout(&domi_nzones, numzones, sizeof (uint_t)) != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5450
		error = EFAULT;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5451
	} else if (zoneidlist != NULL && user_nzones != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5452
		if (copyout(zoneids, zoneidlist,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5453
		    user_nzones * sizeof (zoneid_t)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5454
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5455
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5456
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5457
	if (real_nzones > 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5458
		kmem_free(zoneids, real_nzones * sizeof (zoneid_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5459
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5460
	if (error != 0)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5461
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5462
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5463
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5464
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5466
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5467
 * Systemcall entry point for zone_lookup(2).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5468
 *
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5469
 * Non-global zones are only able to see themselves and (on labeled systems)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5470
 * the zones they dominate.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5471
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5472
static zoneid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5473
zone_lookup(const char *zone_name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5474
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5475
	char *kname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5476
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5477
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5478
	int err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5479
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5480
	if (zone_name == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5481
		/* return caller's zone id */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5482
		return (getzoneid());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5483
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5485
	kname = kmem_zalloc(ZONENAME_MAX, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5486
	if ((err = copyinstr(zone_name, kname, ZONENAME_MAX, NULL)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5487
		kmem_free(kname, ZONENAME_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5488
		return (set_errno(err));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5489
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5490
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5491
	mutex_enter(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5492
	zone = zone_find_all_by_name(kname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5493
	kmem_free(kname, ZONENAME_MAX);
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5494
	/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5495
	 * In a non-global zone, can only lookup global and own name.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5496
	 * In Trusted Extensions zone label dominance rules apply.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5497
	 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5498
	if (zone == NULL ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5499
	    zone_status_get(zone) < ZONE_IS_READY ||
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5500
	    !zone_list_access(zone)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5501
		mutex_exit(&zonehash_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5502
		return (set_errno(EINVAL));
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5503
	} else {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5504
		zoneid = zone->zone_id;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5505
		mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5506
		return (zoneid);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5507
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5508
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5509
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5510
static int
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5511
zone_version(int *version_arg)
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5512
{
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5513
	int version = ZONE_SYSCALL_API_VERSION;
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5514
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5515
	if (copyout(&version, version_arg, sizeof (int)) != 0)
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5516
		return (set_errno(EFAULT));
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5517
	return (0);
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5518
}
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5519
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5520
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5521
long
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5522
zone(int cmd, void *arg1, void *arg2, void *arg3, void *arg4)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5523
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5524
	zone_def zs;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5525
	int err;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5527
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5528
	case ZONE_CREATE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5529
		if (get_udatamodel() == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5530
			if (copyin(arg1, &zs, sizeof (zone_def))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5531
				return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5532
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5533
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5534
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5535
			zone_def32 zs32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5537
			if (copyin(arg1, &zs32, sizeof (zone_def32))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5538
				return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5539
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5540
			zs.zone_name =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5541
			    (const char *)(unsigned long)zs32.zone_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5542
			zs.zone_root =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5543
			    (const char *)(unsigned long)zs32.zone_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5544
			zs.zone_privs =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5545
			    (const struct priv_set *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5546
			    (unsigned long)zs32.zone_privs;
1409
c25d6f2622c9 6366674 zones service common name could be more descriptive
dp
parents: 1166
diff changeset
  5547
			zs.zone_privssz = zs32.zone_privssz;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5548
			zs.rctlbuf = (caddr_t)(unsigned long)zs32.rctlbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5549
			zs.rctlbufsz = zs32.rctlbufsz;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5550
			zs.zfsbuf = (caddr_t)(unsigned long)zs32.zfsbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5551
			zs.zfsbufsz = zs32.zfsbufsz;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5552
			zs.extended_error =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5553
			    (int *)(unsigned long)zs32.extended_error;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5554
			zs.match = zs32.match;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5555
			zs.doi = zs32.doi;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5556
			zs.label = (const bslabel_t *)(uintptr_t)zs32.label;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5557
			zs.flags = zs32.flags;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5558
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5559
			panic("get_udatamodel() returned bogus result\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5560
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5561
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5562
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5563
		return (zone_create(zs.zone_name, zs.zone_root,
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5564
		    zs.zone_privs, zs.zone_privssz,
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5565
		    (caddr_t)zs.rctlbuf, zs.rctlbufsz,
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5566
		    (caddr_t)zs.zfsbuf, zs.zfsbufsz,
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  5567
		    zs.extended_error, zs.match, zs.doi,
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5568
		    zs.label, zs.flags));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5569
	case ZONE_BOOT:
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5570
		return (zone_boot((zoneid_t)(uintptr_t)arg1));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5571
	case ZONE_DESTROY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5572
		return (zone_destroy((zoneid_t)(uintptr_t)arg1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5573
	case ZONE_GETATTR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5574
		return (zone_getattr((zoneid_t)(uintptr_t)arg1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5575
		    (int)(uintptr_t)arg2, arg3, (size_t)arg4));
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5576
	case ZONE_SETATTR:
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5577
		return (zone_setattr((zoneid_t)(uintptr_t)arg1,
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5578
		    (int)(uintptr_t)arg2, arg3, (size_t)arg4));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5579
	case ZONE_ENTER:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5580
		return (zone_enter((zoneid_t)(uintptr_t)arg1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5581
	case ZONE_LIST:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5582
		return (zone_list((zoneid_t *)arg1, (uint_t *)arg2));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5583
	case ZONE_SHUTDOWN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5584
		return (zone_shutdown((zoneid_t)(uintptr_t)arg1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5585
	case ZONE_LOOKUP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5586
		return (zone_lookup((const char *)arg1));
813
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5587
	case ZONE_VERSION:
0e6d3e880863 6317239 zone(2) needs subcode to query API version
dp
parents: 789
diff changeset
  5588
		return (zone_version((int *)arg1));
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5589
	case ZONE_ADD_DATALINK:
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5590
		return (zone_add_datalink((zoneid_t)(uintptr_t)arg1,
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5591
		    (datalink_id_t)(uintptr_t)arg2));
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5592
	case ZONE_DEL_DATALINK:
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5593
		return (zone_remove_datalink((zoneid_t)(uintptr_t)arg1,
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5594
		    (datalink_id_t)(uintptr_t)arg2));
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5595
	case ZONE_CHECK_DATALINK: {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5596
		zoneid_t	zoneid;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5597
		boolean_t	need_copyout;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5598
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5599
		if (copyin(arg1, &zoneid, sizeof (zoneid)) != 0)
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5600
			return (EFAULT);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5601
		need_copyout = (zoneid == ALL_ZONES);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5602
		err = zone_check_datalink(&zoneid,
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5603
		    (datalink_id_t)(uintptr_t)arg2);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5604
		if (err == 0 && need_copyout) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5605
			if (copyout(&zoneid, arg1, sizeof (zoneid)) != 0)
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5606
				err = EFAULT;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5607
		}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5608
		return (err == 0 ? 0 : set_errno(err));
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5609
	}
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5610
	case ZONE_LIST_DATALINK:
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  5611
		return (zone_list_datalink((zoneid_t)(uintptr_t)arg1,
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  5612
		    (int *)arg2, (datalink_id_t *)(uintptr_t)arg3));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5613
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5614
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5615
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5618
struct zarg {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5619
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5620
	zone_cmd_arg_t arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5621
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5623
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5624
zone_lookup_door(const char *zone_name, door_handle_t *doorp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5625
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5626
	char *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5627
	size_t buflen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5628
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5630
	buflen = sizeof (ZONE_DOOR_PATH) + strlen(zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5631
	buf = kmem_alloc(buflen, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5632
	(void) snprintf(buf, buflen, ZONE_DOOR_PATH, zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5633
	error = door_ki_open(buf, doorp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5634
	kmem_free(buf, buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5635
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5636
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5638
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5639
zone_release_door(door_handle_t *doorp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5640
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5641
	door_ki_rele(*doorp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5642
	*doorp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5643
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5645
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5646
zone_ki_call_zoneadmd(struct zarg *zargp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5647
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5648
	door_handle_t door = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5649
	door_arg_t darg, save_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5650
	char *zone_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5651
	size_t zone_namelen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5652
	zoneid_t zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5653
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5654
	zone_cmd_arg_t arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5655
	uint64_t uniqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5656
	size_t size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5657
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5658
	int retry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5660
	zone = zargp->zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5661
	arg = zargp->arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5662
	kmem_free(zargp, sizeof (*zargp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5664
	zone_namelen = strlen(zone->zone_name) + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5665
	zone_name = kmem_alloc(zone_namelen, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5666
	bcopy(zone->zone_name, zone_name, zone_namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5667
	zoneid = zone->zone_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5668
	uniqid = zone->zone_uniqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5669
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5670
	 * zoneadmd may be down, but at least we can empty out the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5671
	 * We can ignore the return value of zone_empty() since we're called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5672
	 * from a kernel thread and know we won't be delivered any signals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5673
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5674
	ASSERT(curproc == &p0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5675
	(void) zone_empty(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5676
	ASSERT(zone_status_get(zone) >= ZONE_IS_EMPTY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5677
	zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5679
	size = sizeof (arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5680
	darg.rbuf = (char *)&arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5681
	darg.data_ptr = (char *)&arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5682
	darg.rsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5683
	darg.data_size = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5684
	darg.desc_ptr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5685
	darg.desc_num = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5687
	save_arg = darg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5688
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5689
	 * Since we're not holding a reference to the zone, any number of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5690
	 * things can go wrong, including the zone disappearing before we get a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5691
	 * chance to talk to zoneadmd.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5692
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5693
	for (retry = 0; /* forever */; retry++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5694
		if (door == NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5695
		    (error = zone_lookup_door(zone_name, &door)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5696
			goto next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5697
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5698
		ASSERT(door != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5699
6997
056043f166c6 PSARC 2008/208 Flexible Credentials and Result Limits for Kernel Door Upcalls
jwadams
parents: 6073
diff changeset
  5700
		if ((error = door_ki_upcall_limited(door, &darg, NULL,
056043f166c6 PSARC 2008/208 Flexible Credentials and Result Limits for Kernel Door Upcalls
jwadams
parents: 6073
diff changeset
  5701
		    SIZE_MAX, 0)) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5702
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5703
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5704
		switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5705
		case EINTR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5706
			/* FALLTHROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5707
		case EAGAIN:	/* process may be forking */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5708
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5709
			 * Back off for a bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5710
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5711
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5712
		case EBADF:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5713
			zone_release_door(&door);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5714
			if (zone_lookup_door(zone_name, &door) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5715
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5716
				 * zoneadmd may be dead, but it may come back to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5717
				 * life later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5718
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5719
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5720
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5721
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5722
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5723
			cmn_err(CE_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5724
			    "zone_ki_call_zoneadmd: door_ki_upcall error %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5725
			    error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5726
			goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5727
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5728
next:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5729
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5730
		 * If this isn't the same zone_t that we originally had in mind,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5731
		 * then this is the same as if two kadmin requests come in at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5732
		 * the same time: the first one wins.  This means we lose, so we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5733
		 * bail.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5734
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5735
		if ((zone = zone_find_by_id(zoneid)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5736
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5737
			 * Problem is solved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5738
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5739
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5740
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5741
		if (zone->zone_uniqid != uniqid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5742
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5743
			 * zoneid recycled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5744
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5745
			zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5746
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5747
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5748
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5749
		 * We could zone_status_timedwait(), but there doesn't seem to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5750
		 * be much point in doing that (plus, it would mean that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5751
		 * zone_free() isn't called until this thread exits).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5752
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5753
		zone_rele(zone);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5754
		delay(hz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5755
		darg = save_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5756
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5757
out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5758
	if (door != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5759
		zone_release_door(&door);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5760
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5761
	kmem_free(zone_name, zone_namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5762
	thread_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5763
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5765
/*
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5766
 * Entry point for uadmin() to tell the zone to go away or reboot.  Analog to
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5767
 * kadmin().  The caller is a process in the zone.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5768
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5769
 * In order to shutdown the zone, we will hand off control to zoneadmd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5770
 * (running in the global zone) via a door.  We do a half-hearted job at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5771
 * killing all processes in the zone, create a kernel thread to contact
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5772
 * zoneadmd, and make note of the "uniqid" of the zone.  The uniqid is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5773
 * a form of generation number used to let zoneadmd (as well as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5774
 * zone_destroy()) know exactly which zone they're re talking about.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5775
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5776
int
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5777
zone_kadmin(int cmd, int fcn, const char *mdep, cred_t *credp)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5778
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5779
	struct zarg *zargp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5780
	zone_cmd_t zcmd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5781
	zone_t *zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5782
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5783
	zone = curproc->p_zone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5784
	ASSERT(getzoneid() != GLOBAL_ZONEID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5786
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5787
	case A_SHUTDOWN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5788
		switch (fcn) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5789
		case AD_HALT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5790
		case AD_POWEROFF:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5791
			zcmd = Z_HALT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5792
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5793
		case AD_BOOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5794
			zcmd = Z_REBOOT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5795
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5796
		case AD_IBOOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5797
		case AD_SBOOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5798
		case AD_SIBOOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5799
		case AD_NOSYNC:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5800
			return (ENOTSUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5801
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5802
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5803
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5804
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5805
	case A_REBOOT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5806
		zcmd = Z_REBOOT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5807
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5808
	case A_FTRACE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5809
	case A_REMOUNT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5810
	case A_FREEZE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5811
	case A_DUMP:
9160
1517e6edbc6f PSARC/2008/760 Boot configuration Service
Sherry Moore <Sherry.Moore@Sun.COM>
parents: 9121
diff changeset
  5812
	case A_CONFIG:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5813
		return (ENOTSUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5814
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5815
		ASSERT(cmd != A_SWAPCTL);	/* handled by uadmin() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5816
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5817
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5818
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5819
	if (secpolicy_zone_admin(credp, B_FALSE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5820
		return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5821
	mutex_enter(&zone_status_lock);
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5822
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5823
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5824
	 * zone_status can't be ZONE_IS_EMPTY or higher since curproc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5825
	 * is in the zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5826
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5827
	ASSERT(zone_status_get(zone) < ZONE_IS_EMPTY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5828
	if (zone_status_get(zone) > ZONE_IS_RUNNING) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5829
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5830
		 * This zone is already on its way down.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5831
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5832
		mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5833
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5835
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5836
	 * Prevent future zone_enter()s
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5837
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5838
	zone_status_set(zone, ZONE_IS_SHUTTING_DOWN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5839
	mutex_exit(&zone_status_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5840
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5841
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5842
	 * Kill everyone now and call zoneadmd later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5843
	 * zone_ki_call_zoneadmd() will do a more thorough job of this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5844
	 * later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5845
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5846
	killall(zone->zone_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5847
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5848
	 * Now, create the thread to contact zoneadmd and do the rest of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5849
	 * work.  This thread can't be created in our zone otherwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5850
	 * zone_destroy() would deadlock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5851
	 */
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5852
	zargp = kmem_zalloc(sizeof (*zargp), KM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5853
	zargp->arg.cmd = zcmd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5854
	zargp->arg.uniqid = zone->zone_uniqid;
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5855
	zargp->zone = zone;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5856
	(void) strcpy(zargp->arg.locale, "C");
2267
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5857
	/* mdep was already copied in for us by uadmin */
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5858
	if (mdep != NULL)
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5859
		(void) strlcpy(zargp->arg.bootbuf, mdep,
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5860
		    sizeof (zargp->arg.bootbuf));
c5d9a656170f PSARC/2006/269 Zone Boot Arguments II
dp
parents: 2110
diff changeset
  5861
	zone_hold(zone);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5863
	(void) thread_create(NULL, 0, zone_ki_call_zoneadmd, zargp, 0, &p0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5864
	    TS_RUN, minclsyspri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5865
	exit(CLD_EXITED, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5867
	return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5868
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5870
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5871
 * Entry point so kadmin(A_SHUTDOWN, ...) can set the global zone's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5872
 * status to ZONE_IS_SHUTTING_DOWN.
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5873
 *
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5874
 * This function also shuts down all running zones to ensure that they won't
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5875
 * fork new processes.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5876
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5877
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5878
zone_shutdown_global(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5879
{
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5880
	zone_t *current_zonep;
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5881
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5882
	ASSERT(INGLOBALZONE(curproc));
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5883
	mutex_enter(&zonehash_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5884
	mutex_enter(&zone_status_lock);
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5885
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5886
	/* Modify the global zone's status first. */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5887
	ASSERT(zone_status_get(global_zone) == ZONE_IS_RUNNING);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5888
	zone_status_set(global_zone, ZONE_IS_SHUTTING_DOWN);
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5889
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5890
	/*
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5891
	 * Now change the states of all running zones to ZONE_IS_SHUTTING_DOWN.
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5892
	 * We don't mark all zones with ZONE_IS_SHUTTING_DOWN because doing so
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5893
	 * could cause assertions to fail (e.g., assertions about a zone's
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5894
	 * state during initialization, readying, or booting) or produce races.
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5895
	 * We'll let threads continue to initialize and ready new zones: they'll
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5896
	 * fail to boot the new zones when they see that the global zone is
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5897
	 * shutting down.
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5898
	 */
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5899
	for (current_zonep = list_head(&zone_active); current_zonep != NULL;
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5900
	    current_zonep = list_next(&zone_active, current_zonep)) {
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5901
		if (zone_status_get(current_zonep) == ZONE_IS_RUNNING)
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5902
			zone_status_set(current_zonep, ZONE_IS_SHUTTING_DOWN);
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5903
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5904
	mutex_exit(&zone_status_lock);
8364
a7175cb7e760 5075745 madly forking zones can prevent the global zone from rebooting
jv227347 <Jordan.Vaughan@Sun.com>
parents: 6997
diff changeset
  5905
	mutex_exit(&zonehash_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  5906
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5907
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5908
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5909
 * Returns true if the named dataset is visible in the current zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5910
 * The 'write' parameter is set to 1 if the dataset is also writable.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5911
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5912
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5913
zone_dataset_visible(const char *dataset, int *write)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5914
{
11850
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5915
	static int zfstype = -1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5916
	zone_dataset_t *zd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5917
	size_t len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5918
	zone_t *zone = curproc->p_zone;
11850
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5919
	const char *name = NULL;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5920
	vfs_t *vfsp = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5921
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5922
	if (dataset[0] == '\0')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5923
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5924
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5925
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5926
	 * Walk the list once, looking for datasets which match exactly, or
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5927
	 * specify a dataset underneath an exported dataset.  If found, return
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5928
	 * true and note that it is writable.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5929
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5930
	for (zd = list_head(&zone->zone_datasets); zd != NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5931
	    zd = list_next(&zone->zone_datasets, zd)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5932
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5933
		len = strlen(zd->zd_dataset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5934
		if (strlen(dataset) >= len &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5935
		    bcmp(dataset, zd->zd_dataset, len) == 0 &&
816
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 813
diff changeset
  5936
		    (dataset[len] == '\0' || dataset[len] == '/' ||
4a2d51f7b961 6344201 Assertion failed: err == 0 (0x1 == 0x0), file: ../../common/fs/zfs/zfs_ctldir.c, line: 659
maybee
parents: 813
diff changeset
  5937
		    dataset[len] == '@')) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5938
			if (write)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5939
				*write = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5940
			return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5941
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5942
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5943
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5944
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5945
	 * Walk the list a second time, searching for datasets which are parents
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5946
	 * of exported datasets.  These should be visible, but read-only.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5947
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5948
	 * Note that we also have to support forms such as 'pool/dataset/', with
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5949
	 * a trailing slash.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5950
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5951
	for (zd = list_head(&zone->zone_datasets); zd != NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5952
	    zd = list_next(&zone->zone_datasets, zd)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5953
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5954
		len = strlen(dataset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5955
		if (dataset[len - 1] == '/')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5956
			len--;	/* Ignore trailing slash */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5957
		if (len < strlen(zd->zd_dataset) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5958
		    bcmp(dataset, zd->zd_dataset, len) == 0 &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5959
		    zd->zd_dataset[len] == '/') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5960
			if (write)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5961
				*write = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5962
			return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5963
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5964
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  5965
11850
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5966
	/*
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5967
	 * We reach here if the given dataset is not found in the zone_dataset
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5968
	 * list. Check if this dataset was added as a filesystem (ie. "add fs")
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5969
	 * instead of delegation. For this we search for the dataset in the
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5970
	 * zone_vfslist of this zone. If found, return true and note that it is
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5971
	 * not writable.
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5972
	 */
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5973
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5974
	/*
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5975
	 * Initialize zfstype if it is not initialized yet.
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5976
	 */
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5977
	if (zfstype == -1) {
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5978
		struct vfssw *vswp = vfs_getvfssw("zfs");
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5979
		zfstype = vswp - vfssw;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5980
		vfs_unrefvfssw(vswp);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5981
	}
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5982
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5983
	vfs_list_read_lock();
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5984
	vfsp = zone->zone_vfslist;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5985
	do {
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5986
		ASSERT(vfsp);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5987
		if (vfsp->vfs_fstype == zfstype) {
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5988
			name = refstr_value(vfsp->vfs_resource);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5989
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5990
			/*
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5991
			 * Check if we have an exact match.
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5992
			 */
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5993
			if (strcmp(dataset, name) == 0) {
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5994
				vfs_list_unlock();
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5995
				if (write)
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5996
					*write = 0;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5997
				return (1);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5998
			}
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  5999
			/*
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6000
			 * We need to check if we are looking for parents of
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6001
			 * a dataset. These should be visible, but read-only.
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6002
			 */
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6003
			len = strlen(dataset);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6004
			if (dataset[len - 1] == '/')
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6005
				len--;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6006
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6007
			if (len < strlen(name) &&
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6008
			    bcmp(dataset, name, len) == 0 && name[len] == '/') {
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6009
				vfs_list_unlock();
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6010
				if (write)
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6011
					*write = 0;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6012
				return (1);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6013
			}
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6014
		}
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6015
		vfsp = vfsp->vfs_zone_next;
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6016
	} while (vfsp != zone->zone_vfslist);
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6017
e8fd9dbe1e8d 6826620 df shows a wrong results for a zfs dataset from a non-global zone
Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
parents: 11173
diff changeset
  6018
	vfs_list_unlock();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  6019
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 766
diff changeset
  6020
}
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6021
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6022
/*
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6023
 * zone_find_by_any_path() -
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6024
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6025
 * kernel-private routine similar to zone_find_by_path(), but which
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6026
 * effectively compares against zone paths rather than zonerootpath
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6027
 * (i.e., the last component of zonerootpaths, which should be "root/",
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6028
 * are not compared.)  This is done in order to accurately identify all
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6029
 * paths, whether zone-visible or not, including those which are parallel
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6030
 * to /root/, such as /dev/, /home/, etc...
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6031
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6032
 * If the specified path does not fall under any zone path then global
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6033
 * zone is returned.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6034
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6035
 * The treat_abs parameter indicates whether the path should be treated as
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6036
 * an absolute path although it does not begin with "/".  (This supports
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6037
 * nfs mount syntax such as host:any/path.)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6038
 *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6039
 * The caller is responsible for zone_rele of the returned zone.
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6040
 */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6041
zone_t *
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6042
zone_find_by_any_path(const char *path, boolean_t treat_abs)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6043
{
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6044
	zone_t *zone;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6045
	int path_offset = 0;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6046
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6047
	if (path == NULL) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6048
		zone_hold(global_zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6049
		return (global_zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6050
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6051
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6052
	if (*path != '/') {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6053
		ASSERT(treat_abs);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6054
		path_offset = 1;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6055
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6056
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6057
	mutex_enter(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6058
	for (zone = list_head(&zone_active); zone != NULL;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6059
	    zone = list_next(&zone_active, zone)) {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6060
		char	*c;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6061
		size_t	pathlen;
1876
1427ed2daa73 6414797 code in zone_find_by_any_path generates bad assembly code and panic, can be worked around w/ change
mp46848
parents: 1769
diff changeset
  6062
		char *rootpath_start;
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6063
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6064
		if (zone == global_zone)	/* skip global zone */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6065
			continue;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6066
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6067
		/* scan backwards to find start of last component */
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6068
		c = zone->zone_rootpath + zone->zone_rootpathlen - 2;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6069
		do {
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6070
			c--;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6071
		} while (*c != '/');
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6072
1876
1427ed2daa73 6414797 code in zone_find_by_any_path generates bad assembly code and panic, can be worked around w/ change
mp46848
parents: 1769
diff changeset
  6073
		pathlen = c - zone->zone_rootpath + 1 - path_offset;
1427ed2daa73 6414797 code in zone_find_by_any_path generates bad assembly code and panic, can be worked around w/ change
mp46848
parents: 1769
diff changeset
  6074
		rootpath_start = (zone->zone_rootpath + path_offset);
1427ed2daa73 6414797 code in zone_find_by_any_path generates bad assembly code and panic, can be worked around w/ change
mp46848
parents: 1769
diff changeset
  6075
		if (strncmp(path, rootpath_start, pathlen) == 0)
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6076
			break;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6077
	}
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6078
	if (zone == NULL)
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6079
		zone = global_zone;
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6080
	zone_hold(zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6081
	mutex_exit(&zonehash_lock);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6082
	return (zone);
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1409
diff changeset
  6083
}
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6084
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6085
/*
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6086
 * Finds a zone_dl_t with the given linkid in the given zone.  Returns the
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6087
 * zone_dl_t pointer if found, and NULL otherwise.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6088
 */
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6089
static zone_dl_t *
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6090
zone_find_dl(zone_t *zone, datalink_id_t linkid)
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6091
{
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6092
	zone_dl_t *zdl;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6093
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6094
	ASSERT(mutex_owned(&zone->zone_lock));
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6095
	for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6096
	    zdl = list_next(&zone->zone_dl_list, zdl)) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6097
		if (zdl->zdl_id == linkid)
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6098
			break;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6099
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6100
	return (zdl);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6101
}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6102
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6103
static boolean_t
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6104
zone_dl_exists(zone_t *zone, datalink_id_t linkid)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6105
{
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6106
	boolean_t exists;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6107
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6108
	mutex_enter(&zone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6109
	exists = (zone_find_dl(zone, linkid) != NULL);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6110
	mutex_exit(&zone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6111
	return (exists);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6112
}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6113
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6114
/*
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6115
 * Add an data link name for the zone.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6116
 */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6117
static int
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6118
zone_add_datalink(zoneid_t zoneid, datalink_id_t linkid)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6119
{
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6120
	zone_dl_t *zdl;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6121
	zone_t *zone;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6122
	zone_t *thiszone;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6123
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6124
	if ((thiszone = zone_find_by_id(zoneid)) == NULL)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6125
		return (set_errno(ENXIO));
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6126
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6127
	/* Verify that the datalink ID doesn't already belong to a zone. */
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6128
	mutex_enter(&zonehash_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6129
	for (zone = list_head(&zone_active); zone != NULL;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6130
	    zone = list_next(&zone_active, zone)) {
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6131
		if (zone_dl_exists(zone, linkid)) {
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6132
			mutex_exit(&zonehash_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6133
			zone_rele(thiszone);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6134
			return (set_errno((zone == thiszone) ? EEXIST : EPERM));
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6135
		}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6136
	}
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6137
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6138
	zdl = kmem_zalloc(sizeof (*zdl), KM_SLEEP);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6139
	zdl->zdl_id = linkid;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6140
	mutex_enter(&thiszone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6141
	list_insert_head(&thiszone->zone_dl_list, zdl);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6142
	mutex_exit(&thiszone->zone_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6143
	mutex_exit(&zonehash_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6144
	zone_rele(thiszone);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6145
	return (0);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6146
}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6147
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6148
static int
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6149
zone_remove_datalink(zoneid_t zoneid, datalink_id_t linkid)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6150
{
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6151
	zone_dl_t *zdl;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6152
	zone_t *zone;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6153
	int err = 0;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6154
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6155
	if ((zone = zone_find_by_id(zoneid)) == NULL)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6156
		return (set_errno(EINVAL));
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6157
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6158
	mutex_enter(&zone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6159
	if ((zdl = zone_find_dl(zone, linkid)) == NULL) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6160
		err = ENXIO;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6161
	} else {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6162
		list_remove(&zone->zone_dl_list, zdl);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6163
		kmem_free(zdl, sizeof (zone_dl_t));
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6164
	}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6165
	mutex_exit(&zone->zone_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6166
	zone_rele(zone);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6167
	return (err == 0 ? 0 : set_errno(err));
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6168
}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6169
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6170
/*
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6171
 * Using the zoneidp as ALL_ZONES, we can lookup which zone has been assigned
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6172
 * the linkid.  Otherwise we just check if the specified zoneidp has been
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6173
 * assigned the supplied linkid.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6174
 */
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6175
int
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6176
zone_check_datalink(zoneid_t *zoneidp, datalink_id_t linkid)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6177
{
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6178
	zone_t *zone;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6179
	int err = ENXIO;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6180
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6181
	if (*zoneidp != ALL_ZONES) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6182
		if ((zone = zone_find_by_id(*zoneidp)) != NULL) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6183
			if (zone_dl_exists(zone, linkid))
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6184
				err = 0;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6185
			zone_rele(zone);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6186
		}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6187
		return (err);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6188
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6189
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6190
	mutex_enter(&zonehash_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6191
	for (zone = list_head(&zone_active); zone != NULL;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6192
	    zone = list_next(&zone_active, zone)) {
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6193
		if (zone_dl_exists(zone, linkid)) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6194
			*zoneidp = zone->zone_id;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6195
			err = 0;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6196
			break;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6197
		}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6198
	}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6199
	mutex_exit(&zonehash_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6200
	return (err);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6201
}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6202
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6203
/*
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6204
 * Get the list of datalink IDs assigned to a zone.
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6205
 *
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6206
 * On input, *nump is the number of datalink IDs that can fit in the supplied
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6207
 * idarray.  Upon return, *nump is either set to the number of datalink IDs
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6208
 * that were placed in the array if the array was large enough, or to the
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6209
 * number of datalink IDs that the function needs to place in the array if the
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6210
 * array is too small.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6211
 */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6212
static int
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6213
zone_list_datalink(zoneid_t zoneid, int *nump, datalink_id_t *idarray)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6214
{
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6215
	uint_t num, dlcount;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6216
	zone_t *zone;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6217
	zone_dl_t *zdl;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6218
	datalink_id_t *idptr = idarray;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6219
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6220
	if (copyin(nump, &dlcount, sizeof (dlcount)) != 0)
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6221
		return (set_errno(EFAULT));
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6222
	if ((zone = zone_find_by_id(zoneid)) == NULL)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6223
		return (set_errno(ENXIO));
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6224
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6225
	num = 0;
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6226
	mutex_enter(&zone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6227
	for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6228
	    zdl = list_next(&zone->zone_dl_list, zdl)) {
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6229
		/*
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6230
		 * If the list is bigger than what the caller supplied, just
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6231
		 * count, don't do copyout.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6232
		 */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6233
		if (++num > dlcount)
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6234
			continue;
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6235
		if (copyout(&zdl->zdl_id, idptr, sizeof (*idptr)) != 0) {
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6236
			mutex_exit(&zone->zone_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6237
			zone_rele(zone);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6238
			return (set_errno(EFAULT));
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6239
		}
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6240
		idptr++;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6241
	}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6242
	mutex_exit(&zone->zone_lock);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6243
	zone_rele(zone);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6244
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6245
	/* Increased or decreased, caller should be notified. */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6246
	if (num != dlcount) {
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6247
		if (copyout(&num, nump, sizeof (num)) != 0)
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6248
			return (set_errno(EFAULT));
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6249
	}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6250
	return (0);
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6251
}
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6252
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6253
/*
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6254
 * Public interface for looking up a zone by zoneid. It's a customized version
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6255
 * for netstack_zone_create(). It can only be called from the zsd create
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6256
 * callbacks, since it doesn't have reference on the zone structure hence if
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6257
 * it is called elsewhere the zone could disappear after the zonehash_lock
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6258
 * is dropped.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6259
 *
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6260
 * Furthermore it
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6261
 * 1. Doesn't check the status of the zone.
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6262
 * 2. It will be called even before zone_init is called, in that case the
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6263
 *    address of zone0 is returned directly, and netstack_zone_create()
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6264
 *    will only assign a value to zone0.zone_netstack, won't break anything.
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6265
 * 3. Returns without the zone being held.
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6266
 */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6267
zone_t *
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6268
zone_find_by_id_nolock(zoneid_t zoneid)
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6269
{
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6270
	zone_t *zone;
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6271
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6272
	mutex_enter(&zonehash_lock);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6273
	if (zonehashbyid == NULL)
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6274
		zone = &zone0;
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6275
	else
5880
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6276
		zone = zone_find_all_by_id(zoneid);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6277
	mutex_exit(&zonehash_lock);
3f55db3cd80f 6558857 ZSD callback locking cause deadlocks
nordmark
parents: 5753
diff changeset
  6278
	return (zone);
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3446
diff changeset
  6279
}
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6280
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6281
/*
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6282
 * Walk the datalinks for a given zone
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6283
 */
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6284
int
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6285
zone_datalink_walk(zoneid_t zoneid, int (*cb)(datalink_id_t, void *),
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6286
    void *data)
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6287
{
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6288
	zone_t		*zone;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6289
	zone_dl_t	*zdl;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6290
	datalink_id_t	*idarray;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6291
	uint_t		idcount = 0;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6292
	int		i, ret = 0;
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6293
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6294
	if ((zone = zone_find_by_id(zoneid)) == NULL)
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6295
		return (ENOENT);
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6296
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6297
	/*
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6298
	 * We first build an array of linkid's so that we can walk these and
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6299
	 * execute the callback with the zone_lock dropped.
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6300
	 */
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6301
	mutex_enter(&zone->zone_lock);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6302
	for (zdl = list_head(&zone->zone_dl_list); zdl != NULL;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6303
	    zdl = list_next(&zone->zone_dl_list, zdl)) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6304
		idcount++;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6305
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6306
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6307
	if (idcount == 0) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6308
		mutex_exit(&zone->zone_lock);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6309
		zone_rele(zone);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6310
		return (0);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6311
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6312
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6313
	idarray = kmem_alloc(sizeof (datalink_id_t) * idcount, KM_NOSLEEP);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6314
	if (idarray == NULL) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6315
		mutex_exit(&zone->zone_lock);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6316
		zone_rele(zone);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6317
		return (ENOMEM);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6318
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6319
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6320
	for (i = 0, zdl = list_head(&zone->zone_dl_list); zdl != NULL;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6321
	    i++, zdl = list_next(&zone->zone_dl_list, zdl)) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6322
		idarray[i] = zdl->zdl_id;
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6323
	}
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6324
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6325
	mutex_exit(&zone->zone_lock);
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6326
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6327
	for (i = 0; i < idcount && ret == 0; i++) {
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6328
		if ((ret = (*cb)(idarray[i], data)) != 0)
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6329
			break;
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6330
	}
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6331
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6332
	zone_rele(zone);
10616
3be00c4a6835 PSARC 2009/373 Clearview IP Tunneling
Sebastien Roy <Sebastien.Roy@Sun.COM>
parents: 9160
diff changeset
  6333
	kmem_free(idarray, sizeof (datalink_id_t) * idcount);
5895
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6334
	return (ret);
f251acdd9bdc PSARC/2006/499 Clearview Nemo unification and vanity naming
yz147064
parents: 5880
diff changeset
  6335
}