[PATCH] Make ENOSPC not fatal in semaphore creation - Mailing list pgsql-hackers
From | mp39590@gmail.com |
---|---|
Subject | [PATCH] Make ENOSPC not fatal in semaphore creation |
Date | |
Msg-id | 20211017141128.26728-1-mp39590@gmail.com Whole thread Raw |
Responses |
Re: [PATCH] Make ENOSPC not fatal in semaphore creation
|
List | pgsql-hackers |
From: Mikhail <mp39590@gmail.com> We might be in situation when we have "just enough" semaphores in the system limit to start but previously crashed unexpectedly, in that case we won't be able to start again - semget() will return ENOSPC, despite the semaphores are ours, and we can recycle them, so check this situation and try to remove the semaphore, if we are unable - give up and abort. --- src/backend/port/sysv_sema.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c index 21c883ba9a..a889591dba 100644 --- a/src/backend/port/sysv_sema.c +++ b/src/backend/port/sysv_sema.c @@ -88,10 +88,6 @@ static void ReleaseSemaphores(int status, Datum arg); * * Attempt to create a new semaphore set with the specified key. * Will fail (return -1) if such a set already exists. - * - * If we fail with a failure code other than collision-with-existing-set, - * print out an error and abort. Other types of errors suggest nonrecoverable - * problems. */ static IpcSemaphoreId InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems) @@ -118,10 +114,33 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems) return -1; /* - * Else complain and abort + * We might be in situation when we have "just enough" semaphores in the system + * limit to start but previously crashed unexpectedly, in that case we won't be + * able to start again - semget() will return ENOSPC, despite the semaphores + * are ours, and we can recycle them, so check this situation and try to remove + * the semaphore, if we are unable - give up and abort. + * + * We use same semkey for every start - it's gotten from inode number of the + * data folder. So on repeated starts we will use the same key. */ + if (saved_errno == ENOSPC) + { + union semun semun; + + semId = semget(semKey, 0, 0); + + semun.val = 0; /* unused, but keep compiler quiet */ + if (semctl(semId, 0, IPC_RMID, semun) == 0) + { + /* Recycled - get the same semaphore again */ + semId = semget(semKey, numSems, IPC_CREAT | IPC_EXCL | IPCProtection); + + return semId; + } + } + ereport(FATAL, - (errmsg("could not create semaphores: %m"), + (errmsg("could not create semaphores: %s", strerror(saved_errno)), errdetail("Failed system call was semget(%lu, %d, 0%o).", (unsigned long) semKey, numSems, IPC_CREAT | IPC_EXCL | IPCProtection), -- 2.33.0
pgsql-hackers by date: