Print this page
OS-4741 Add support for multiple addresses & IPv6 to lx-branded zones
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
+++ new/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/ctfs.h>
28 28 #include <sys/contract/process.h>
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
29 29 #include <sys/socket.h>
30 30 #include <sys/time.h>
31 31 #include <sys/wait.h>
32 32 #include <fcntl.h>
33 33 #include <libcontract.h>
34 34 #include <libcontract_priv.h>
35 35 #include <unistd.h>
36 36 #include <stdio.h>
37 37 #include <stdlib.h>
38 38 #include <string.h>
39 +#include <zone.h>
39 40
40 41 #include "dhcpagent_ipc.h"
41 42 #include "dhcpagent_util.h"
42 43
43 44 /*
44 45 * Strings returned by dhcp_status_hdr_string() and
45 46 * dhcp_status_reply_to_string(). The first define is the header line, and
46 47 * the second defines line printed underneath.
47 48 * The spacing of fields must match.
48 49 */
49 50 #define DHCP_STATUS_HDR "Interface State Sent Recv Declined Flags\n"
50 51 #define DHCP_STATUS_STR "%-10s %-12s %5d %5d %9d "
51 52
52 53 static const char *time_to_string(time_t abs_time);
53 54
54 55 /*
55 56 * dhcp_state_to_string(): given a state, provides the state's name
56 57 *
57 58 * input: DHCPSTATE: the state to get the name of
58 59 * output: const char *: the state's name
59 60 */
60 61
61 62 const char *
62 63 dhcp_state_to_string(DHCPSTATE state)
63 64 {
64 65 const char *states[] = {
65 66 "INIT",
66 67 "SELECTING",
67 68 "REQUESTING",
68 69 "PRE_BOUND",
69 70 "BOUND",
70 71 "RENEWING",
71 72 "REBINDING",
72 73 "INFORMATION",
73 74 "INIT_REBOOT",
74 75 "ADOPTING",
75 76 "INFORM_SENT",
76 77 "DECLINING",
77 78 "RELEASING"
78 79 };
79 80
80 81 if (state < 0 || state >= DHCP_NSTATES)
81 82 return ("<unknown>");
82 83
83 84 return (states[state]);
84 85 }
85 86
86 87 static int
87 88 init_template(void)
88 89 {
89 90 int fd;
90 91 int err = 0;
91 92
92 93 fd = open64(CTFS_ROOT "/process/template", O_RDWR);
93 94 if (fd == -1)
94 95 return (-1);
95 96
96 97 /*
97 98 * Deliver no events, don't inherit, and allow it to be orphaned.
98 99 */
99 100 err |= ct_tmpl_set_critical(fd, 0);
100 101 err |= ct_tmpl_set_informative(fd, 0);
101 102 err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
102 103 err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
103 104 if (err != 0 || ct_tmpl_activate(fd) != 0) {
104 105 (void) close(fd);
105 106 return (-1);
106 107 }
107 108
108 109 return (fd);
109 110 }
110 111
111 112 /*
112 113 * dhcp_start_agent(): starts the agent if not already running
113 114 *
114 115 * input: int: number of seconds to wait for agent to start (-1 is forever)
115 116 * output: int: 0 on success, -1 on failure
116 117 */
117 118
|
↓ open down ↓ |
69 lines elided |
↑ open up ↑ |
118 119 int
119 120 dhcp_start_agent(int timeout)
120 121 {
121 122 int error;
122 123 time_t start_time = time(NULL);
123 124 dhcp_ipc_request_t *request;
124 125 dhcp_ipc_reply_t *reply;
125 126 int ctfd;
126 127 pid_t childpid;
127 128 ctid_t ct;
129 + char dhcpcmd[MAXPATHLEN];
130 + const char *zroot = zone_get_nroot();
128 131
132 + /* Prepend the root of the native code in the brand to the command */
133 + (void) snprintf(dhcpcmd, sizeof (dhcpcmd), "%s%s", zroot != NULL ?
134 + zroot : "", DHCP_AGENT_PATH);
135 +
129 136 /*
130 137 * just send a dummy request to the agent to find out if it's
131 138 * up. we do this instead of directly connecting to it since
132 139 * we want to make sure we follow its IPC conventions
133 140 * (otherwise, it will log warnings to syslog).
134 141 */
135 142
136 143 request = dhcp_ipc_alloc_request(DHCP_PING, "", NULL, 0,
137 144 DHCP_TYPE_NONE);
138 145 if (request == NULL)
139 146 return (-1);
140 147
141 148 error = dhcp_ipc_make_request(request, &reply, 0);
142 149 if (error == 0) {
143 150 free(reply);
144 151 free(request);
145 152 return (0);
146 153 }
147 154 if (error != DHCP_IPC_E_CONNECT)
148 155 goto fail;
149 156
150 157 if ((ctfd = init_template()) == -1)
151 158 goto fail;
152 159
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
153 160 childpid = fork();
154 161
155 162 (void) ct_tmpl_clear(ctfd);
156 163 (void) close(ctfd);
157 164
158 165 switch (childpid) {
159 166 case -1:
160 167 goto fail;
161 168
162 169 case 0:
163 - (void) execl(DHCP_AGENT_PATH, DHCP_AGENT_PATH, (char *)0);
170 + (void) execl(dhcpcmd, dhcpcmd, (char *)0);
164 171 _exit(EXIT_FAILURE);
165 172
166 173 default:
167 174 break;
168 175 }
169 176
170 177 /* wait for the daemon to run and then abandon the contract */
171 178 (void) waitpid(childpid, NULL, 0);
172 179
173 180 if (contract_latest(&ct) != -1)
174 181 (void) contract_abandon_id(ct);
175 182
176 183 while ((timeout != -1) && (time(NULL) - start_time < timeout)) {
177 184 error = dhcp_ipc_make_request(request, &reply, 0);
178 185 if (error == 0) {
179 186 free(reply);
180 187 free(request);
181 188 return (0);
182 189 } else if (error != DHCP_IPC_E_CONNECT)
183 190 break;
184 191 (void) sleep(1);
185 192 }
186 193
187 194 fail:
188 195 free(request);
189 196 return (-1);
190 197 }
191 198
192 199 /*
193 200 * dhcp_status_hdr_string(): Return a string suitable to use as the header
194 201 * when printing DHCP_STATUS reply.
195 202 * output: const char *: newline terminated printable string
196 203 */
197 204 const char *
198 205 dhcp_status_hdr_string(void)
199 206 {
200 207 return (DHCP_STATUS_HDR);
201 208 }
202 209
203 210 /*
204 211 * time_to_string(): Utility routine for printing time
205 212 *
206 213 * input: time_t *: time_t to stringify
207 214 * output: const char *: printable time
208 215 */
209 216 static const char *
210 217 time_to_string(time_t abs_time)
211 218 {
212 219 static char time_buf[24];
213 220 time_t tm = abs_time;
214 221
215 222 if (tm == DHCP_PERM)
216 223 return ("Never");
217 224
218 225 if (strftime(time_buf, sizeof (time_buf), "%m/%d/%Y %R",
219 226 localtime(&tm)) == 0)
220 227 return ("<unknown>");
221 228
222 229 return (time_buf);
223 230 }
224 231
225 232 /*
226 233 * dhcp_status_reply_to_string(): Return DHCP IPC reply of type DHCP_STATUS
227 234 * as a printable string
228 235 *
229 236 * input: dhcp_reply_t *: contains the status structure to print
230 237 * output: const char *: newline terminated printable string
231 238 */
232 239 const char *
233 240 dhcp_status_reply_to_string(dhcp_ipc_reply_t *reply)
234 241 {
235 242 static char str[1024];
236 243 size_t reply_size;
237 244 dhcp_status_t *status;
238 245
239 246 status = dhcp_ipc_get_data(reply, &reply_size, NULL);
240 247 if (reply_size < DHCP_STATUS_VER1_SIZE)
241 248 return ("<Internal error: status msg size>\n");
242 249
243 250 (void) snprintf(str, sizeof (str), DHCP_STATUS_STR,
244 251 status->if_name, dhcp_state_to_string(status->if_state),
245 252 status->if_sent, status->if_recv, status->if_bad_offers);
246 253
247 254 if (status->if_dflags & DHCP_IF_PRIMARY)
248 255 (void) strlcat(str, "[PRIMARY] ", sizeof (str));
249 256
250 257 if (status->if_dflags & DHCP_IF_BOOTP)
251 258 (void) strlcat(str, "[BOOTP] ", sizeof (str));
252 259
253 260 if (status->if_dflags & DHCP_IF_FAILED)
254 261 (void) strlcat(str, "[FAILED] ", sizeof (str));
255 262
256 263 if (status->if_dflags & DHCP_IF_BUSY)
257 264 (void) strlcat(str, "[BUSY] ", sizeof (str));
258 265
259 266 if (status->if_dflags & DHCP_IF_V6)
260 267 (void) strlcat(str, "[V6] ", sizeof (str));
261 268
262 269 (void) strlcat(str, "\n", sizeof (str));
263 270
264 271 switch (status->if_state) {
265 272 case BOUND:
266 273 case RENEWING:
267 274 case REBINDING:
268 275 break;
269 276 default:
270 277 return (str);
271 278 }
272 279
273 280 (void) strlcat(str, "(Began, Expires, Renew) = (", sizeof (str));
274 281 (void) strlcat(str, time_to_string(status->if_began), sizeof (str));
275 282 (void) strlcat(str, ", ", sizeof (str));
276 283 (void) strlcat(str, time_to_string(status->if_lease), sizeof (str));
277 284 (void) strlcat(str, ", ", sizeof (str));
278 285 (void) strlcat(str, time_to_string(status->if_t1), sizeof (str));
279 286 (void) strlcat(str, ")\n", sizeof (str));
280 287 return (str);
281 288 }
|
↓ open down ↓ |
108 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX