summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdhcpagent/common/dhcpagent_util.c')
-rw-r--r--usr/src/lib/libdhcpagent/common/dhcpagent_util.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/usr/src/lib/libdhcpagent/common/dhcpagent_util.c b/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
index e6d95cd0d1..1c381fa08f 100644
--- a/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
+++ b/usr/src/lib/libdhcpagent/common/dhcpagent_util.c
@@ -19,19 +19,24 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
+#include <sys/ctfs.h>
+#include <sys/contract/process.h>
#include <sys/socket.h>
#include <sys/time.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <libcontract.h>
+#include <libcontract_priv.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "dhcpagent_ipc.h"
#include "dhcpagent_util.h"
@@ -78,6 +83,31 @@ dhcp_state_to_string(DHCPSTATE state)
return (states[state]);
}
+static int
+init_template(void)
+{
+ int fd;
+ int err = 0;
+
+ fd = open64(CTFS_ROOT "/process/template", O_RDWR);
+ if (fd == -1)
+ return (-1);
+
+ /*
+ * Deliver no events, don't inherit, and allow it to be orphaned.
+ */
+ err |= ct_tmpl_set_critical(fd, 0);
+ err |= ct_tmpl_set_informative(fd, 0);
+ err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
+ err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
+ if (err != 0 || ct_tmpl_activate(fd) != 0) {
+ (void) close(fd);
+ return (-1);
+ }
+
+ return (fd);
+}
+
/*
* dhcp_start_agent(): starts the agent if not already running
*
@@ -92,6 +122,9 @@ dhcp_start_agent(int timeout)
time_t start_time = time(NULL);
dhcp_ipc_request_t *request;
dhcp_ipc_reply_t *reply;
+ int ctfd;
+ pid_t childpid;
+ ctid_t ct;
/*
* just send a dummy request to the agent to find out if it's
@@ -111,16 +144,20 @@ dhcp_start_agent(int timeout)
free(request);
return (0);
}
- if (error != DHCP_IPC_E_CONNECT) {
- free(request);
- return (-1);
- }
+ if (error != DHCP_IPC_E_CONNECT)
+ goto fail;
+
+ if ((ctfd = init_template()) == -1)
+ goto fail;
- switch (fork()) {
+ childpid = fork();
+ (void) ct_tmpl_clear(ctfd);
+ (void) close(ctfd);
+
+ switch (childpid) {
case -1:
- free(request);
- return (-1);
+ goto fail;
case 0:
(void) execl(DHCP_AGENT_PATH, DHCP_AGENT_PATH, (char *)0);
@@ -130,6 +167,12 @@ dhcp_start_agent(int timeout)
break;
}
+ /* wait for the daemon to run and then abandon the contract */
+ (void) waitpid(childpid, NULL, 0);
+
+ if (contract_latest(&ct) != -1)
+ (void) contract_abandon_id(ct);
+
while ((timeout != -1) && (time(NULL) - start_time < timeout)) {
error = dhcp_ipc_make_request(request, &reply, 0);
if (error == 0) {
@@ -141,6 +184,7 @@ dhcp_start_agent(int timeout)
(void) sleep(1);
}
+fail:
free(request);
return (-1);
}