~ubuntu-branches/ubuntu/jaunty/trousers/jaunty

« back to all changes in this revision

Viewing changes to src/tcsd/tcsd_threads.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *
5
5
 * trousers - An open source TCG Software Stack
6
6
 *
7
 
 * (C) Copyright International Business Machines Corp. 2004
 
7
 * (C) Copyright International Business Machines Corp. 2004-2006
8
8
 *
9
9
 */
10
10
 
12
12
#include <stdlib.h>
13
13
#include <stdio.h>
14
14
#include <syslog.h>
15
 
#include <pthread.h>
16
15
#include <errno.h>
17
16
#include <string.h>
18
17
#include <unistd.h>
 
18
#include <sys/types.h>
 
19
#include <sys/socket.h>
19
20
 
20
21
#include "trousers/tss.h"
21
22
#include "trousers_types.h"
25
26
#include "tcsd_wrap.h"
26
27
#include "tcsd.h"
27
28
#include "tcslog.h"
 
29
#include "rpc_tcstp_tcs.h"
28
30
 
29
31
struct tcsd_thread_mgr *tm = NULL;
30
32
 
34
36
        int rc;
35
37
        UINT32 i;
36
38
 
37
 
        pthread_mutex_lock(&(tm->lock));
 
39
        MUTEX_LOCK(tm->lock);
38
40
 
39
41
        tm->shutdown = 1;
40
42
 
41
 
        pthread_mutex_unlock(&(tm->lock));
 
43
        MUTEX_UNLOCK(tm->lock);
42
44
 
43
45
        /* wait for all currently running threads to exit */
44
46
        for (i = 0; i < tm->max_threads; i++) {
45
 
                if (tm->thread_data[i].thread_id != (pthread_t)0) {
46
 
                        if ((rc = pthread_join(tm->thread_data[i].thread_id, NULL))) {
47
 
                                LogError("pthread_join() failed: error: %d", rc);
 
47
                if (tm->thread_data[i].thread_id != THREAD_NULL) {
 
48
                        if ((rc = THREAD_JOIN(tm->thread_data[i].thread_id, NULL))) {
 
49
                                LogError("Thread join failed: error: %d", rc);
48
50
                        }
49
51
                }
50
52
        }
87
89
        UINT32 thread_num;
88
90
#ifndef TCSD_SINGLE_THREAD_DEBUG
89
91
        int rc;
90
 
        pthread_attr_t tcsd_thread_attr;
 
92
        THREAD_ATTR_DECLARE(tcsd_thread_attr);
91
93
 
92
94
        /* init the thread attribute */
93
 
        if ((rc = pthread_attr_init(&tcsd_thread_attr))) {
94
 
                LogError("pthread_attr_init failed: error=%d: %s", rc, strerror(rc));
 
95
        if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) {
 
96
                LogError("Initializing thread attribute failed: error=%d: %s", rc, strerror(rc));
95
97
                return TCSERR(TSS_E_INTERNAL_ERROR);
96
98
        }
97
99
        /* make all threads joinable */
98
 
        if ((rc = pthread_attr_setdetachstate(&tcsd_thread_attr, PTHREAD_CREATE_JOINABLE))) {
99
 
                LogError("pthread_attr_init failed: error=%d: %s", rc, strerror(rc));
 
100
        if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) {
 
101
                LogError("Making thread attribute joinable failed: error=%d: %s", rc, strerror(rc));
100
102
                return TCSERR(TSS_E_INTERNAL_ERROR);
101
103
        }
102
104
 
103
 
        pthread_mutex_lock(&(tm->lock));
 
105
        MUTEX_LOCK(tm->lock);
104
106
#endif
105
107
        if (tm->num_active_threads == tm->max_threads) {
106
108
                close(socket);
112
114
                                 " refused.", tm->max_threads);
113
115
                }
114
116
                free(hostname);
115
 
                pthread_mutex_unlock(&(tm->lock));
 
117
                MUTEX_UNLOCK(tm->lock);
116
118
                return TCSERR(TSS_E_CONNECTION_FAILED);
117
119
        }
118
120
 
119
121
        /* search for an open slot to store the thread data in */
120
122
        for (thread_num = 0; thread_num < tm->max_threads; thread_num++) {
121
 
                if (tm->thread_data[thread_num].thread_id == (pthread_t)0)
 
123
                if (tm->thread_data[thread_num].thread_id == THREAD_NULL)
122
124
                        break;
123
125
        }
124
126
 
132
134
#ifdef TCSD_SINGLE_THREAD_DEBUG
133
135
        (void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num])));
134
136
#else
135
 
        if ((rc = pthread_create(&(tm->thread_data[thread_num].thread_id),
 
137
        if ((rc = THREAD_CREATE(&(tm->thread_data[thread_num].thread_id),
136
138
                                 &tcsd_thread_attr,
137
139
                                 tcsd_thread_run,
138
140
                                 (void *)(&(tm->thread_data[thread_num]))))) {
139
 
                LogError("pthread_create() failed: %d", rc);
140
 
                pthread_mutex_unlock(&(tm->lock));
 
141
                LogError("Thread create failed: %d", rc);
 
142
                MUTEX_UNLOCK(tm->lock);
141
143
                return TCSERR(TSS_E_INTERNAL_ERROR);
142
144
        }
143
145
 
144
146
        tm->num_active_threads++;
145
147
 
146
 
        pthread_mutex_unlock(&(tm->lock));
 
148
        MUTEX_UNLOCK(tm->lock);
147
149
#endif
148
150
        return TSS_SUCCESS;
149
151
}
150
152
 
151
 
/* since we don't want any of the worker threads to catch any signals,
152
 
 * we must mask off any potential signals here after creating the threads.  If any of
153
 
 * the created threads catch a signal, they'd eventually call pthread_join() on
154
 
 * themselves, causing a deadlock.
 
153
/* Since we don't want any of the worker threads to catch any signals, we must mask off any
 
154
 * potential signals here after creating the threads.  If any of the created threads catch a signal,
 
155
 * they'd eventually call join on themselves, causing a deadlock.
155
156
 */
156
157
void
157
158
thread_signal_init()
161
162
 
162
163
        if ((rc = sigfillset(&thread_sigmask))) {
163
164
                LogError("sigfillset failed: error=%d: %s", rc, strerror(rc));
164
 
                LogError("worker thread %u is exiting prematurely", (unsigned int)pthread_self());
165
 
                pthread_exit(NULL);
166
 
        }
167
 
 
168
 
        if ((rc = pthread_sigmask(SIG_BLOCK, &thread_sigmask, NULL))) {
169
 
                LogError("pthread_sigmask failed: error=%d: %s", rc, strerror(rc));
170
 
                LogError("worker thread %u is exiting prematurely", (unsigned int)pthread_self());
171
 
                pthread_exit(NULL);
172
 
        }
173
 
}
174
 
 
 
165
                LogError("worker thread %zd is exiting prematurely", THREAD_ID);
 
166
                THREAD_EXIT(NULL);
 
167
        }
 
168
 
 
169
        if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) {
 
170
                LogError("Setting thread sigmask failed: error=%d: %s", rc, strerror(rc));
 
171
                LogError("worker thread %zd is exiting prematurely", THREAD_ID);
 
172
                THREAD_EXIT(NULL);
 
173
        }
 
174
}
 
175
#if 0
 
176
void *
 
177
tcsd_thread_run(void *v)
 
178
{
 
179
        struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
 
180
        BYTE buffer[TCSD_TXBUF_SIZE];
 
181
        struct tcsd_packet_hdr *ret_buf = NULL;
 
182
        TSS_RESULT result;
 
183
        int sizeToSend, sent_total, sent;
 
184
        UINT64 offset;
 
185
#ifndef TCSD_SINGLE_THREAD_DEBUG
 
186
        int rc;
 
187
 
 
188
        thread_signal_init();
 
189
#endif
 
190
 
 
191
        if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
 
192
                LogError("Failed Receive: %s", strerror(errno));
 
193
                goto done;
 
194
        }
 
195
        LogDebug("Rx'd packet");
 
196
 
 
197
        data->buf = buffer;
 
198
 
 
199
        while (1) {
 
200
                sent_total = 0;
 
201
                if (data->buf_size > TCSD_TXBUF_SIZE) {
 
202
                        LogError("Packet received from socket %d was too large (%u bytes)",
 
203
                                 data->sock, data->buf_size);
 
204
                        goto done;
 
205
                } else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) {
 
206
                        LogError("Packet received from socket %d was too small (%u bytes)",
 
207
                                 data->sock, data->buf_size);
 
208
                        goto done;
 
209
                }
 
210
 
 
211
                if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) {
 
212
                        /* something internal to the TCSD went wrong in preparing the packet
 
213
                         * to return to the TSP.  Use our already allocated buffer to return a
 
214
                         * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
 
215
                         * these LoadBlob's are done in getTCSDPacket().
 
216
                         */
 
217
                        offset = 0;
 
218
                        /* load result */
 
219
                        LoadBlob_UINT32(&offset, result, buffer);
 
220
                        /* load packet size */
 
221
                        LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
 
222
                        /* load num parms */
 
223
                        LoadBlob_UINT16(&offset, 0, buffer);
 
224
 
 
225
                        sizeToSend = sizeof(struct tcsd_packet_hdr);
 
226
                        LogDebug("Sending 0x%X bytes back", sizeToSend);
 
227
 
 
228
                        while (sent_total < sizeToSend) {
 
229
                                if ((sent = send(data->sock,
 
230
                                                 &data->buf[sent_total],
 
231
                                                 sizeToSend - sent_total, 0)) < 0) {
 
232
                                        LogError("Packet send to TSP failed: send: %s. Thread exiting.",
 
233
                                                        strerror(errno));
 
234
                                        goto done;
 
235
                                }
 
236
                                sent_total += sent;
 
237
                        }
 
238
                } else {
 
239
                        sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));
 
240
 
 
241
                        LogDebug("Sending 0x%X bytes back", sizeToSend);
 
242
 
 
243
                        while (sent_total < sizeToSend) {
 
244
                                if ((sent = send(data->sock,
 
245
                                                 &(((BYTE *)ret_buf)[sent_total]),
 
246
                                                 sizeToSend - sent_total, 0)) < 0) {
 
247
                                        LogError("response to TSP failed: send: %s. Thread exiting.",
 
248
                                                        strerror(errno));
 
249
                                        free(ret_buf);
 
250
                                        ret_buf = NULL;
 
251
                                        goto done;
 
252
                                }
 
253
                                sent_total += sent;
 
254
                        }
 
255
                        free(ret_buf);
 
256
                        ret_buf = NULL;
 
257
                }
 
258
 
 
259
                if (tm->shutdown) {
 
260
                        LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
 
261
                        break;
 
262
                }
 
263
 
 
264
                /* receive the next packet */
 
265
                if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
 
266
                        LogError("TSP has closed its connection: %s. Thread exiting.",
 
267
                                 strerror(errno));
 
268
                        break;
 
269
                } else if (data->buf_size == 0) {
 
270
                        LogDebug("The TSP has closed the socket's connection. Thread exiting.");
 
271
                        break;
 
272
                }
 
273
        }
 
274
 
 
275
done:
 
276
        /* Closing connection to TSP */
 
277
        close(data->sock);
 
278
        data->sock = -1;
 
279
        data->buf = NULL;
 
280
        data->buf_size = -1;
 
281
        /* If the connection was not shut down cleanly, free TCS resources here */
 
282
        if (data->context != NULL_TCS_HANDLE) {
 
283
                TCS_CloseContext_Internal(data->context);
 
284
                data->context = NULL_TCS_HANDLE;
 
285
        }
 
286
 
 
287
#ifndef TCSD_SINGLE_THREAD_DEBUG
 
288
        MUTEX_LOCK(tm->lock);
 
289
        tm->num_active_threads--;
 
290
        /* if we're not in shutdown mode, then nobody is waiting to join this thread, so
 
291
         * detach it so that its resources are free at THREAD_EXIT() time. */
 
292
        if (!tm->shutdown) {
 
293
                if ((rc = THREAD_DETACH(data->thread_id))) {
 
294
                        LogError("Thread detach failed (errno %d)."
 
295
                                 " Resources may not be properly released.", rc);
 
296
                }
 
297
        }
 
298
        free(data->hostname);
 
299
        data->hostname = NULL;
 
300
        data->thread_id = THREAD_NULL;
 
301
        MUTEX_UNLOCK(tm->lock);
 
302
        THREAD_EXIT(NULL);
 
303
#else
 
304
        return NULL;
 
305
#endif
 
306
}
 
307
#else
175
308
void *
176
309
tcsd_thread_run(void *v)
177
310
{
194
327
                recv_size = sizeof(struct tcsd_packet_hdr);
195
328
                if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
196
329
                        break;
197
 
                buffer += sizeof(struct tcsd_packet_hdr);       /* increment the buffer pointer */
 
330
                buffer += sizeof(struct tcsd_packet_hdr);       /* increment the buffer pointer */
198
331
 
199
332
                /* check the packet size */
200
333
                recv_size = Decode_UINT32(data->comm.buf);
201
334
                if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
202
335
                        LogError("Packet to receive from socket %d is too small (%d bytes)",
203
 
                                 data->sock, recv_size);
 
336
                                        data->sock, recv_size);
204
337
                        break;
205
338
                }
206
339
 
219
352
                }
220
353
 
221
354
                /* get the rest of the packet */
222
 
                recv_size -= sizeof(struct tcsd_packet_hdr);    /* already received the header */
 
355
                recv_size -= sizeof(struct tcsd_packet_hdr);    /* already received the header */
223
356
                if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
224
357
                        break;
225
358
                LogDebug("Rx'd packet");
226
359
 
227
360
                /* create a platform version of the tcsd header */
228
361
                offset = 0;
229
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf, NULL);
230
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf, NULL);
231
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf, NULL);
232
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf, NULL);
233
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf, NULL);
234
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf, NULL);
235
 
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf, NULL);
 
362
                UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf);
 
363
                UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf);
 
364
                UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf);
 
365
                UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf);
 
366
                UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf);
 
367
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf);
 
368
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf);
236
369
 
237
370
                if ((result = getTCSDPacket(data)) != TSS_SUCCESS) {
238
371
                        /* something internal to the TCSD went wrong in preparing the packet
244
377
                        memset(data->comm.buf, 0, data->comm.buf_size);
245
378
                        offset = 0;
246
379
                        /* load packet size */
247
 
                        LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), data->comm.buf, NULL);
 
380
                        LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), data->comm.buf);
248
381
                        /* load result */
249
 
                        LoadBlob_UINT32(&offset, result, data->comm.buf, NULL);
 
382
                        LoadBlob_UINT32(&offset, result, data->comm.buf);
250
383
                }
251
384
                send_size = Decode_UINT32(data->comm.buf);
252
385
                LogDebug("Sending 0x%X bytes back", send_size);
256
389
 
257
390
                /* check for shutdown */
258
391
                if (tm->shutdown) {
259
 
                        LogDebug("Thread %u exiting via shutdown signal!", (unsigned int)pthread_self());
 
392
                        LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
260
393
                        break;
261
394
                }
262
395
        }
295
428
        return NULL;
296
429
#endif
297
430
}
 
431
 
 
432
#endif