src/zoneproxy/zoneproxyd/zoneproxyd.c
author Andrzej Szeszo <aszeszo@gmail.com>
Wed, 01 Jun 2011 13:04:21 +0100
changeset 2389 30ea7b982e91
parent 2349 4b4ff1617157
permissions -rw-r--r--
Make zoneproxy to compile on OI 151
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     1
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     2
 * CDDL HEADER START
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     3
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     7
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    11
 * and limitations under the License.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    12
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    18
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    19
 * CDDL HEADER END
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    20
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    21
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    22
 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    23
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    24
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    25
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    26
 * The zone proxy daemon and zone proxy client.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    27
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    28
 * For package operations in zones, the system must make available a certain
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    29
 * group of publishers and repositories to client zones.  This ensures that data
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    30
 * necessary for installing or updating a zone is always available to zones
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    31
 * consumers, regardless of the exact network configuration within the local
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    32
 * zone.  In order to accomplish this, the proxy daemon and proxy client provide
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    33
 * a TCP proxy to a special repository that is maintained in the global zone.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    34
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    35
 * The zone-proxy client is responsible for creating a listening TCP socket in a
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    36
 * pre-determined location, and then passing control of that socket to the proxy
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    37
 * daemon.  Once the proxy client has completed this hand-off, it sleeps in the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    38
 * local zone, waiting for notification of any changes in the global zone.  If
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    39
 * the proxy daemon exits, or is re-configured, the proxy client creates a new
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    40
 * socket, and the process is repeated.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    41
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    42
 * The proxy daemon listens on the sockets passed to it by the proxy client, and
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    43
 * when it gets a new connection, establishes a connection to the zones
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    44
 * repository that serves packaging information.  The proxy daemon and client
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    45
 * pass information through a door.  The daemon also listens for notifications
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    46
 * about zone startup and shutdown on the door.  (zoneadmd, knows to poke the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    47
 * daemon when zones are created or destroyed).  When a zone is created, the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    48
 * proxy daemon enters the zone, and creates a new door there, so that the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    49
 * client and daemon can rendezvous.  The proxy daemon manages a pool of thread
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    50
 * workers for handling network connections, and has some door callbacks to
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    51
 * manage a pool of IPC threads.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    52
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    53
 * Each new connection generates a pair of sockets.  The data transfer algorithm
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    54
 * here is lockless, and depends upon event ports as the polling mechanism.  The
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    55
 * socket is dup'd, and one is always used for reading, and the other always
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    56
 * used for writing.  As long as no thread reads and writes the same fd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    57
 * operation is atomic, and correct.  When a thread needs data, the event
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    58
 * mechanism is used either to wait for data, or to wait to write data.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    59
 * Although each proxy connection has a buffer, we try our best to drain that
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    60
 * buffer ASAP, especially before getting more data.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    61
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    62
#include <alloca.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    63
#include <atomic.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    64
#include <door.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    65
#include <errno.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    66
#include <fcntl.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    67
#include <libcontract.h>
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
    68
#include <libscf.h>
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    69
#include <limits.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    70
#include <netdb.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    71
#include <port.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    72
#include <priv.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    73
#include <pthread.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    74
#include <synch.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    75
#include <signal.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    76
#include <stddef.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    77
#include <stdio.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    78
#include <stdlib.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    79
#include <string.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    80
#include <stropts.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    81
#include <thread.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    82
#include <ucred.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    83
#include <unistd.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    84
#include <zone.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    85
#include <zoneproxy_impl.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    86
#include <sys/ctfs.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    87
#include <sys/contract/process.h>
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
    88
#include <sys/queue.h>
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    89
#include <sys/resource.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    90
#include <sys/socket.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    91
#include <sys/stat.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    92
#include <sys/sysmacros.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    93
#include <sys/types.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    94
#include <sys/wait.h>
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    95
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    96
#define	PROXY_THREAD_DEFAULT		8
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    97
#define	PROXY_THREAD_MAX		20
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    98
#define	DOOR_THREAD_MAX			5
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
    99
#define	DEFAULT_LOCK_ALIGN		64
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   100
#define	DEFAULT_TIMEOUT			30
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   101
#define	TIMEOUT_COUNT			4
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   102
#define	MAX_FDS_DEFAULT			6000
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   103
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   104
#define	SYSREPO_FMRI    "svc:/application/pkg/system-repository:default"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   105
#define	SYSREPO_PG      "config"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   106
#define	SYSREPO_HOST    "host"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   107
#define	SYSREPO_PORT    "port"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   108
#define	DEFAULT_HOST	"127.0.0.1"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   109
#define	DEFAULT_PORT	"1008"
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   110
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   111
#define	BUFFER_SIZ		8168
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   112
#define	CONF_STR_SZ		2048
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   113
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   114
typedef enum {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   115
	PROXY_USER_GENERIC = 0,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   116
	PROXY_USER_LISTENER,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   117
	PROXY_USER_PAIR,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   118
	PROXY_USER_END
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   119
} pu_type_t;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   120
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   121
typedef enum {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   122
	PROXY_STATE_INIT = 0,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   123
	PROXY_STATE_WAIT_CONNECT,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   124
	PROXY_STATE_WAIT_DATA,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   125
	PROXY_STATE_CLOSING,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   126
	PROXY_STATE_FREED,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   127
	PROXY_STATE_END
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   128
} proxy_state_t;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   129
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   130
/* structure definitions */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   131
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   132
struct proxy_user {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   133
	pu_type_t	pu_type;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   134
	void		(*pu_callback)(struct proxy_user *, port_event_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   135
};
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   136
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   137
struct proxy_listener {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   138
	pu_type_t	pl_type;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   139
	void		(*pl_callback)(struct proxy_listener *, port_event_t *);
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   140
	TAILQ_ENTRY(proxy_listener) pl_list_link;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   141
	zoneid_t	pl_zid;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   142
	int		pl_fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   143
	mutex_t		pl_lock;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   144
	boolean_t	pl_cleanup;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   145
	int		pl_pipefd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   146
	int		pl_closefd;
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   147
	char		*pl_proxy_host;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   148
	char		*pl_proxy_port;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   149
	uint64_t	pl_gen;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   150
};
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   151
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   152
struct proxy_pair {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   153
	pu_type_t	pp_type;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   154
	void		(*pp_callback)(struct proxy_pair *, port_event_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   155
	int		pp_readfd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   156
	int		pp_writefd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   157
	size_t		pp_fbcnt;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   158
	proxy_state_t	pp_state;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   159
	char		pp_buffer[BUFFER_SIZ];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   160
};
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   161
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   162
struct proxy_config {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   163
	mutex_t			pc_lock;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   164
	scf_handle_t		*pc_hdl;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   165
	scf_instance_t		*pc_inst;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   166
	scf_propertygroup_t	*pc_pg;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   167
	scf_property_t		*pc_prop;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   168
	scf_value_t		*pc_val;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   169
	char			*pc_proxy_host;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   170
	char			*pc_proxy_port;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   171
	uint64_t		pc_gen;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   172
};
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   173
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   174
/* global variables */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   175
int		g_port;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   176
int		g_door;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   177
int		g_pipe_fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   178
int		g_max_door_thread = DOOR_THREAD_MAX;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   179
int		g_door_thread_count = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   180
uint_t		g_proxy_pair_count = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   181
thread_key_t	g_thr_info_key;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   182
mutex_t		*g_door_thr_lock;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   183
mutex_t		*g_listener_lock;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   184
mutex_t		*g_thr_pool_lock;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   185
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   186
/* global variables protected by g_thr_pool_lock */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   187
int		g_tp_running_threads;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   188
int		g_tp_exited_threads;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   189
int		g_tp_max_threads = PROXY_THREAD_MAX;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   190
int		g_tp_min_threads = PROXY_THREAD_DEFAULT;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   191
cond_t		g_thr_pool_cv = DEFAULTCV;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   192
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   193
/* global variables shared between main thread and s_handler thread */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   194
mutex_t		g_quit_lock = DEFAULTMUTEX;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   195
cond_t		g_quit_cv = DEFAULTCV;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   196
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   197
/* proxy config protected by internal lock */
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   198
struct proxy_config	*g_proxy_config;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   199
boolean_t		g_config_smf;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   200
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   201
TAILQ_HEAD(zq_queuehead, proxy_listener);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   202
struct zq_queuehead	zone_listener_list;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   203
static volatile boolean_t g_quit;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   204
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   205
/* function declarations */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   206
static struct proxy_listener *alloc_proxy_listener(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   207
static struct proxy_pair *alloc_proxy_pair(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   208
static int check_connect(struct proxy_pair *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   209
static int clone_and_register(struct proxy_pair *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   210
static void close_door_descs(door_desc_t *, uint_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   211
static int close_on_exec(int);
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   212
static struct proxy_config *config_alloc(void);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   213
static void config_free(struct proxy_config *);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   214
static int config_read(struct proxy_config *);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   215
static int contract_abandon_id(ctid_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   216
static int contract_latest(ctid_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   217
static int contract_open(ctid_t, const char *, const char *, int);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   218
static void daemonize_ready(char);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   219
static int daemonize_start(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   220
static int do_fattach(int, char *, boolean_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   221
static void drop_privs(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   222
static void escalate_privs(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   223
static void fattach_all_zones(boolean_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   224
static void free_proxy_listener(struct proxy_listener *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   225
static void free_proxy_pair(struct proxy_pair *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   226
static int init_template(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   227
static void listen_func(struct proxy_listener *, port_event_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   228
static void proxy_func(struct proxy_pair *, port_event_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   229
static void *proxy_thread_loop(void *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   230
static void s_handler(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   231
static int send_recv_data(struct proxy_pair *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   232
static void shutdown_proxypair(struct proxy_pair *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   233
static void thread_exiting(void *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   234
static void *thread_manager(void *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   235
static void usage(void);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   236
static int zpd_add_listener(zoneid_t, int, int, int);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   237
static void zpd_door_create_thread(door_info_t *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   238
static void *zpd_door_loop(void *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   239
static void zpd_door_server(void *, char *, size_t, door_desc_t *, uint_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   240
static void zpd_fattach_zone(zoneid_t, int, boolean_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   241
static struct proxy_listener *zpd_find_listener(zoneid_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   242
static void zpd_listener_cleanup(struct proxy_listener *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   243
static int zpd_perm_check(int, zoneid_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   244
static void zpd_remove_listener(struct proxy_listener *);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   245
static int zpd_remove_zone(zoneid_t);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   246
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   247
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   248
usage(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   249
{
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   250
	(void) fprintf(stderr, "Usage: zoneproxyd [-s host:port]\n");
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   251
	exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   252
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   253
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   254
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   255
set_noblocking(int fd)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   256
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   257
	int		flags;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   258
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   259
	if ((flags = fcntl(fd, F_GETFL, 0)) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   260
		perror("fcntl (GETFL)");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   261
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   262
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   263
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   264
	if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   265
		perror("fcntl (SETFL)");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   266
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   267
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   268
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   269
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   270
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   271
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   272
static struct proxy_listener *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   273
alloc_proxy_listener(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   274
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   275
	struct proxy_listener	*listener;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   276
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   277
	listener = malloc(sizeof (struct proxy_listener));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   278
	if (listener == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   279
		perror("malloc");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   280
		return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   281
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   282
	(void) memset(listener, 0, sizeof (struct proxy_listener));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   283
	listener->pl_type = PROXY_USER_LISTENER;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   284
	listener->pl_callback = listen_func;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   285
	listener->pl_fd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   286
	listener->pl_pipefd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   287
	listener->pl_closefd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   288
	listener->pl_cleanup = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   289
	if (mutex_init(&listener->pl_lock, USYNC_THREAD, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   290
		perror("mutex_init");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   291
		return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   292
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   293
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   294
	return (listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   295
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   296
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   297
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   298
static struct proxy_pair *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   299
alloc_proxy_pair(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   300
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   301
	struct proxy_pair	*pair;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   302
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   303
	pair = malloc(sizeof (struct proxy_pair));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   304
	if (pair == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   305
		perror("malloc");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   306
		return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   307
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   308
	(void) memset(pair, 0, sizeof (struct proxy_pair));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   309
	pair->pp_type = PROXY_USER_PAIR;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   310
	pair->pp_callback = proxy_func;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   311
	pair->pp_readfd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   312
	pair->pp_writefd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   313
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   314
	return (pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   315
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   316
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   317
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   318
free_proxy_listener(struct proxy_listener *listener)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   319
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   320
	if (listener->pl_fd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   321
		if (close(listener->pl_fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   322
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   323
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   324
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   325
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   326
	if (listener->pl_pipefd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   327
		if (close(listener->pl_pipefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   328
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   329
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   330
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   331
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   332
	if (listener->pl_closefd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   333
		if (close(listener->pl_closefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   334
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   335
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   336
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   337
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   338
	(void) mutex_destroy(&listener->pl_lock);
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   339
	free(listener->pl_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   340
	free(listener->pl_proxy_port);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   341
	free(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   342
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   343
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   344
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   345
free_proxy_pair(struct proxy_pair *pair)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   346
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   347
	if (pair->pp_readfd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   348
		if (close(pair->pp_readfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   349
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   350
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   351
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   352
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   353
	if (pair->pp_writefd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   354
		if (close(pair->pp_writefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   355
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   356
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   357
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   358
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   359
	pair->pp_state = PROXY_STATE_FREED;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   360
	free(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   361
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   362
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   363
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   364
 * Once a pair has been connected, dup the file descriptors, switching read and
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   365
 * write, so that both pair can be seperately queued for events.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   366
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   367
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   368
clone_and_register(struct proxy_pair *pair)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   369
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   370
	struct proxy_pair	*op_pair;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   371
	int			fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   372
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   373
	/* Allocate another proxy_pair object */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   374
	op_pair = alloc_proxy_pair();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   375
	if (op_pair == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   376
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   377
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   378
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   379
	/* Copy state */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   380
	op_pair->pp_state = pair->pp_state;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   381
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   382
	/* Dup fd's switching read for write */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   383
	if ((fd = dup(pair->pp_readfd)) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   384
		perror("dup");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   385
		free_proxy_pair(op_pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   386
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   387
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   388
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   389
	op_pair->pp_writefd = fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   390
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   391
	if ((fd = dup(pair->pp_writefd)) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   392
		perror("dup");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   393
		free_proxy_pair(op_pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   394
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   395
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   396
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   397
	op_pair->pp_readfd = fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   398
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   399
	/* Register each pair to wait for input */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   400
	if (port_associate(g_port, PORT_SOURCE_FD, op_pair->pp_readfd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   401
	    POLLIN, op_pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   402
		perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   403
		free_proxy_pair(op_pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   404
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   405
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   406
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   407
	if (port_associate(g_port, PORT_SOURCE_FD, pair->pp_readfd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   408
	    POLLIN, pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   409
		perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   410
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   411
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   412
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   413
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   414
	 * Increment the proxy count by two, since there are two proxy-pair
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   415
	 * objects per connection, each representing one direction of the flow.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   416
	 * The objects are shutdown separately, so each will decrment the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   417
	 * count by one in its shutdown method.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   418
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   419
	atomic_add_int(&g_proxy_pair_count, 2);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   420
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   421
	 * Try to poke the thread manager.  If someone else is poking him, or
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   422
	 * he's already running, just return.  In the worst case the manager
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   423
	 * will double-check the number of threads after the timeout.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   424
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   425
	if (mutex_trylock(g_thr_pool_lock) == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   426
		(void) cond_signal(&g_thr_pool_cv);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   427
		(void) mutex_unlock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   428
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   429
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   430
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   431
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   432
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   433
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   434
shutdown_proxypair(struct proxy_pair *pair)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   435
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   436
	(void) port_dissociate(g_port, PORT_SOURCE_FD, pair->pp_readfd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   437
	(void) port_dissociate(g_port, PORT_SOURCE_FD, pair->pp_writefd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   438
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   439
	if (pair->pp_fbcnt > 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   440
		(void) write(pair->pp_writefd, pair->pp_buffer, pair->pp_fbcnt);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   441
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   442
	(void) shutdown(pair->pp_readfd, SHUT_RD);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   443
	(void) shutdown(pair->pp_writefd, SHUT_WR);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   444
	free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   445
	atomic_dec_uint(&g_proxy_pair_count);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   446
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   447
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   448
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   449
send_recv_data(struct proxy_pair *pair)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   450
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   451
	int	b_wr;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   452
	int	b_rd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   453
	int	read_needed = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   454
	int	write_needed = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   455
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   456
	if (pair->pp_fbcnt == 0) /* need to read */ {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   457
		b_rd = read(pair->pp_readfd, pair->pp_buffer, BUFFER_SIZ);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   458
		if (b_rd < 0 && (errno == EAGAIN || errno == EWOULDBLOCK ||
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   459
		    errno == EINTR)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   460
			b_rd = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   461
			read_needed = 1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   462
		} else if (b_rd <= 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   463
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   464
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   465
		pair->pp_fbcnt = b_rd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   466
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   467
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   468
	if (pair->pp_fbcnt > 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   469
		b_wr = write(pair->pp_writefd, pair->pp_buffer, pair->pp_fbcnt);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   470
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   471
		if (b_wr < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   472
			if (errno != EAGAIN && errno != EWOULDBLOCK) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   473
				return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   474
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   475
			b_wr = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   476
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   477
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   478
		if (b_wr < pair->pp_fbcnt) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   479
			if (b_wr != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   480
				(void) memmove(pair->pp_buffer,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   481
				    pair->pp_buffer + b_wr,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   482
				    pair->pp_fbcnt - b_wr);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   483
				pair->pp_fbcnt -= b_wr;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   484
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   485
			write_needed = 1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   486
			/* If the write side is slow, disable read here */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   487
			read_needed = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   488
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   489
			pair->pp_fbcnt = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   490
			read_needed = 1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   491
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   492
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   493
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   494
	if (read_needed) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   495
		if (port_associate(g_port, PORT_SOURCE_FD, pair->pp_readfd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   496
		    POLLIN, pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   497
			perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   498
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   499
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   500
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   501
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   502
	if (write_needed) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   503
		if (port_associate(g_port, PORT_SOURCE_FD, pair->pp_writefd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   504
		    POLLOUT, pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   505
			perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   506
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   507
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   508
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   509
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   510
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   511
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   512
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   513
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   514
static void *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   515
proxy_thread_loop(void *arg)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   516
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   517
	port_event_t ev;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   518
	struct proxy_user *pu;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   519
	int timeouts = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   520
	timespec_t tmot;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   521
	boolean_t timed_out = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   522
	boolean_t should_exit = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   523
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   524
	for (;;) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   525
		tmot.tv_sec = DEFAULT_TIMEOUT;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   526
		tmot.tv_nsec = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   527
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   528
		if (port_get(g_port, &ev, &tmot) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   529
			if (errno == ETIME) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   530
				timed_out = B_TRUE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   531
				timeouts++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   532
			} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   533
				/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   534
				 * Unexpected error.  Adjust thread
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   535
				 * bean counters and exit.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   536
				 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   537
				(void) mutex_lock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   538
				g_tp_exited_threads++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   539
				g_tp_running_threads--;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   540
				(void) cond_signal(&g_thr_pool_cv);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   541
				(void) mutex_unlock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   542
				perror("port_get");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   543
				thr_exit(NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   544
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   545
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   546
			timeouts = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   547
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   548
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   549
		/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   550
		 * Reached timeout count. Check to see if thread
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   551
		 * should exit.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   552
		 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   553
		if (timed_out && timeouts > TIMEOUT_COUNT) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   554
			(void) mutex_lock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   555
			if ((g_proxy_pair_count < g_tp_running_threads) &&
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   556
			    (g_tp_running_threads > g_tp_min_threads)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   557
				g_tp_exited_threads++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   558
				g_tp_running_threads--;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   559
				should_exit = B_TRUE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   560
				(void) cond_signal(&g_thr_pool_cv);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   561
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   562
			(void) mutex_unlock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   563
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   564
			if (should_exit) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   565
				thr_exit(NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   566
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   567
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   568
			/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   569
			 * Reached timeout count, but not allowed to
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   570
			 * exit.  Reset counters and continue.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   571
			 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   572
			timed_out = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   573
			timeouts = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   574
			continue;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   575
		} else if (timed_out) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   576
			/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   577
			 * If port_get timed out, but this thread hasn't
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   578
			 * reached its timeout count just continue.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   579
			 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   580
			timed_out = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   581
			continue;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   582
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   583
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   584
		/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   585
		 * Event handling code.  This is what we do when we don't
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   586
		 * timeout.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   587
		 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   588
		if (ev.portev_source == PORT_SOURCE_FD) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   589
			pu = (struct proxy_user *)ev.portev_user;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   590
			pu->pu_callback(pu, &ev);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   591
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   592
			/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   593
			 * Exit requested. Don't bother adjusting counters
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   594
			 * since cleanup here is handled by main thread,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   595
			 * not manager thread.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   596
			 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   597
			break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   598
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   599
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   600
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   601
	return (arg);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   602
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   603
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   604
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   605
check_connect(struct proxy_pair *pair)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   606
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   607
	int error;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   608
	socklen_t len;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   609
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   610
	len = sizeof(error);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   611
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   612
	if (getsockopt(pair->pp_writefd, SOL_SOCKET, SO_ERROR, &error,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   613
	    &len) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   614
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   615
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   616
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   617
	if (error) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   618
		errno = error;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   619
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   620
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   621
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   622
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   623
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   624
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   625
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   626
proxy_func(struct proxy_pair *pair, port_event_t *ev)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   627
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   628
	int	rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   629
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   630
	if (ev->portev_events & (POLLERR | POLLHUP | POLLNVAL)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   631
		pair->pp_state = PROXY_STATE_CLOSING;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   632
		shutdown_proxypair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   633
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   634
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   635
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   636
	switch (pair->pp_state) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   637
	case PROXY_STATE_WAIT_CONNECT:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   638
		rc = check_connect(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   639
		if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   640
			/* break out early if connect failed */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   641
			break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   642
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   643
		pair->pp_state = PROXY_STATE_WAIT_DATA;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   644
		rc = clone_and_register(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   645
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   646
	case PROXY_STATE_WAIT_DATA:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   647
		rc = send_recv_data(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   648
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   649
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   650
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   651
	if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   652
		pair->pp_state = PROXY_STATE_CLOSING;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   653
		shutdown_proxypair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   654
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   655
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   656
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   657
/* ARGSUSED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   658
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   659
listen_func(struct proxy_listener *listener, port_event_t *ev)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   660
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   661
	struct proxy_pair	*pair;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   662
	int			newffd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   663
	int			newbfd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   664
	int			err_code;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   665
	struct addrinfo		hints;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   666
	struct addrinfo		*ai = NULL;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   667
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   668
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   669
	 * Hold listener's lock, check if cleanup has been requested.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   670
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   671
	(void) mutex_lock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   672
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   673
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   674
	 * pl_closefd is the other half of the pipe that we weren't able
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   675
	 * to close before calling door_return.  Close it now, if it's set to
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   676
	 * something that's a fd.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   677
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   678
	if (listener->pl_closefd > -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   679
		if (close(listener->pl_closefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   680
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   681
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   682
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   683
		listener->pl_closefd = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   684
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   685
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   686
	if (listener->pl_cleanup) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   687
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   688
		zpd_remove_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   689
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   690
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   691
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   692
	newffd = accept(listener->pl_fd, NULL, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   693
	if (newffd < 0 && (errno == ECONNABORTED || errno == EINTR ||
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   694
	    errno == EWOULDBLOCK)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   695
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   696
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   697
	} else if (newffd < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   698
		perror("accept");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   699
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   700
		(void) zpd_remove_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   701
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   702
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   703
	(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   704
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   705
	pair = alloc_proxy_pair();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   706
	if (pair == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   707
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   708
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   709
	pair->pp_readfd = newffd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   710
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   711
	/* mark newffd as non-blocking */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   712
	if (set_noblocking(newffd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   713
		free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   714
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   715
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   716
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   717
	(void) memset(&hints, 0, sizeof (struct addrinfo));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   718
	hints.ai_flags = AI_ADDRCONFIG;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   719
	hints.ai_family = PF_UNSPEC;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   720
	hints.ai_socktype = SOCK_STREAM;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   721
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   722
	/* If proxy config has changed, pull the new info into the listener. */
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   723
	if (g_proxy_config->pc_gen > listener->pl_gen) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   724
		mutex_lock(&g_proxy_config->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   725
		free(listener->pl_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   726
		free(listener->pl_proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   727
		listener->pl_proxy_host = strdup(g_proxy_config->pc_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   728
		listener->pl_proxy_port = strdup(g_proxy_config->pc_proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   729
		if (listener->pl_proxy_host == NULL ||
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   730
		    listener->pl_proxy_port == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   731
			(void) fprintf(stderr, "Unable to allocate memory for "
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   732
			    "listener configuration.\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   733
			exit(EXIT_FAILURE);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   734
		}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   735
		listener->pl_gen = g_proxy_config->pc_gen;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   736
		mutex_unlock(&g_proxy_config->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   737
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   738
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   739
	if ((err_code = getaddrinfo(listener->pl_proxy_host,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   740
	    listener->pl_proxy_port, &hints, &ai)) != 0) {
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   741
		(void) fprintf(stderr, "zoneproxyd: Unable to "
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   742
		    "perform name lookup\n");
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
   743
		(void) fprintf(stderr, "%s: %s\n", listener->pl_proxy_host,
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   744
		    gai_strerror(err_code));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   745
		free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   746
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   747
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   748
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   749
	if ((newbfd = socket(ai->ai_family, SOCK_STREAM, 0)) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   750
		perror("socket");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   751
		free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   752
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   753
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   754
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   755
	/* mark newbfd as non-blocking */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   756
	if (set_noblocking(newbfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   757
		if (close(newbfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   758
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   759
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   760
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   761
		free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   762
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   763
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   764
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   765
	/* Connect to the proxy backend */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   766
	err_code = connect(newbfd, ai->ai_addr, ai->ai_addrlen);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   767
	if (err_code < 0 && errno == EINPROGRESS) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   768
		pair->pp_state = PROXY_STATE_WAIT_CONNECT;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   769
		pair->pp_writefd = newbfd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   770
		/* receipt of POLLOUT means we're connected */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   771
		if (port_associate(g_port, PORT_SOURCE_FD, pair->pp_writefd,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   772
		    POLLOUT, pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   773
			perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   774
			if (close(newbfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   775
				perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   776
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   777
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   778
			free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   779
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   780
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   781
	} else if (err_code < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   782
		/* Error, cleanup */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   783
		if (close(newbfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   784
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   785
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   786
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   787
		free_proxy_pair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   788
		goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   789
	} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   790
		/* connected without waiting! */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   791
		pair->pp_state = PROXY_STATE_WAIT_DATA;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   792
		pair->pp_writefd = newbfd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   793
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   794
		if (clone_and_register(pair) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   795
			pair->pp_state = PROXY_STATE_CLOSING;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   796
			shutdown_proxypair(pair);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   797
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   798
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   799
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   800
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   801
out:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   802
	if (ai) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   803
		freeaddrinfo(ai);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   804
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   805
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   806
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   807
	 * Check to make sure that cleanup hasn't been requested before calling
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   808
	 * port_associate to get another connection.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   809
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   810
	(void) mutex_lock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   811
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   812
	if (listener->pl_cleanup) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   813
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   814
		zpd_remove_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   815
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   816
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   817
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   818
	/* re-associate listener; accept further connections */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   819
	if (port_associate(g_port, PORT_SOURCE_FD, listener->pl_fd, POLLIN,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   820
	    listener) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   821
		perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   822
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   823
		zpd_remove_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   824
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   825
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   826
	(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   827
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   828
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   829
/* ARGSUSED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   830
static void *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   831
zpd_door_loop(void *arg)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   832
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   833
	thread_t *tid;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   834
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   835
	/* Bind to door's private pool */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   836
	if (door_bind(g_door) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   837
		perror("door_bind");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   838
		return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   839
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   840
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   841
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   842
	 * Disable cancellation.  Solaris threads have no cancellation
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   843
	 * mechanism, but are interchangeable with PThreads.  This means we must
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   844
	 * use the pthread interface to disable cancellation.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   845
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   846
	(void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   847
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   848
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   849
	 * Threads use the thr_keycreate interface to register a destructor.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   850
	 * The destructor allows us to decrement the door thread count when a
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   851
	 * thread exits.  In order for the destructor to be called, each thread
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   852
	 * must register a non-NULL value through thr_setspecfic.  Do this
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   853
	 * here.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   854
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   855
	tid = malloc(sizeof (thread_t));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   856
	if (tid == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   857
		perror("malloc");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   858
		return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   859
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   860
	*tid = thr_self();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   861
	(void) thr_setspecific(g_thr_info_key, tid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   862
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   863
	/* Invoke door_return to wait for door_call. */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   864
	(void) door_return(NULL, 0, NULL, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   865
	return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   866
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   867
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   868
/* ARGSUSED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   869
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   870
thread_exiting(void *arg)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   871
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   872
	free(arg);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   873
	(void) mutex_lock(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   874
	g_door_thread_count--;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   875
	(void) mutex_unlock(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   876
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   877
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   878
/* ARGSUSED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   879
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   880
zpd_door_create_thread(door_info_t *dip)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   881
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   882
	int rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   883
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   884
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   885
	 * Only create threads for DOOR_PRIVATE pools.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   886
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   887
	if (dip == NULL)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   888
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   889
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   890
	(void) mutex_lock(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   891
	if (g_door_thread_count < g_max_door_thread && !g_quit) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   892
		rc = thr_create(NULL, 0, zpd_door_loop, NULL, THR_DAEMON,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   893
		    NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   894
		if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   895
			perror("thr_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   896
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   897
			g_door_thread_count++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   898
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   899
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   900
	(void) mutex_unlock(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   901
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   902
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   903
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   904
 * Thread responsible for creating/joining proxy threads
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   905
 * during normal operation of zoneproxyd.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   906
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   907
static void *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   908
thread_manager(void *arg)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   909
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   910
	int i;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   911
	int rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   912
	int nthr = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   913
	timestruc_t tmo;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   914
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   915
	(void) mutex_lock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   916
	g_tp_exited_threads = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   917
	g_tp_running_threads = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   918
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   919
	/* Start proxy threads */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   920
	for (i = 0; i < g_tp_min_threads; i++) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   921
		rc = thr_create(NULL, 0, proxy_thread_loop, NULL,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   922
		    THR_BOUND, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   923
		if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   924
			perror("thr_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   925
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   926
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   927
		g_tp_running_threads++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   928
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   929
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   930
	/* Loop waiting for threads to exit, or need to be started */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   931
	for (;;) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   932
		if (g_quit == B_TRUE) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   933
			break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   934
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   935
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   936
		while (g_tp_exited_threads > 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   937
			if (thr_join(0, NULL, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   938
				perror("thr_join");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   939
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   940
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   941
			g_tp_exited_threads--;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   942
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   943
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   944
		/* Compute number of threads to create, if any */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   945
		if (g_tp_running_threads < g_tp_min_threads) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   946
			nthr = g_tp_min_threads - g_tp_running_threads;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   947
		} else if ((g_tp_running_threads < g_tp_max_threads) &&
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   948
		    (g_proxy_pair_count > g_tp_running_threads)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   949
			nthr = MIN(g_proxy_pair_count,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   950
			    g_tp_max_threads - g_tp_running_threads);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   951
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   952
			nthr = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   953
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   954
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   955
		for (i = 0; i < nthr; i++) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   956
			rc = thr_create(NULL, 0, proxy_thread_loop, NULL,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   957
			    THR_BOUND, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   958
			if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   959
				perror("thr_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   960
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   961
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   962
			g_tp_running_threads++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   963
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   964
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   965
		/* sleep, waiting for timeout or cond_signal */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   966
		tmo.tv_sec = DEFAULT_TIMEOUT;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   967
		tmo.tv_nsec = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   968
		(void) cond_reltimedwait(&g_thr_pool_cv, g_thr_pool_lock, &tmo);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   969
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   970
	(void) mutex_unlock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   971
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   972
	return (arg);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   973
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   974
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   975
/* Contract stuff for zone_enter() */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   976
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   977
init_template(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   978
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   979
	int fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   980
	int err = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   981
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   982
	fd = open(CTFS_ROOT "/process/template", O_RDWR);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   983
	if (fd == -1)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   984
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   985
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   986
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   987
	 * For now, zoneadmd doesn't do anything with the contract.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   988
	 * Deliver no events, don't inherit, and allow it to be orphaned.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   989
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   990
	err |= ct_tmpl_set_critical(fd, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   991
	err |= ct_tmpl_set_informative(fd, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   992
	err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   993
	err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   994
	if (err || ct_tmpl_activate(fd)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   995
		if (close(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   996
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   997
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   998
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
   999
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1000
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1001
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1002
	return (fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1003
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1004
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1005
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1006
 * Contract stuff for zone_enter()
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1007
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1008
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1009
contract_latest(ctid_t *id)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1010
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1011
	int cfd, r;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1012
	ct_stathdl_t st;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1013
	ctid_t result;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1014
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1015
	if ((cfd = open(CTFS_ROOT "/process/latest", O_RDONLY)) == -1)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1016
		return (errno);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1017
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1018
	if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1019
		if (close(cfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1020
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1021
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1022
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1023
		return (r);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1024
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1025
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1026
	result = ct_status_get_id(st);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1027
	ct_status_free(st);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1028
	if (close(cfd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1029
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1030
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1031
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1032
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1033
	*id = result;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1034
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1035
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1036
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1037
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1038
 * Boilerplate for contract abandon stuff.  This program doesn't currently exec
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1039
 * but this is set just in case.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1040
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1041
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1042
close_on_exec(int fd)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1043
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1044
	int flags = fcntl(fd, F_GETFD, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1045
	if ((flags != -1) && (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1))
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1046
		return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1047
	return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1048
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1049
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1050
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1051
contract_open(ctid_t ctid, const char *type, const char *file, int oflag)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1052
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1053
	char path[PATH_MAX];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1054
	int n, fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1055
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1056
	if (type == NULL)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1057
		type = "all";
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1058
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1059
	n = snprintf(path, PATH_MAX, CTFS_ROOT "/%s/%ld/%s", type, ctid, file);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1060
	if (n >= sizeof (path)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1061
		errno = ENAMETOOLONG;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1062
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1063
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1064
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1065
	fd = open(path, oflag);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1066
	if (fd != -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1067
		if (close_on_exec(fd) == -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1068
			int err = errno;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1069
			if (close(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1070
				perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1071
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1072
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1073
			errno = err;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1074
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1075
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1076
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1077
	return (fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1078
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1079
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1080
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1081
contract_abandon_id(ctid_t ctid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1082
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1083
	int fd, err;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1084
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1085
	fd = contract_open(ctid, "all", "ctl", O_WRONLY);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1086
	if (fd == -1)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1087
		return (errno);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1088
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1089
	err = ct_ctl_abandon(fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1090
	if (close(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1091
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1092
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1093
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1094
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1095
	return (err);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1096
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1097
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1098
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1099
do_fattach(int door, char *path, boolean_t detach_only)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1100
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1101
	int fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1102
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1103
	(void) fdetach(path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1104
	(void) unlink(path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1105
	if (detach_only)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1106
		return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1107
	/* Only priviliged processes should open this file */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1108
	fd = open(path, O_CREAT|O_RDWR, 0600);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1109
	if (fd < 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1110
		return (2);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1111
	if (fattach(door, path) != 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1112
		return (3);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1113
	if (close(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1114
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1115
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1116
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1117
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1118
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1119
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1120
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1121
zpd_fattach_zone(zoneid_t zid, int door, boolean_t detach_only)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1122
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1123
	char *path = ZP_DOOR_PATH;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1124
	int pid, stat, tmpl_fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1125
	ctid_t ct;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1126
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1127
	escalate_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1128
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1129
	/* Don't bother forking if fattach is happening in the global zone. */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1130
	if (zid == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1131
		int rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1132
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1133
		rc = do_fattach(door, path, detach_only);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1134
		if (rc == 2)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1135
			(void) fprintf(stderr,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1136
			    "Unable to create door file: %s\n", path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1137
		else if (rc == 3)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1138
			(void) fprintf(stderr,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1139
			    "Unable to fattach file: %s\n", path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1140
		drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1141
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1142
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1143
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1144
	if ((tmpl_fd = init_template()) == -1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1145
		(void) fprintf(stderr, "Unable to init template\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1146
		drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1147
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1148
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1149
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1150
	pid = fork1();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1151
	if (pid < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1152
		(void) ct_tmpl_clear(tmpl_fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1153
		(void) fprintf(stderr,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1154
		    "Can't fork to add zoneproxy door to zoneid %ld\n", zid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1155
		drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1156
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1157
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1158
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1159
	if (pid == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1160
		(void) ct_tmpl_clear(tmpl_fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1161
		if (close(tmpl_fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1162
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1163
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1164
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1165
		if (zone_enter(zid) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1166
			if (errno == EINVAL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1167
				_exit(EXIT_SUCCESS);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1168
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1169
			_exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1170
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1171
		_exit(do_fattach(door, path, detach_only));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1172
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1173
	if (contract_latest(&ct) == -1)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1174
		ct = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1175
	(void) ct_tmpl_clear(tmpl_fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1176
	if (close(tmpl_fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1177
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1178
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1179
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1180
	(void) contract_abandon_id(ct);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1181
	while (waitpid(pid, &stat, 0) != pid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1182
		;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1183
	if (WIFEXITED(stat) && WEXITSTATUS(stat) == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1184
		drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1185
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1186
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1187
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1188
	(void) fprintf(stderr, "Unable to attach door to zoneid: %ld\n", zid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1189
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1190
	if (WEXITSTATUS(stat) == 1)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1191
		(void) fprintf(stderr, "Cannot enter zone\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1192
	else if (WEXITSTATUS(stat) == 2)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1193
		(void) fprintf(stderr, "Unable to create door file: %s\n",
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1194
		    path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1195
	else if (WEXITSTATUS(stat) == 3)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1196
		(void) fprintf(stderr, "Unable to fattach file: %s\n", path);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1197
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1198
	(void) fprintf(stderr, "Internal error entering zone: %ld\n", zid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1199
	drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1200
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1201
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1202
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1203
fattach_all_zones(boolean_t detach_only)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1204
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1205
	zoneid_t *zids;
2389
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1206
	uint_t nzids, nzids_last;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1207
	int i;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1208
2389
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1209
again:
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1210
	(void) zone_list(NULL, &nzids);
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1211
	nzids_last = nzids;
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1212
	zids = (zoneid_t *)malloc(sizeof (zoneid_t) * nzids_last);
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1213
	if (zids == NULL)
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1214
		(void) fprintf(stderr, "Out of memory");
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1215
2389
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1216
	(void) zone_list(zids, &nzids);
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1217
	if (nzids > nzids_last) {
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1218
		free(zids);
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1219
		goto again;
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1220
    }
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1221
	for (i = 0; i < nzids; i++)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1222
		zpd_fattach_zone(zids[i], g_door, detach_only);
2389
30ea7b982e91 Make zoneproxy to compile on OI 151
Andrzej Szeszo <aszeszo@gmail.com>
parents: 2349
diff changeset
  1223
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1224
	free(zids);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1225
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1226
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1227
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1228
close_door_descs(door_desc_t *dp, uint_t ndesc)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1229
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1230
	int fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1231
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1232
	while (ndesc > 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1233
		fd = dp->d_data.d_desc.d_descriptor;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1234
		if (dp->d_attributes & DOOR_DESCRIPTOR) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1235
			if (close(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1236
				perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1237
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1238
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1239
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1240
		dp++;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1241
		ndesc--;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1242
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1243
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1244
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1245
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1246
zpd_perm_check(int cmd, zoneid_t zid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1247
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1248
	ucred_t *ucred;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1249
	zoneid_t uzid;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1250
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1251
	ucred = alloca(ucred_size());
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1252
	if (door_ucred(&ucred) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1253
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1254
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1255
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1256
	uzid = ucred_getzoneid(ucred);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1257
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1258
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1259
	 * Enforce the following permission checks:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1260
	 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1261
	 * If the command is ADD/REMOVE zone, the caller must be the global
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1262
	 * zone.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1263
	 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1264
	 * If the command is NEW_LISTENER, the caller must be a non-global zone
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1265
	 * and the supplied zoneid must match the caller's zoneid.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1266
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1267
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1268
	switch (cmd) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1269
	case ZP_CMD_PING:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1270
		/* Always OK to ping */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1271
		return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1272
	case ZP_CMD_REMOVE_LISTENER:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1273
	case ZP_CMD_NEW_LISTENER:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1274
		if (uzid == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1275
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1276
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1277
		if (uzid != zid) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1278
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1279
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1280
		return(0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1281
	case ZP_CMD_ZONE_ADDED:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1282
	case ZP_CMD_ZONE_REMOVED:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1283
		if (uzid != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1284
			return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1285
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1286
		return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1287
	default:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1288
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1289
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1290
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1291
	return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1292
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1293
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1294
static struct proxy_listener *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1295
zpd_find_listener(zoneid_t zid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1296
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1297
	struct proxy_listener *wl;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1298
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1299
	for (wl = TAILQ_FIRST(&zone_listener_list); wl != NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1300
	    wl = TAILQ_NEXT(wl, pl_list_link)) {
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1301
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1302
		if (wl->pl_zid == zid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1303
			return (wl);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1304
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1305
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1306
	return (NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1307
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1308
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1309
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1310
zpd_add_listener(zoneid_t zid, int fd, int pipefd, int closefd)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1311
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1312
	struct proxy_listener *old_listener;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1313
	struct proxy_listener *listener;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1314
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1315
	(void) mutex_lock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1316
	old_listener = zpd_find_listener(zid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1317
	if (old_listener) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1318
		zpd_listener_cleanup(old_listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1319
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1320
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1321
	listener = alloc_proxy_listener();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1322
	if (listener == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1323
		goto fail;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1324
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1325
	listener->pl_fd = fd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1326
	listener->pl_zid = zid;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1327
	listener->pl_pipefd = pipefd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1328
	listener->pl_closefd = closefd;
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1329
	TAILQ_INSERT_TAIL(&zone_listener_list, listener, pl_list_link);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1330
	if (set_noblocking(fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1331
		goto fail;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1332
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1333
	if (set_noblocking(pipefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1334
		goto fail;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1335
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1336
	if (port_associate(g_port, PORT_SOURCE_FD, listener->pl_fd, POLLIN,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1337
	    listener) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1338
		perror("port_associate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1339
		goto fail;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1340
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1341
	(void) mutex_unlock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1342
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1343
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1344
fail:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1345
	if (listener) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1346
		/* No cleanup required, since list lock was never dropped */
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1347
		TAILQ_REMOVE(&zone_listener_list, listener, pl_list_link);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1348
		free_proxy_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1349
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1350
	(void) mutex_unlock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1351
	return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1352
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1353
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1354
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1355
 * This method has to perform an intricate dance to cleanup a listener.  If it
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1356
 * is able to dissociate the listener from the port, it may remove the listener.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1357
 * Otherwise, it must set the cleanup flag and let the thread running the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1358
 * listener perform the removal.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1359
 *
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1360
 * Caller should hold the listener list lock.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1361
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1362
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1363
zpd_listener_cleanup(struct proxy_listener *listener)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1364
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1365
	int rc;
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1366
	struct proxy_listener *wl;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1367
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1368
	(void) mutex_lock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1369
	if (listener->pl_cleanup) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1370
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1371
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1372
	}
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1373
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1374
	for (wl = TAILQ_FIRST(&zone_listener_list); wl != NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1375
	    wl = TAILQ_NEXT(wl, pl_list_link)) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1376
		if (wl == listener) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1377
			TAILQ_REMOVE(&zone_listener_list, listener,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1378
			    pl_list_link);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1379
			break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1380
		}
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1381
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1382
	rc = port_dissociate(g_port, PORT_SOURCE_FD, listener->pl_fd);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1383
	if (rc == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1384
		/* successfully got the object, remove it. */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1385
		(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1386
		free_proxy_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1387
		return;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1388
	} else if (rc < 0 && errno == ENOENT) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1389
		/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1390
		 * Didn't find the event associated with the port. Another
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1391
		 * thread must be concurrently processing events for the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1392
		 * fd.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1393
		 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1394
		listener->pl_cleanup = B_TRUE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1395
	} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1396
		/* Unexpected error */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1397
		perror("port_dissociate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1398
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1399
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1400
	(void) mutex_unlock(&listener->pl_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1401
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1402
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1403
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1404
zpd_remove_listener(struct proxy_listener *listener)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1405
{
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1406
	struct proxy_listener *wl;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1407
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1408
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1409
	 * Add and remove operations hold the list lock for the duration of
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1410
	 * their execution.  When this routine acquires the list lock and
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1411
	 * removes the listener, it should no longer be reachable by any other
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1412
	 * thread.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1413
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1414
	(void) mutex_lock(g_listener_lock);
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1415
	for (wl = TAILQ_FIRST(&zone_listener_list); wl != NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1416
	    wl = TAILQ_NEXT(wl, pl_list_link)) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1417
		if (wl == listener) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1418
			TAILQ_REMOVE(&zone_listener_list, listener,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1419
			    pl_list_link);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1420
			break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1421
		}
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1422
	}
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1423
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1424
	(void) mutex_unlock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1425
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1426
	free_proxy_listener(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1427
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1428
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1429
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1430
 * Zone removal call.  This routine cannot fdetach the door in the zone because
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1431
 * the zone is in shutdown state and cannot be zone_enter'd.  This means that
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1432
 * the add_zone code must always fdetach and unlink the existing door before
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1433
 * creating a new one.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1434
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1435
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1436
zpd_remove_zone(zoneid_t zid)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1437
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1438
	struct proxy_listener *listener;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1439
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1440
	(void) mutex_lock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1441
	listener = zpd_find_listener(zid);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1442
	if (listener) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1443
		zpd_listener_cleanup(listener);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1444
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1445
	(void) mutex_unlock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1446
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1447
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1448
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1449
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1450
/* ARGSUSED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1451
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1452
zpd_door_server(void *cookie, char *argp, size_t arg_size,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1453
    door_desc_t *dp, uint_t n_desc)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1454
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1455
	int *args, cmd;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1456
	int pipefd[2];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1457
	uint_t nexpected_desc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1458
	door_desc_t *r_dp = NULL;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1459
	door_desc_t rdesc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1460
	uint_t r_n_desc = 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1461
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1462
	if (argp == DOOR_UNREF_DATA) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1463
		(void) door_return(NULL, 0, NULL, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1464
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1465
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1466
	if (arg_size != sizeof (cmd) * 2) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1467
		close_door_descs(dp, n_desc);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1468
		(void) door_return(NULL, 0, NULL, 0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1469
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1470
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1471
	/* LINTED */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1472
	args = (int *)argp;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1473
	cmd = args[0];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1474
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1475
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1476
	 * Caller may have passed more descriptors than expected.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1477
	 * If so, close the extraneous fds.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1478
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1479
	nexpected_desc = (cmd == ZP_CMD_NEW_LISTENER) ? 1 : 0;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1480
	if (n_desc > nexpected_desc) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1481
		close_door_descs(dp + nexpected_desc, n_desc - nexpected_desc);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1482
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1483
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1484
	switch (cmd) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1485
	case ZP_CMD_NEW_LISTENER:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1486
		if (zpd_perm_check(cmd, args[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1487
			close_door_descs(dp, n_desc);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1488
			args[1] = ZP_STATUS_PERMISSION;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1489
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1490
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1491
		if (n_desc < 1 || (dp->d_attributes & DOOR_DESCRIPTOR) == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1492
			args[1] = ZP_STATUS_INVALID;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1493
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1494
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1495
		if (pipe(pipefd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1496
			args[1] = ZP_STATUS_ERROR;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1497
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1498
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1499
		if (zpd_add_listener(args[1],
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1500
		    dp->d_data.d_desc.d_descriptor, pipefd[0], pipefd[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1501
			close_door_descs(dp, n_desc);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1502
			if (close(pipefd[0]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1503
				perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1504
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1505
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1506
			if (close(pipefd[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1507
				perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1508
				exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1509
			}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1510
			args[1] = ZP_STATUS_ERROR;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1511
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1512
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1513
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1514
		r_dp = &rdesc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1515
		r_dp->d_attributes = DOOR_DESCRIPTOR;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1516
		r_dp->d_data.d_desc.d_descriptor = pipefd[1];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1517
		r_n_desc = 1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1518
		args[1] = ZP_STATUS_OK;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1519
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1520
	case ZP_CMD_ZONE_ADDED:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1521
		if (zpd_perm_check(cmd, args[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1522
			args[1] = ZP_STATUS_PERMISSION;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1523
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1524
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1525
		zpd_fattach_zone(args[1], g_door, B_FALSE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1526
		args[1] = ZP_STATUS_OK;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1527
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1528
	case ZP_CMD_REMOVE_LISTENER:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1529
	case ZP_CMD_ZONE_REMOVED:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1530
		if (zpd_perm_check(cmd, args[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1531
			args[1] = ZP_STATUS_PERMISSION;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1532
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1533
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1534
		if (zpd_remove_zone(args[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1535
			args[1] = ZP_STATUS_ERROR;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1536
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1537
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1538
		args[1] = ZP_STATUS_OK;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1539
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1540
	case ZP_CMD_PING:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1541
		if (zpd_perm_check(cmd, args[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1542
			args[1] = ZP_STATUS_PERMISSION;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1543
			goto out;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1544
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1545
		args[1] = ZP_STATUS_OK;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1546
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1547
	default:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1548
		args[1] = ZP_STATUS_UNKNOWN;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1549
		break;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1550
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1551
out:
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1552
	(void) door_return(argp, sizeof (cmd) * 2, r_dp, r_n_desc);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1553
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1554
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1555
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1556
daemonize_ready(char status)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1557
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1558
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1559
	 * wake the parent with a clue
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1560
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1561
	(void) write(g_pipe_fd, &status, 1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1562
	if (close(g_pipe_fd) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1563
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1564
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1565
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1566
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1567
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1568
static int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1569
daemonize_start(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1570
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1571
	char data;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1572
	int status;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1573
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1574
	int filedes[2];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1575
	pid_t pid;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1576
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1577
	if (close(0) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1578
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1579
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1580
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1581
	if (dup2(2, 1) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1582
		perror("dup2");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1583
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1584
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1585
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1586
	if (pipe(filedes) < 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1587
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1588
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1589
	(void) fflush(NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1590
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1591
	if ((pid = fork1()) < 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1592
		return (-1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1593
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1594
	if (pid != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1595
		/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1596
		 * parent
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1597
		 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1598
		if (close(filedes[1]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1599
			perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1600
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1601
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1602
		if (read(filedes[0], &data, 1) == 1) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1603
			/* forward ready code via exit status */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1604
			exit(data);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1605
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1606
		status = -1;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1607
		(void) wait4(pid, &status, 0, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1608
		/* daemon process exited before becoming ready */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1609
		if (WIFEXITED(status)) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1610
			/* assume daemon process printed useful message */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1611
			exit(WEXITSTATUS(status));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1612
		} else {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1613
			(void) fprintf(stderr,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1614
			    "daemon process killed or died\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1615
			exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1616
		}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1617
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1618
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1619
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1620
	 * child
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1621
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1622
	g_pipe_fd = filedes[1];
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1623
	if (close(filedes[0]) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1624
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1625
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1626
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1627
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1628
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1629
	 * generic Unix setup
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1630
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1631
	(void) setsid();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1632
	(void) umask(0000);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1633
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1634
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1635
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1636
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1637
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1638
drop_privs(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1639
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1640
	priv_set_t *ePrivSet = NULL;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1641
	priv_set_t *lPrivSet = NULL;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1642
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1643
	if ((ePrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1644
		(void) fprintf(stderr, "Unable to get 'basic' privset\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1645
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1646
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1647
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1648
	/* Drop any privs out of the basic set that we won't need */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1649
	(void) priv_delset(ePrivSet, PRIV_FILE_LINK_ANY);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1650
	(void) priv_delset(ePrivSet, PRIV_PROC_INFO);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1651
	(void) priv_delset(ePrivSet, PRIV_PROC_SESSION);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1652
	(void) priv_delset(ePrivSet, PRIV_PROC_EXEC);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1653
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1654
	/* Add privs needed for daemon operation */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1655
	(void) priv_addset(ePrivSet, PRIV_CONTRACT_EVENT);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1656
	(void) priv_addset(ePrivSet, PRIV_CONTRACT_IDENTITY);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1657
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1658
	/* Set effective set */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1659
	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, ePrivSet) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1660
		(void) fprintf(stderr, "Unable to drop privs\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1661
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1662
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1663
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1664
	/* clear limit set */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1665
	if ((lPrivSet = priv_allocset()) == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1666
		(void) fprintf(stderr, "Unable to allocate privset\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1667
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1668
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1669
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1670
	priv_emptyset(lPrivSet);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1671
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1672
	if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1673
		(void) fprintf(stderr, "Unable to set limit set\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1674
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1675
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1676
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1677
	priv_freeset(lPrivSet);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1678
	priv_freeset(ePrivSet);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1679
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1680
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1681
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1682
/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1683
 * zone_enter requires that the process have the full privilege set.  We try to
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1684
 * run with the lowest possible set, but in the case where we zone-enter, we
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1685
 * must re-set the effective set to be all privs.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1686
 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1687
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1688
escalate_privs(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1689
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1690
	priv_set_t *ePrivSet = NULL;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1691
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1692
	if ((ePrivSet = priv_allocset()) == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1693
		(void) fprintf(stderr, "Unable to allocate privset\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1694
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1695
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1696
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1697
	priv_fillset(ePrivSet);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1698
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1699
	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, ePrivSet) != 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1700
		(void) fprintf(stderr, "Unable to set effective priv set\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1701
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1702
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1703
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1704
	priv_freeset(ePrivSet);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1705
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1706
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1707
static struct proxy_config *
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1708
config_alloc(void)
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1709
{
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1710
	struct proxy_config *pc = NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1711
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1712
	if ((pc = malloc(sizeof (struct proxy_config))) == NULL)
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1713
		return (NULL);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1714
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1715
	(void) memset(pc, 0, sizeof (struct proxy_config));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1716
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1717
	if (mutex_init(&pc->pc_lock, USYNC_THREAD, NULL) < 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1718
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1719
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1720
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1721
	if ((pc->pc_hdl = scf_handle_create(SCF_VERSION)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1722
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1723
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1724
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1725
	if ((pc->pc_inst = scf_instance_create(pc->pc_hdl)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1726
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1727
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1728
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1729
	if ((pc->pc_pg = scf_pg_create(pc->pc_hdl)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1730
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1731
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1732
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1733
	if ((pc->pc_prop = scf_property_create(pc->pc_hdl)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1734
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1735
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1736
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1737
	if ((pc->pc_val = scf_value_create(pc->pc_hdl)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1738
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1739
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1740
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1741
	if ((pc->pc_proxy_host = strdup(DEFAULT_HOST)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1742
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1743
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1744
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1745
	if ((pc->pc_proxy_port = strdup(DEFAULT_PORT)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1746
		goto out;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1747
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1748
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1749
	pc->pc_gen = 1;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1750
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1751
	return (pc);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1752
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1753
out:
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1754
	config_free(pc);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1755
	return (NULL);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1756
}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1757
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1758
static void
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1759
config_free(struct proxy_config *pc)
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1760
{
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1761
	if (pc == NULL)
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1762
		return;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1763
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1764
	if (pc->pc_inst != NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1765
		scf_instance_destroy(pc->pc_inst);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1766
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1767
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1768
	if (pc->pc_pg != NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1769
		scf_pg_destroy(pc->pc_pg);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1770
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1771
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1772
	if (pc->pc_prop != NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1773
		scf_property_destroy(pc->pc_prop);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1774
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1775
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1776
	if (pc->pc_val != NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1777
		scf_value_destroy(pc->pc_val);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1778
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1779
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1780
	if (pc->pc_hdl != NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1781
		scf_handle_destroy(pc->pc_hdl);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1782
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1783
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1784
	free(pc->pc_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1785
	free(pc->pc_proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1786
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1787
	(void) mutex_destroy(&pc->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1788
	free(pc);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1789
}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1790
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1791
static int
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1792
config_read(struct proxy_config *pc)
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1793
{
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1794
	char *host = NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1795
	char *port = NULL;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1796
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1797
	if ((host = malloc(CONF_STR_SZ)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1798
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1799
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1800
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1801
	if ((port = malloc(CONF_STR_SZ)) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1802
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1803
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1804
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1805
	mutex_lock(&pc->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1806
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1807
	if (scf_handle_bind(pc->pc_hdl) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1808
		(void) fprintf(stderr, "scf_handle_bind failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1809
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1810
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1811
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1812
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1813
	if (scf_handle_decode_fmri(pc->pc_hdl, SYSREPO_FMRI, NULL, NULL,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1814
	    pc->pc_inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1815
		(void) fprintf(stderr, "scf_handle_decode_fmri failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1816
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1817
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1818
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1819
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1820
	if (scf_instance_get_pg(pc->pc_inst, SYSREPO_PG, pc->pc_pg) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1821
		(void) fprintf(stderr, "scf_instance_get_pg failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1822
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1823
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1824
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1825
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1826
	if (scf_pg_get_property(pc->pc_pg, SYSREPO_HOST, pc->pc_prop) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1827
		(void) fprintf(stderr, "scf_pg_get_property failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1828
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1829
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1830
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1831
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1832
	if (scf_property_get_value(pc->pc_prop, pc->pc_val) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1833
		(void) fprintf(stderr, "scf_property_get_value failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1834
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1835
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1836
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1837
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1838
	if (scf_value_get_as_string_typed(pc->pc_val, SCF_TYPE_ASTRING,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1839
	    host, CONF_STR_SZ) < 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1840
		(void) fprintf(stderr,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1841
		    "scf_value_get_as_string_typed failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1842
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1843
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1844
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1845
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1846
	if (scf_pg_get_property(pc->pc_pg, SYSREPO_PORT, pc->pc_prop) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1847
		(void) fprintf(stderr, "scf_pg_get_property failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1848
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1849
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1850
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1851
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1852
	if (scf_property_get_value(pc->pc_prop, pc->pc_val) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1853
		(void) fprintf(stderr, "scf_property_get_value failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1854
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1855
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1856
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1857
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1858
	if (scf_value_get_as_string_typed(pc->pc_val, SCF_TYPE_COUNT,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1859
	    port, CONF_STR_SZ) < 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1860
		(void) fprintf(stderr,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1861
		    "scf_value_get_as_string_typed failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1862
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1863
		goto fail;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1864
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1865
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1866
	if (scf_handle_unbind(pc->pc_hdl) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1867
		(void) fprintf(stderr, "scf_handle_unbind failed; %s\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1868
		    scf_strerror(scf_error()));
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1869
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1870
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1871
	free(pc->pc_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1872
	free(pc->pc_proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1873
	pc->pc_proxy_host = host;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1874
	pc->pc_proxy_port = port;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1875
	pc->pc_gen++;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1876
	mutex_unlock(&pc->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1877
	return (0);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1878
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1879
fail:
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1880
	mutex_unlock(&pc->pc_lock);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1881
	free(host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1882
	free(port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1883
	return (-1);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1884
}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1885
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1886
static void
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1887
s_handler(void)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1888
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1889
	sigset_t get_sigs;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1890
	int rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1891
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1892
	(void) sigfillset(&get_sigs);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1893
	while (g_quit == B_FALSE) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1894
		rc = sigwait(&get_sigs);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1895
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1896
		if (rc == SIGINT || rc == SIGTERM || rc == SIGHUP) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1897
			(void) mutex_lock(&g_quit_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1898
			g_quit = B_TRUE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1899
			(void) cond_signal(&g_quit_cv);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1900
			(void) mutex_unlock(&g_quit_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1901
		}
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1902
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1903
		if (g_config_smf && rc == SIGUSR1) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1904
			if (config_read(g_proxy_config) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1905
				(void) fprintf(stderr, "Unable to re-load "
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1906
				    "proxy configuration from SMF.\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1907
			}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1908
		}
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1909
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1910
}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1911
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1912
int
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1913
main(int argc, char **argv)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1914
{
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1915
	extern char *optarg;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1916
	char *proxystr = NULL;
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1917
	char *proxy_host, *proxy_port;
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1918
	int rc;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1919
	int ncpu;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1920
	struct proxy_listener *wl;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1921
	sigset_t blockset;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1922
	struct rlimit rlp = {0};
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1923
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1924
        while ((rc = getopt(argc, argv, "s:")) != -1) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1925
                switch (rc) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1926
                case 's':
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1927
                        proxystr = optarg;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1928
                        break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1929
                case ':':
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1930
                        (void) fprintf(stderr, "Option -%c requires operand\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1931
                            optopt);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1932
                        usage();
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1933
                        break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1934
                case '?':
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1935
                        (void) fprintf(stderr, "Unrecognized option -%c\n",
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1936
                            optopt);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1937
                        usage();
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1938
                        break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1939
                default:
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1940
                        break;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1941
                }
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1942
        }
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1943
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1944
	g_config_smf = (proxystr == NULL) ? B_TRUE : B_FALSE;
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1945
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1946
	if (!g_config_smf) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1947
		proxy_host = strtok(proxystr, ":");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1948
		if (proxy_host == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1949
			(void) fprintf(stderr,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1950
			    "host must be of format hostname:port\n");
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1951
			usage();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1952
		}
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1953
		proxy_port = strtok(NULL, ":");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1954
		if (proxy_port == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1955
			(void) fprintf(stderr,
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1956
			    "host must be of format hostname:port\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1957
			usage();
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1958
		}
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1959
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1960
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1961
	g_quit = B_FALSE;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1962
	(void) signal(SIGPIPE, SIG_IGN);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1963
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1964
	if ((g_proxy_config = config_alloc()) == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1965
		(void) fprintf(stderr, "Unable to allocate proxy config\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1966
		exit(EXIT_FAILURE);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1967
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1968
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1969
	if (g_config_smf) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1970
		if (config_read(g_proxy_config) != 0) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1971
			(void) fprintf(stderr, "Unable to read proxy config. "
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1972
			    "Falling back to defaults.\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1973
		}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1974
	} else {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1975
		free(g_proxy_config->pc_proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1976
		free(g_proxy_config->pc_proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1977
		g_proxy_config->pc_proxy_host = strdup(proxy_host);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1978
		g_proxy_config->pc_proxy_port = strdup(proxy_port);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1979
		if (g_proxy_config->pc_proxy_host == NULL ||
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1980
		    g_proxy_config->pc_proxy_port == NULL) {
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1981
			(void) fprintf(stderr, "Unable to allocate memory for "
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1982
			    "proxy configuration strings\n");
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1983
			exit(EXIT_FAILURE);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1984
		}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1985
	}
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  1986
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1987
	if (daemonize_start() < 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1988
		(void) fprintf(stderr, "Unable to start daemon\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1989
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1990
	drop_privs();
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1991
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1992
	(void) sigfillset(&blockset);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1993
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1994
	if (thr_sigsetmask(SIG_BLOCK, &blockset, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1995
		perror("thr_sigsetmask");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1996
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1997
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1998
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  1999
	/* Increase the number of maximum file descriptors */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2000
	(void) getrlimit(RLIMIT_NOFILE, &rlp);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2001
	rlp.rlim_cur = MAX_FDS_DEFAULT;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2002
	if (setrlimit(RLIMIT_NOFILE, &rlp) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2003
		perror("setrlimit");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2004
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2005
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2006
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2007
	/* Create single global event port */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2008
	if ((g_port = port_create()) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2009
		perror("port_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2010
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2011
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2012
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2013
	/* Setup listener list. */
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  2014
	TAILQ_INIT(&zone_listener_list);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2015
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2016
	/* Initialize locks */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2017
	g_door_thr_lock = memalign(DEFAULT_LOCK_ALIGN, sizeof (mutex_t));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2018
	if (g_door_thr_lock == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2019
		(void) fprintf(stderr, "Unable to allocate g_door_thr_lock\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2020
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2021
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2022
	if (mutex_init(g_door_thr_lock, USYNC_THREAD, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2023
		perror("mutex_init");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2024
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2025
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2026
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2027
	g_listener_lock = memalign(DEFAULT_LOCK_ALIGN, sizeof (mutex_t));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2028
	if (g_listener_lock == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2029
		(void) fprintf(stderr, "Unable to allocate g_listener_lock\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2030
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2031
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2032
	if (mutex_init(g_listener_lock, USYNC_THREAD, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2033
		perror("mutex_init");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2034
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2035
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2036
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2037
	g_thr_pool_lock = memalign(DEFAULT_LOCK_ALIGN, sizeof (mutex_t));
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2038
	if (g_thr_pool_lock == NULL) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2039
		(void) fprintf(stderr, "Unable to alloc g_thr_pool_lock\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2040
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2041
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2042
	if (mutex_init(g_thr_pool_lock, USYNC_THREAD, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2043
		perror("mutex_init");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2044
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2045
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2046
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2047
	if (thr_keycreate(&g_thr_info_key, thread_exiting) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2048
		perror("thr_keycreate");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2049
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2050
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2051
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2052
	/* Auto-tune min/max threads based upon number of cpus in system */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2053
	ncpu = sysconf(_SC_NPROCESSORS_ONLN);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2054
	if (ncpu < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2055
		perror("sysconf");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2056
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2057
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2058
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2059
	/* Paranoia. */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2060
	if (ncpu == 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2061
		(void) fprintf(stderr, "0 cpus online. How is this running?\n");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2062
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2063
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2064
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2065
	g_tp_min_threads = MIN(g_tp_min_threads, ncpu);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2066
	g_tp_max_threads = MAX(g_tp_max_threads, ncpu/4);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2067
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2068
	/* Setup door */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2069
	(void) door_server_create(zpd_door_create_thread);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2070
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2071
	g_door = door_create(zpd_door_server, NULL,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2072
	    DOOR_PRIVATE | DOOR_NO_CANCEL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2073
	if (g_door < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2074
		perror("door_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2075
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2076
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2077
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2078
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2079
	 * Set a limit on the size of the data that may be passed
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2080
	 * through the door, as well as the number of FDs that may be passed in
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2081
	 * any particular call.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2082
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2083
	if (door_setparam(g_door, DOOR_PARAM_DATA_MAX, sizeof (int) * 2) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2084
		perror("door_setparam");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2085
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2086
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2087
	if (door_setparam(g_door, DOOR_PARAM_DESC_MAX, 1) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2088
		perror("door_setparam");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2089
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2090
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2091
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2092
	fattach_all_zones(B_FALSE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2093
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2094
	/* start signal handling thread */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2095
	rc = thr_create(NULL, 0, (void *(*)(void *))s_handler, NULL,
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2096
	    THR_BOUND, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2097
	if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2098
		perror("thr_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2099
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2100
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2101
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2102
	/* Start thread pool manager */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2103
	rc = thr_create(NULL, 0, thread_manager, NULL, THR_BOUND, NULL);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2104
	if (rc < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2105
		perror("thr_create");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2106
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2107
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2108
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2109
	daemonize_ready(0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2110
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2111
	/* Wait for signal handling thread to notify us to quit */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2112
	while (g_quit == B_FALSE) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2113
		(void) mutex_lock(&g_quit_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2114
		(void) cond_wait(&g_quit_cv, &g_quit_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2115
		(void) mutex_unlock(&g_quit_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2116
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2117
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2118
	/* Wake up manager thread, so it will exit */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2119
	(void) mutex_lock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2120
	(void) cond_signal(&g_thr_pool_cv);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2121
	(void) mutex_unlock(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2122
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2123
	/* set port alert to wake any sleeping threads */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2124
	if (port_alert(g_port, PORT_ALERT_SET, 1, NULL) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2125
		perror("port_alert");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2126
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2127
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2128
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2129
	/* detach doors */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2130
	fattach_all_zones(B_TRUE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2131
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2132
	(void) door_revoke(g_door);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2133
	if (close(g_port) < 0) {
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2134
		perror("close");
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2135
		exit(EXIT_FAILURE);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2136
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2137
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2138
	/* Wait for threads to exit */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2139
	while (thr_join(0, NULL, NULL) == 0)
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2140
		;
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2141
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2142
	/*
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2143
	 * Tell any waiting listeners that we're quitting.  Walk the
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2144
	 * listener list, writing a byte to each pipe.  Then teardown
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2145
	 * any remaining listener structures.
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2146
	 */
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2147
	(void) mutex_lock(g_listener_lock);
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  2148
	while (!TAILQ_EMPTY(&zone_listener_list)) {
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2149
		char pipeval = '0';
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2150
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  2151
		wl = TAILQ_FIRST(&zone_listener_list);
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  2152
		TAILQ_REMOVE(&zone_listener_list, wl, pl_list_link);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2153
		(void) write(wl->pl_pipefd, &pipeval, 1);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2154
		free_proxy_listener(wl);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2155
	}
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2156
	(void) mutex_unlock(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2157
2349
4b4ff1617157 18277 zoneproxy client should release socket on orderly shutdown
johansen <johansen@opensolaris.org>
parents: 2338
diff changeset
  2158
	config_free(g_proxy_config);
2338
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2159
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2160
	(void) mutex_destroy(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2161
	(void) mutex_destroy(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2162
	(void) mutex_destroy(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2163
	free(g_door_thr_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2164
	free(g_listener_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2165
	free(g_thr_pool_lock);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2166
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2167
	return (0);
63a4d56416c6 18240 zone proxy needed
johansen <johansen@opensolaris.org>
parents:
diff changeset
  2168
}