summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorVuong Nguyen <Vuong.Nguyen@Sun.COM>2010-05-28 14:36:29 -0700
committerVuong Nguyen <Vuong.Nguyen@Sun.COM>2010-05-28 14:36:29 -0700
commitf044df33d9fe9e8e3ed7344a8b548b17f20709f2 (patch)
treecebc50555ea22ae6486f75e2e1c4f7a385913d99 /usr/src
parent40e886f92f4231c9632666933a33b7c1ff729da3 (diff)
downloadillumos-joyent-f044df33d9fe9e8e3ed7344a8b548b17f20709f2.tar.gz
6953679 sun4v: SIGTERM coming from libldom on topo_snap_release()
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c53
-rw-r--r--usr/src/lib/fm/libldom/sparc/ldom_utils.c66
-rw-r--r--usr/src/lib/fm/libldom/sparc/ldom_utils.h5
-rw-r--r--usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c37
4 files changed, 75 insertions, 86 deletions
diff --git a/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c b/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c
index 9367cc0221..be9e78cc3e 100644
--- a/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c
+++ b/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdlib.h>
@@ -104,7 +103,7 @@ static struct poller_s {
pthread_mutex_t mt;
pthread_cond_t cv;
pthread_t polling_tid;
- int polling_thr_sig;
+ int notify_pipe[2];
int doreset;
int doexit;
int nclients;
@@ -115,7 +114,7 @@ static struct poller_s {
PTHREAD_MUTEX_INITIALIZER,
PTHREAD_COND_INITIALIZER,
0,
- SIGTERM,
+ {-1, -1},
1,
0,
0,
@@ -190,7 +189,7 @@ read_stream(int fd, void *buf, size_t size)
*/
do {
if ((rv = read(fd, (void *)currentp, data_left)) < 0) {
- if (errno == EAGAIN && poll(&pollfd, 1, -1) > 0)
+ if (errno == EAGAIN && poll(&pollfd, 1, 3000) > 0)
continue; /* retry */
else
return (1);
@@ -427,9 +426,11 @@ poller_shutdown(boolean_t wait)
(void) pthread_mutex_unlock(&pollbase.mt);
if (wait == B_TRUE) {
- /* stop the poller thread and wait for it to end */
- (void) pthread_kill(pollbase.polling_tid,
- pollbase.polling_thr_sig);
+ /*
+ * Write a byte to the pipe to notify the poller thread to exit.
+ * Then wait for it to exit.
+ */
+ (void) write(pollbase.notify_pipe[0], "1", 1);
(void) pthread_join(pollbase.polling_tid, NULL);
}
}
@@ -444,7 +445,9 @@ static void *
poller_loop(void *arg)
{
struct ldmsvcs_info *lsp;
- pollfd_t pollfd;
+ pollfd_t pollfd[2];
+ struct pollfd *pipe_fd = &pollfd[0];
+ struct pollfd *recv_fd = &pollfd[1];
int ier;
lsp = (struct ldmsvcs_info *)arg;
@@ -470,6 +473,7 @@ poller_loop(void *arg)
pollbase.doreset = 0;
}
+
(void) pthread_mutex_unlock(&pollbase.mt);
if ((ier = channel_openreset(lsp)) == 1) {
@@ -482,18 +486,28 @@ poller_loop(void *arg)
continue;
}
- pollfd.events = POLLIN;
- pollfd.revents = 0;
- pollfd.fd = lsp->fds_chan.fd;
+ pipe_fd->fd = pollbase.notify_pipe[1]; /* notification pipe */
+ pipe_fd->events = POLLIN;
+ pipe_fd->revents = 0;
+ recv_fd->fd = lsp->fds_chan.fd; /* FMA LDC */
+ recv_fd->events = POLLIN;
+ recv_fd->revents = 0;
- if (poll(&pollfd, 1, -1) <= 0 || read_msg(lsp) != 0) {
- /*
- * read error and/or fd got closed
- */
+ if (poll(pollfd, 2, -1) <= 0) {
+ /* fd got closed */
+ (void) pthread_mutex_lock(&pollbase.mt);
+ pollbase.doreset = 1;
+ (void) pthread_mutex_unlock(&pollbase.mt);
+ channel_close(lsp);
+ } else if (pipe_fd->revents & POLLIN) {
+ /* Receive a notification to exit */
+ channel_close(lsp);
+ pthread_exit((void *)NULL);
+ } else if (read_msg(lsp) != 0) {
+ /* fail to read a message from the LDOM manager */
(void) pthread_mutex_lock(&pollbase.mt);
pollbase.doreset = 1;
(void) pthread_mutex_unlock(&pollbase.mt);
-
channel_close(lsp);
}
}
@@ -517,10 +531,9 @@ poller_init(struct ldmsvcs_info *lsp)
/*
* create a joinable polling thread for receiving messages
- * The polling_thr_sig stores the signal number that is not
- * currently masked. it is used to stop the poller thread.
+ * The notify pipe is for stopping the thread
*/
- pollbase.polling_thr_sig = ldom_find_thr_sig();
+ (void) notify_setup(pollbase.notify_pipe);
if (pthread_create(&pollbase.polling_tid, attr,
poller_loop, lsp) != 0)
rc = 1;
diff --git a/usr/src/lib/fm/libldom/sparc/ldom_utils.c b/usr/src/lib/fm/libldom/sparc/ldom_utils.c
index 2fe3961bd9..1bb7482c76 100644
--- a/usr/src/lib/fm/libldom/sparc/ldom_utils.c
+++ b/usr/src/lib/fm/libldom/sparc/ldom_utils.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -31,60 +30,17 @@
*/
#include <stdio.h>
-#include <signal.h>
-#include <pthread.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
-/*
- * ldom_find_thr_sig()
- * Description:
- * Find an unmasked signal which is used for terminating the thread
- *
- * If the libldom.so thread is started before all fmd modules are loaded,
- * all signals are unmasked. Either SIGTERM or SIGUSR1 can be used to
- * stop the thread.
- * If the thread is started by a fmd module, fmd has masked all signals
- * except the client.thrsig and a list of reserver/non-catchable signals.
- * The fmd client.thrsig signal must be used to stop the thread. The default
- * value of the client.thrsig is SIGUSR1.
- *
- * This fucntion first tries to check if the SIGTERM, SIGUSR1 or SIGUSR2
- * signal is umasked. If so, select this signal.
- * Otherwise, go through all the signals and find an umasked one.
- */
-int
-ldom_find_thr_sig(void)
+boolean_t
+notify_setup(int *notify_pipe)
{
- int i;
- sigset_t oset, rset;
- int sig[] = {SIGTERM, SIGUSR1, SIGUSR2};
- int sig_sz = sizeof (sig) / sizeof (int);
- int rc = SIGTERM;
-
- /* prefered set of signals that are likely used to terminate threads */
- (void) sigemptyset(&oset);
- (void) pthread_sigmask(SIG_SETMASK, NULL, &oset);
- for (i = 0; i < sig_sz; i++) {
- if (sigismember(&oset, sig[i]) == 0) {
- return (sig[i]);
- }
+ if (pipe(notify_pipe) < 0) {
+ return (B_FALSE);
+ } else {
+ fcntl(notify_pipe[1], F_SETFL, O_NONBLOCK);
}
-
- /* reserved set of signals that are not allowed to terminate thread */
- (void) sigemptyset(&rset);
- (void) sigaddset(&rset, SIGABRT);
- (void) sigaddset(&rset, SIGKILL);
- (void) sigaddset(&rset, SIGSTOP);
- (void) sigaddset(&rset, SIGCANCEL);
-
- /* Find signal that is not masked and not in the reserved list. */
- for (i = 1; i < MAXSIG; i++) {
- if (sigismember(&rset, i) == 1) {
- continue;
- }
- if (sigismember(&oset, i) == 0) {
- return (i);
- }
- }
-
- return (rc);
+ return (B_TRUE);
}
diff --git a/usr/src/lib/fm/libldom/sparc/ldom_utils.h b/usr/src/lib/fm/libldom/sparc/ldom_utils.h
index 3475120e9e..995a956213 100644
--- a/usr/src/lib/fm/libldom/sparc/ldom_utils.h
+++ b/usr/src/lib/fm/libldom/sparc/ldom_utils.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -35,7 +34,7 @@
extern "C" {
#endif
-extern int ldom_find_thr_sig(void);
+extern boolean_t notify_setup(int *);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c b/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c
index fdf15cf489..f183b5b7f9 100644
--- a/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c
+++ b/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -81,7 +80,7 @@ static void handle_ldm_resp(xmpp_conn_t *conn, char *buf, size_t buf_size);
static void handle_ldm_event(xmpp_conn_t *conn, char *buf, size_t buf_size);
static int xmpp_enable = 0;
-static int xmpp_thr_sig = SIGTERM;
+static int xmpp_notify_pipe[2];
static pthread_t xmpp_tid = 0;
static pthread_mutex_t xmpp_tid_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -344,6 +343,9 @@ xmpp_client_thr(void *data)
int cnt;
char buf[XMPP_BUF_SIZE];
xmpp_conn_t conn;
+ pollfd_t pollfd[2];
+ struct pollfd *pipe_fd = &pollfd[0];
+ struct pollfd *recv_fd = &pollfd[1];
while (xmpp_enable) {
/* clear the conn struct */
@@ -364,10 +366,26 @@ xmpp_client_thr(void *data)
continue;
}
+ pipe_fd->fd = xmpp_notify_pipe[1]; /* notification pipe */
+ pipe_fd->events = POLLIN;
+ recv_fd->fd = conn.fd; /* XMPP connection */
+ recv_fd->events = POLLIN;
+
/* process input */
while ((conn.state != CONN_STATE_FAILURE) &&
(conn.state != CONN_STATE_DONE) && xmpp_enable) {
+ /* Wait for xmpp input or the notification */
+ pipe_fd->revents = 0;
+ recv_fd->revents = 0;
+ if (poll(pollfd, 2, -1) <= 0) {
+ break;
+ } else if (pipe_fd->revents & POLLIN) {
+ /* Receive a notification to exit */
+ xmpp_close(&conn);
+ pthread_exit((void *)NULL);
+ }
+
/*
* Assume the document size of a ldmd response is
* less than 1KB. This assumption is valid with the
@@ -517,7 +535,11 @@ xmpp_stop(void)
(void) pthread_mutex_lock(&xmpp_tid_lock);
xmpp_enable = 0;
if (xmpp_tid) {
- (void) pthread_kill(xmpp_tid, xmpp_thr_sig);
+ /*
+ * Write a byte to the pipe to notify the xmpp thread to exit.
+ * Then wait for it to exit.
+ */
+ (void) write(xmpp_notify_pipe[0], "1", 1);
(void) pthread_join(xmpp_tid, NULL);
xmpp_tid = 0;
}
@@ -550,11 +572,10 @@ xmpp_start(void)
xmpp_enable = 1;
/*
- * create xmpp client thread for receiving domain events
- * xmpp_thr_sig stores the signal number that is not currently masked.
- * It is used to stop the client thread.
+ * create xmpp client thread for receiving domain events.
+ * The notification pipe is for stopping the thread.
*/
- xmpp_thr_sig = ldom_find_thr_sig();
+ (void) notify_setup(xmpp_notify_pipe);
(void) pthread_create(&xmpp_tid, NULL, xmpp_client_thr, NULL);
(void) pthread_mutex_unlock(&xmpp_tid_lock);