6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
26 */
27
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/list.h>
31 #include <sys/stropts.h>
32 #include <sys/siginfo.h>
33 #include <sys/wait.h>
34 #include <arpa/inet.h>
35 #include <netinet/in.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <strings.h>
39 #include <stddef.h>
40 #include <unistd.h>
41 #include <libilb.h>
42 #include <port.h>
43 #include <time.h>
44 #include <signal.h>
45 #include <assert.h>
1271 pid_t pid;
1272 char *child_argv[HC_PROBE_ARGC];
1273 ilbd_hc_probe_event_t *probe_ev;
1274 char *probe_name;
1275
1276 bzero(child_argv, HC_PROBE_ARGC * sizeof (char *));
1277 if ((probe_ev = calloc(1, sizeof (*probe_ev))) == NULL) {
1278 logdebug("ilbd_run_probe: calloc");
1279 return (B_FALSE);
1280 }
1281
1282 /* Set up a pipe to get output from probe command. */
1283 if (pipe(fds) < 0) {
1284 logdebug("ilbd_run_probe: cannot create pipe");
1285 free(probe_ev);
1286 return (B_FALSE);
1287 }
1288 /* Set our side of the pipe to be non-blocking */
1289 if ((fdflags = fcntl(fds[0], F_GETFL, 0)) == -1) {
1290 logdebug("ilbd_run_probe: fcntl(F_GETFL)");
1291 goto cleanup;
1292 }
1293 if (fcntl(fds[0], F_SETFL, fdflags | O_NONBLOCK) == -1) {
1294 logdebug("ilbd_run_probe: fcntl(F_SETFL)");
1295 goto cleanup;
1296 }
1297
1298 if (posix_spawn_file_actions_init(&fd_actions) != 0) {
1299 logdebug("ilbd_run_probe: posix_spawn_file_actions_init");
1300 goto cleanup;
1301 }
1302 if (posix_spawnattr_init(&attr) != 0) {
1303 logdebug("ilbd_run_probe: posix_spawnattr_init");
1304 goto cleanup;
1305 }
1306 if (posix_spawn_file_actions_addclose(&fd_actions, fds[0]) != 0) {
1307 logdebug("ilbd_run_probe: posix_spawn_file_actions_addclose");
1308 goto cleanup;
1309 }
1310 if (posix_spawn_file_actions_adddup2(&fd_actions, fds[1],
1311 STDOUT_FILENO) != 0) {
1312 logdebug("ilbd_run_probe: posix_spawn_file_actions_dup2");
1313 goto cleanup;
1314 }
1315 if (posix_spawn_file_actions_addclose(&fd_actions, fds[1]) != 0) {
1316 logdebug("ilbd_run_probe: posix_spawn_file_actions_addclose");
1317 goto cleanup;
1318 }
1319
1320 /* Reset all signal handling of the child to default. */
1321 (void) sigfillset(&child_sigset);
1322 if (posix_spawnattr_setsigdefault(&attr, &child_sigset) != 0) {
1323 logdebug("ilbd_run_probe: posix_spawnattr_setsigdefault");
1324 goto cleanup;
1338 /*
1339 * If we are doing default pinging or not using a user supplied
1340 * probe, we should execute our standard supplied probe. The
1341 * supplied probe command handles all types of probes. And the
1342 * type used depends on argv[0], as filled in by create_argv().
1343 */
1344 if (srv->shc_state == ilbd_hc_def_pinging ||
1345 srv->shc_hc->ihc_test_type != ILBD_HC_USER) {
1346 probe_name = ILB_PROBE_PROTO;
1347 } else {
1348 probe_name = srv->shc_hc->ihc_test;
1349 }
1350 if (posix_spawn(&pid, probe_name, &fd_actions, &attr, child_argv,
1351 NULL) != 0) {
1352 logerr("%s: posix_spawn: %s for server %s: %s", __func__,
1353 srv->shc_hc->ihc_test, srv->shc_sg_srv->sgs_srvID,
1354 strerror(errno));
1355 goto cleanup;
1356 }
1357
1358 (void) close(fds[1]);
1359 destroy_argv(child_argv);
1360 srv->shc_child_pid = pid;
1361 srv->shc_child_fd = fds[0];
1362 srv->shc_ev = probe_ev;
1363
1364 probe_ev->ihp_ev = ILBD_EVENT_PROBE;
1365 probe_ev->ihp_srv = srv;
1366 probe_ev->ihp_pid = pid;
1367 if (port_associate(srv->shc_ev_port, PORT_SOURCE_FD, fds[0],
1368 POLLRDNORM, probe_ev) != 0) {
1369 /*
1370 * Need to kill the child. It will free the srv->shc_ev,
1371 * which is probe_ev. So set probe_ev to NULL.
1372 */
1373 ilbd_hc_kill_probe(srv);
1374 probe_ev = NULL;
1375 goto cleanup;
1376 }
1377
1378 return (B_TRUE);
1379
1380 cleanup:
1381 (void) close(fds[0]);
1382 (void) close(fds[1]);
1383 destroy_argv(child_argv);
1384 if (probe_ev != NULL)
1385 free(probe_ev);
1386 return (B_FALSE);
1387 }
1388
1389 /*
1390 * Called by ild_hc_probe_return() to re-associate the fd to a child to
1391 * the event port.
1392 */
1393 static void
1394 reassociate_port(int ev_port, int fd, ilbd_hc_probe_event_t *ev)
1395 {
1396 if (port_associate(ev_port, PORT_SOURCE_FD, fd,
1397 POLLRDNORM, ev) != 0) {
1398 /*
1399 * If we cannot reassociate with the port, the only
1400 * thing we can do now is to kill the child and
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
26 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
27 */
28
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/list.h>
32 #include <sys/stropts.h>
33 #include <sys/siginfo.h>
34 #include <sys/wait.h>
35 #include <arpa/inet.h>
36 #include <netinet/in.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <strings.h>
40 #include <stddef.h>
41 #include <unistd.h>
42 #include <libilb.h>
43 #include <port.h>
44 #include <time.h>
45 #include <signal.h>
46 #include <assert.h>
1272 pid_t pid;
1273 char *child_argv[HC_PROBE_ARGC];
1274 ilbd_hc_probe_event_t *probe_ev;
1275 char *probe_name;
1276
1277 bzero(child_argv, HC_PROBE_ARGC * sizeof (char *));
1278 if ((probe_ev = calloc(1, sizeof (*probe_ev))) == NULL) {
1279 logdebug("ilbd_run_probe: calloc");
1280 return (B_FALSE);
1281 }
1282
1283 /* Set up a pipe to get output from probe command. */
1284 if (pipe(fds) < 0) {
1285 logdebug("ilbd_run_probe: cannot create pipe");
1286 free(probe_ev);
1287 return (B_FALSE);
1288 }
1289 /* Set our side of the pipe to be non-blocking */
1290 if ((fdflags = fcntl(fds[0], F_GETFL, 0)) == -1) {
1291 logdebug("ilbd_run_probe: fcntl(F_GETFL)");
1292 goto cleanup_noactions;
1293 }
1294 if (fcntl(fds[0], F_SETFL, fdflags | O_NONBLOCK) == -1) {
1295 logdebug("ilbd_run_probe: fcntl(F_SETFL)");
1296 goto cleanup_noactions;
1297 }
1298
1299 if (posix_spawn_file_actions_init(&fd_actions) != 0) {
1300 logdebug("ilbd_run_probe: posix_spawn_file_actions_init");
1301 goto cleanup_noactions;
1302 }
1303 if (posix_spawnattr_init(&attr) != 0) {
1304 logdebug("ilbd_run_probe: posix_spawnattr_init");
1305 goto cleanup_noattr;
1306 }
1307 if (posix_spawn_file_actions_addclose(&fd_actions, fds[0]) != 0) {
1308 logdebug("ilbd_run_probe: posix_spawn_file_actions_addclose");
1309 goto cleanup;
1310 }
1311 if (posix_spawn_file_actions_adddup2(&fd_actions, fds[1],
1312 STDOUT_FILENO) != 0) {
1313 logdebug("ilbd_run_probe: posix_spawn_file_actions_dup2");
1314 goto cleanup;
1315 }
1316 if (posix_spawn_file_actions_addclose(&fd_actions, fds[1]) != 0) {
1317 logdebug("ilbd_run_probe: posix_spawn_file_actions_addclose");
1318 goto cleanup;
1319 }
1320
1321 /* Reset all signal handling of the child to default. */
1322 (void) sigfillset(&child_sigset);
1323 if (posix_spawnattr_setsigdefault(&attr, &child_sigset) != 0) {
1324 logdebug("ilbd_run_probe: posix_spawnattr_setsigdefault");
1325 goto cleanup;
1339 /*
1340 * If we are doing default pinging or not using a user supplied
1341 * probe, we should execute our standard supplied probe. The
1342 * supplied probe command handles all types of probes. And the
1343 * type used depends on argv[0], as filled in by create_argv().
1344 */
1345 if (srv->shc_state == ilbd_hc_def_pinging ||
1346 srv->shc_hc->ihc_test_type != ILBD_HC_USER) {
1347 probe_name = ILB_PROBE_PROTO;
1348 } else {
1349 probe_name = srv->shc_hc->ihc_test;
1350 }
1351 if (posix_spawn(&pid, probe_name, &fd_actions, &attr, child_argv,
1352 NULL) != 0) {
1353 logerr("%s: posix_spawn: %s for server %s: %s", __func__,
1354 srv->shc_hc->ihc_test, srv->shc_sg_srv->sgs_srvID,
1355 strerror(errno));
1356 goto cleanup;
1357 }
1358
1359 (void) posix_spawnattr_destroy(&attr);
1360 (void) posix_spawn_file_actions_destroy(&fd_actions);
1361 (void) close(fds[1]);
1362 srv->shc_child_pid = pid;
1363 srv->shc_child_fd = fds[0];
1364 srv->shc_ev = probe_ev;
1365
1366 probe_ev->ihp_ev = ILBD_EVENT_PROBE;
1367 probe_ev->ihp_srv = srv;
1368 probe_ev->ihp_pid = pid;
1369 if (port_associate(srv->shc_ev_port, PORT_SOURCE_FD, fds[0],
1370 POLLRDNORM, probe_ev) != 0) {
1371 /*
1372 * Need to kill the child. It will free the srv->shc_ev,
1373 * which is probe_ev. So set probe_ev to NULL.
1374 */
1375 ilbd_hc_kill_probe(srv);
1376 probe_ev = NULL;
1377 /* posix_spawn attrs & actions already destroyed. */
1378 goto cleanup_noactions;
1379 }
1380 destroy_argv(child_argv);
1381
1382 return (B_TRUE);
1383
1384 cleanup:
1385 (void) posix_spawnattr_destroy(&attr);
1386 cleanup_noattr:
1387 (void) posix_spawn_file_actions_destroy(&fd_actions);
1388 cleanup_noactions:
1389 (void) close(fds[0]);
1390 (void) close(fds[1]);
1391 destroy_argv(child_argv);
1392 if (probe_ev != NULL)
1393 free(probe_ev);
1394 return (B_FALSE);
1395 }
1396
1397 /*
1398 * Called by ild_hc_probe_return() to re-associate the fd to a child to
1399 * the event port.
1400 */
1401 static void
1402 reassociate_port(int ev_port, int fd, ilbd_hc_probe_event_t *ev)
1403 {
1404 if (port_associate(ev_port, PORT_SOURCE_FD, fd,
1405 POLLRDNORM, ev) != 0) {
1406 /*
1407 * If we cannot reassociate with the port, the only
1408 * thing we can do now is to kill the child and
|