Hi Mike, iscsid is leaking IPC identifiers when the startup fails.
Please apply. Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage [EMAIL PROTECTED] +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 [EMAIL PROTECTED] 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 <[EMAIL PROTECTED]> diff --git a/usr/log.c b/usr/log.c index 9b82c46..013caed 100644 --- a/usr/log.c +++ b/usr/log.c @@ -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); } } diff --git a/usr/log.h b/usr/log.h index 4816a1b..4d2a265 100644 --- a/usr/log.h +++ b/usr/log.h @@ -51,6 +51,9 @@ struct logmsg { }; struct logarea { + int shmid; + int shmid_msg; + int shmid_buff; int empty; void *head; void *tail;