summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2013-01-24 23:09:17 +0000
committerBryan Cantrill <bryan@joyent.com>2013-01-24 23:09:17 +0000
commit99f3047c0126e494b457dc700d8c43747e8e28ac (patch)
tree42925ce4c8407878929b6feb68cfd7e0b6505be0 /usr/src
parentbfb56a46ed22310699783e45d5a609dd541bb536 (diff)
downloadillumos-joyent-99f3047c0126e494b457dc700d8c43747e8e28ac.tar.gz
OS-1822 svc.startd dies in getutxent_frec()
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/svc/startd/fork.c11
-rw-r--r--usr/src/cmd/svc/startd/startd.h4
-rw-r--r--usr/src/cmd/svc/startd/utmpx.c21
3 files changed, 34 insertions, 2 deletions
diff --git a/usr/src/cmd/svc/startd/fork.c b/usr/src/cmd/svc/startd/fork.c
index 4717d491b3..7bce347854 100644
--- a/usr/src/cmd/svc/startd/fork.c
+++ b/usr/src/cmd/svc/startd/fork.c
@@ -25,6 +25,10 @@
*/
/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+/*
* fork.c - safe forking for svc.startd
*
* fork_configd() and fork_sulogin() are related, special cases that handle the
@@ -72,6 +76,7 @@ startd_fork1(int *forkerr)
* prefork stack
*/
wait_prefork();
+ utmpx_prefork();
p = fork1();
@@ -81,6 +86,7 @@ startd_fork1(int *forkerr)
/*
* postfork stack
*/
+ utmpx_postfork();
wait_postfork(p);
return (p);
@@ -169,6 +175,8 @@ fork_common(const char *name, const char *svc_fmri, int retries, ctid_t *ctidp,
/* NOTREACHED */
}
+ utmpx_prefork();
+
/*
* Attempt to fork "retries" times.
*/
@@ -181,6 +189,7 @@ fork_common(const char *name, const char *svc_fmri, int retries, ctid_t *ctidp,
err = errno;
(void) ct_tmpl_clear(ctfd);
(void) close(ctfd);
+ utmpx_postfork();
fork_sulogin(B_TRUE, "Could not fork to start %s: %s\n",
name, strerror(err));
/* NOTREACHED */
@@ -188,6 +197,8 @@ fork_common(const char *name, const char *svc_fmri, int retries, ctid_t *ctidp,
(void) sleep(tries);
}
+ utmpx_postfork();
+
/*
* Clean up, return pid and ctid.
*/
diff --git a/usr/src/cmd/svc/startd/startd.h b/usr/src/cmd/svc/startd/startd.h
index 61f710c31e..e4f37a4213 100644
--- a/usr/src/cmd/svc/startd/startd.h
+++ b/usr/src/cmd/svc/startd/startd.h
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#ifndef _STARTD_H
@@ -775,6 +775,8 @@ void utmpx_mark_dead(pid_t, int, boolean_t);
char utmpx_get_runlevel(void);
void utmpx_set_runlevel(char, char, boolean_t);
void utmpx_write_boottime(void);
+void utmpx_prefork(void);
+void utmpx_postfork(void);
/* wait.c */
void wait_init(void);
diff --git a/usr/src/cmd/svc/startd/utmpx.c b/usr/src/cmd/svc/startd/utmpx.c
index 83b9380271..1b3ca95010 100644
--- a/usr/src/cmd/svc/startd/utmpx.c
+++ b/usr/src/cmd/svc/startd/utmpx.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
/*
* utmpx.c - utmpx utility routines
@@ -418,3 +420,20 @@ utmpx_init()
{
(void) pthread_mutex_init(&utmpx_lock, &mutex_attrs);
}
+
+void
+utmpx_prefork()
+{
+ /*
+ * The libc utmpx routines are entirely MT-unsafe; we must assure
+ * that no other thread is in these routines when we fork lest we
+ * leave the child with inconsistent library state.
+ */
+ MUTEX_LOCK(&utmpx_lock);
+}
+
+void
+utmpx_postfork()
+{
+ MUTEX_UNLOCK(&utmpx_lock);
+}