summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1997-11-01 08:13:42 +0000
committerAndrew Tridgell <tridge@samba.org>1997-11-01 08:13:42 +0000
commit92fcced605374948e2481edecaf290c5bea717d5 (patch)
tree239314cb72ed661e7525a8e6023ad7ec2cb15ffe
parent264b1e0e75ae63467b6fe51b339e1e5f3c4477bc (diff)
downloadsamba-92fcced605374948e2481edecaf290c5bea717d5.tar.gz
samba-92fcced605374948e2481edecaf290c5bea717d5.tar.bz2
samba-92fcced605374948e2481edecaf290c5bea717d5.zip
don't use SEM_UNDO because of ridiculously small undo limits on some
OSes. Instead add explicit checks for dead locks at startup. (This used to be commit 79858d610c37675b9dc56a949723053ac9b67620)
-rw-r--r--source3/locking/shmem_sysv.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/source3/locking/shmem_sysv.c b/source3/locking/shmem_sysv.c
index 14ed199738..826de5694c 100644
--- a/source3/locking/shmem_sysv.c
+++ b/source3/locking/shmem_sysv.c
@@ -119,7 +119,7 @@ static BOOL sem_change(int i, int op)
sb.sem_num = i;
sb.sem_op = op;
- sb.sem_flg = SEM_UNDO;
+ sb.sem_flg = 0;
ret = semop(sem_id, &sb, 1);
@@ -539,6 +539,7 @@ struct shmem_ops *sysv_shm_open(int ronly)
struct semid_ds sem_ds;
union semun su;
int i;
+ int pid;
read_only = ronly;
@@ -595,6 +596,16 @@ struct shmem_ops *sysv_shm_open(int ronly)
return NULL;
}
+ if (semctl(sem_id, 0, GETVAL, su) == 0 &&
+ !process_exists((pid=semctl(sem_id, 0, GETPID, su)))) {
+ DEBUG(0,("WARNING: clearing global IPC lock set by dead process %d\n",
+ pid));
+ su.val = 1;
+ if (semctl(sem_id, 0, SETVAL, su) != 0) {
+ DEBUG(0,("ERROR: Failed to clear global lock\n"));
+ }
+ }
+
sem_ds.sem_perm.mode = SEMAPHORE_PERMS;
if (semctl(sem_id, 0, IPC_SET, su) != 0) {
DEBUG(0,("ERROR shm_open : can't IPC_SET\n"));
@@ -605,6 +616,19 @@ struct shmem_ops *sysv_shm_open(int ronly)
if (!global_lock())
return NULL;
+
+
+ for (i=1;i<hash_size+1;i++) {
+ if (semctl(sem_id, i, GETVAL, su) == 0 &&
+ !process_exists((pid=semctl(sem_id, i, GETPID, su)))) {
+ DEBUG(1,("WARNING: clearing IPC lock %d set by dead process %d\n",
+ i, pid));
+ su.val = 1;
+ if (semctl(sem_id, i, SETVAL, su) != 0) {
+ DEBUG(0,("ERROR: Failed to clear IPC lock %d\n", i));
+ }
+ }
+ }
/* try to use an existing key */
shm_id = shmget(SHMEM_KEY, shm_size, 0);