diff options
author | Hannes Reinecke <hare@suse.de> | 2008-04-08 16:51:27 +0200 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2008-04-08 14:04:30 -0500 |
commit | b7091cfb686c279c2fea9b634e9b2ef7da249d63 (patch) | |
tree | 21866eb127fd736bae57d755ba65417014a1e32a /usr | |
parent | 6ae9cb91b746defcf8b10bfae79665fedeca50ae (diff) | |
download | open-iscsi-b7091cfb686c279c2fea9b634e9b2ef7da249d63.tar.gz |
Fixup IPC leak in iscsid
Hi Mike,
iscsid is leaking IPC identifiers when the startup fails.
Please apply.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to open-iscsi-unsubscribe@googlegroups.com
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---
Fixup IPC leak in iscsid
If iscsid is terminated due to a failure we're leaking IPC ids.
And we're not clearing the log area, causing iscsid to oops if
invoked twice.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Diffstat (limited to 'usr')
-rw-r--r-- | usr/log.c | 76 | ||||
-rw-r--r-- | usr/log.h | 3 |
2 files changed, 53 insertions, 26 deletions
@@ -37,6 +37,33 @@ int log_level = 0; static int log_stop_daemon = 0; +static void free_logarea (void) +{ + int shmid; + + if (!la) + return; + + if (la->semid != -1) + semctl(la->semid, 0, IPC_RMID, la->semarg); + if (la->buff) { + shmdt(la->buff); + shmctl(la->shmid_buff, IPC_RMID, NULL); + la->buff = NULL; + la->shmid_buff = -1; + } + if (la->start) { + shmdt(la->start); + shmctl(la->shmid_msg, IPC_RMID, NULL); + la->start = NULL; + la->shmid_msg = -1; + } + shmid = la->shmid; + shmdt(la); + shmctl(shmid, IPC_RMID, NULL); + la = NULL; +} + static int logarea_init (int size) { int shmid; @@ -48,21 +75,28 @@ static int logarea_init (int size) return 1; la = shmat(shmid, NULL, 0); - if (!la) + if (!la) { + shmctl(shmid, IPC_RMID, NULL); return 1; + } + la->shmid = shmid; + la->start = NULL; + la->buff = NULL; + la->semid = -1; if (size < MAX_MSG_SIZE) size = DEFAULT_AREA_SIZE; if ((shmid = shmget(IPC_PRIVATE, size, 0644 | IPC_CREAT | IPC_EXCL)) == -1) { - shmdt(la); + free_logarea(); return 1; } + la->shmid_msg = shmid; - la->start = shmat(shmid, NULL, 0); + la->start = shmat(la->shmid_msg, NULL, 0); if (!la->start) { - shmdt(la); + free_logarea(); return 1; } memset(la->start, 0, size); @@ -74,32 +108,27 @@ static int logarea_init (int size) if ((shmid = shmget(IPC_PRIVATE, MAX_MSG_SIZE + sizeof(struct logmsg), 0644 | IPC_CREAT | IPC_EXCL)) == -1) { - shmdt(la->start); - shmdt(la); + free_logarea(); return 1; } la->buff = shmat(shmid, NULL, 0); if (!la->buff) { - shmdt(la->start); - shmdt(la); + free_logarea(); return 1; } if ((la->semid = semget(SEMKEY, 1, 0600 | IPC_CREAT)) < 0) { - shmdt(la->buff); - shmdt(la->start); - shmdt(la); + free_logarea(); return 1; } la->semarg.val=1; if (semctl(la->semid, 0, SETVAL, la->semarg) < 0) { - shmdt(la->buff); - shmdt(la->start); - shmdt(la); + free_logarea(); return 1; } + la->shmid_buff = shmid; la->ops[0].sem_num = 0; la->ops[0].sem_flg = 0; @@ -107,14 +136,6 @@ static int logarea_init (int size) } -static void free_logarea (void) -{ - shmdt(la->buff); - shmdt(la->start); - shmdt(la); - semctl(la->semid, 0, IPC_RMID, la->semarg); -} - #if LOGDBG static void dump_logarea (void) { @@ -196,7 +217,7 @@ int log_dequeue (void * buff) int len; if (la->empty) - return 1; + return 0; len = strlen((char *)&src->str) * sizeof(char) + sizeof(struct logmsg) + 1; @@ -215,7 +236,7 @@ int log_dequeue (void * buff) memset((void *)src, 0, len); - return la->empty; + return len; } /* @@ -314,19 +335,22 @@ static void __dump_char(int level, unsigned char *buf, int *cp, int ch) static void log_flush(void) { + int msglen; + while (!la->empty) { la->ops[0].sem_op = -1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop up failed %d", errno); exit(1); } - log_dequeue(la->buff); + msglen = log_dequeue(la->buff); la->ops[0].sem_op = 1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop down failed"); exit(1); } - log_syslog(la->buff); + if (msglen) + log_syslog(la->buff); } } @@ -51,6 +51,9 @@ struct logmsg { }; struct logarea { + int shmid; + int shmid_msg; + int shmid_buff; int empty; void *head; void *tail; |