# HG changeset patch # User Bryan Cantrill # Date 1375635518 25200 # Node ID 790945ad784833b881233a24cee28ec77756698a # Parent 615580eeb3d89d5bbdea65f0b594423799f69a79 3986 svc.startd dies in getutxent_frec() 3987 svc.startd dies in utmpx_postfork() Reviewed by: Keith Wesolowski Reviewed by: Robert Mustacchi Reviewed by: Saso Kiselkov Approved by: Richard Lowe diff -r 615580eeb3d8 -r 790945ad7848 usr/src/cmd/svc/startd/fork.c --- a/usr/src/cmd/svc/startd/fork.c Thu Aug 08 14:17:55 2013 -0700 +++ b/usr/src/cmd/svc/startd/fork.c Sun Aug 04 09:58:38 2013 -0700 @@ -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 @@ * prefork stack */ wait_prefork(); + utmpx_prefork(); p = fork1(); @@ -81,6 +86,7 @@ /* * postfork stack */ + utmpx_postfork(); wait_postfork(p); return (p); @@ -169,6 +175,8 @@ /* NOTREACHED */ } + utmpx_prefork(); + /* * Attempt to fork "retries" times. */ @@ -181,6 +189,7 @@ 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 @@ (void) sleep(tries); } + utmpx_postfork(); + /* * Clean up, return pid and ctid. */ diff -r 615580eeb3d8 -r 790945ad7848 usr/src/cmd/svc/startd/startd.c --- a/usr/src/cmd/svc/startd/startd.c Thu Aug 08 14:17:55 2013 -0700 +++ b/usr/src/cmd/svc/startd/startd.c Sun Aug 04 09:58:38 2013 -0700 @@ -771,6 +771,11 @@ log_framework(LOG_DEBUG, "Existing configd contract %ld; not " "starting svc.configd\n", configd_ctid); + /* + * Call utmpx_init() before creating the fork_configd() thread. + */ + utmpx_init(); + (void) startd_thread_create(fork_configd_thread, (void *)configd_ctid); /* @@ -786,7 +791,6 @@ } MUTEX_UNLOCK(&st->st_configd_live_lock); - utmpx_init(); wait_init(); if (read_startd_config()) diff -r 615580eeb3d8 -r 790945ad7848 usr/src/cmd/svc/startd/startd.h --- a/usr/src/cmd/svc/startd/startd.h Thu Aug 08 14:17:55 2013 -0700 +++ b/usr/src/cmd/svc/startd/startd.h Sun Aug 04 09:58:38 2013 -0700 @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #ifndef _STARTD_H @@ -768,6 +769,8 @@ 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 -r 615580eeb3d8 -r 790945ad7848 usr/src/cmd/svc/startd/utmpx.c --- a/usr/src/cmd/svc/startd/utmpx.c Thu Aug 08 14:17:55 2013 -0700 +++ b/usr/src/cmd/svc/startd/utmpx.c Sun Aug 04 09:58:38 2013 -0700 @@ -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 @@ { (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); +}