1373b4ef9b3d92400c2e2d2dec63f3f17fc24fe4
1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## bts595756-notify_email-segfault.dpatch
3 ## by Florian Forster <octo@verplant.org>
4 ##
5 ## DP: notify_email plugin: Serialize all accesses to libesmtp using a mutex.
6 ## DP:
7 ## DP: libesmtp is not thread-safe. This fixes segfaults when accessing the
8 ## DP: plugin in parallel.
10 @DPATCH@
12 diff a/src/notify_email.c b/src/notify_email.c
13 --- a/src/notify_email.c
14 +++ b/src/notify_email.c
15 @@ -1,6 +1,7 @@
16 /**
17 * collectd - src/notify_email.c
18 * Copyright (C) 2008 Oleg King
19 + * Copyright (C) 2010 Florian Forster
20 *
21 * This program is free software; you can redistribute it and/or modify it
22 * under the terms of the GNU General Public License as published by the
23 @@ -18,6 +19,7 @@
24 *
25 * Authors:
26 * Oleg King <king2 at kaluga.ru>
27 + * Florian Forster <octo at collectd.org>
28 **/
30 #include "collectd.h"
31 @@ -26,6 +28,7 @@
33 #include <auth-client.h>
34 #include <libesmtp.h>
35 +#include <pthread.h>
37 #define MAXSTRING 256
39 @@ -45,6 +48,7 @@ static char **recipients;
40 static int recipients_len = 0;
42 static smtp_session_t session;
43 +static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER;
44 static smtp_message_t message;
45 static auth_context_t authctx = NULL;
47 @@ -113,17 +117,23 @@ static int notify_email_init (void)
48 {
49 char server[MAXSTRING];
51 + ssnprintf(server, sizeof (server), "%s:%i",
52 + (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
53 + smtp_port);
54 +
55 + pthread_mutex_lock (&session_lock);
56 +
57 auth_client_init();
58 - if (!(session = smtp_create_session ())) {
59 +
60 + session = smtp_create_session ();
61 + if (session == NULL) {
62 + pthread_mutex_unlock (&session_lock);
63 ERROR ("notify_email plugin: cannot create SMTP session");
64 return (-1);
65 }
67 smtp_set_monitorcb (session, monitor_cb, NULL, 1);
68 smtp_set_hostname (session, hostname_g);
69 - ssnprintf(server, sizeof (server), "%s:%i",
70 - (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host,
71 - smtp_port);
72 smtp_set_server (session, server);
74 if (smtp_user && smtp_password) {
75 @@ -133,18 +143,30 @@ static int notify_email_init (void)
76 }
78 if ( !smtp_auth_set_context (session, authctx)) {
79 + pthread_mutex_unlock (&session_lock);
80 ERROR ("notify_email plugin: cannot set SMTP auth context");
81 return (-1);
82 }
84 + pthread_mutex_unlock (&session_lock);
85 return (0);
86 } /* int notify_email_init */
88 static int notify_email_shutdown (void)
89 {
90 - smtp_destroy_session (session);
91 - auth_destroy_context (authctx);
92 + pthread_mutex_lock (&session_lock);
93 +
94 + if (session != NULL)
95 + smtp_destroy_session (session);
96 + session = NULL;
97 +
98 + if (authctx != NULL)
99 + auth_destroy_context (authctx);
100 + authctx = NULL;
101 +
102 auth_client_exit();
103 +
104 + pthread_mutex_unlock (&session_lock);
105 return (0);
106 } /* int notify_email_shutdown */
108 @@ -248,7 +270,16 @@ static int notify_email_notification (const notification_t *n,
109 n->host,
110 n->message);
112 + pthread_mutex_lock (&session_lock);
113 +
114 + if (session == NULL) {
115 + /* Initialization failed or we're in the process of shutting down. */
116 + pthread_mutex_unlock (&session_lock);
117 + return (-1);
118 + }
119 +
120 if (!(message = smtp_add_message (session))) {
121 + pthread_mutex_unlock (&session_lock);
122 ERROR ("notify_email plugin: cannot set SMTP message");
123 return (-1);
124 }
125 @@ -264,6 +295,7 @@ static int notify_email_notification (const notification_t *n,
126 char buf[MAXSTRING];
127 ERROR ("notify_email plugin: SMTP server problem: %s",
128 smtp_strerror (smtp_errno (), buf, sizeof buf));
129 + pthread_mutex_unlock (&session_lock);
130 return (-1);
131 } else {
132 const smtp_status_t *status;
133 @@ -274,6 +306,7 @@ static int notify_email_notification (const notification_t *n,
134 smtp_enumerate_recipients (message, print_recipient_status, NULL);
135 }
137 + pthread_mutex_unlock (&session_lock);
138 return (0);
139 } /* int notify_email_notification */