summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2008-04-08 16:51:27 +0200
committerMike Christie <michaelc@cs.wisc.edu>2008-04-08 14:04:30 -0500
commitb7091cfb686c279c2fea9b634e9b2ef7da249d63 (patch)
tree21866eb127fd736bae57d755ba65417014a1e32a /usr
parent6ae9cb91b746defcf8b10bfae79665fedeca50ae (diff)
downloadopen-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.c76
-rw-r--r--usr/log.h3
2 files changed, 53 insertions, 26 deletions
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;