Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CA-407313: Replace semaphore & spinlock with rwlock #26

Merged
merged 6 commits into from
Mar 5, 2025
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 21 additions & 79 deletions daemon/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
Expand All @@ -58,8 +58,6 @@
#include "log.h"


#define USE_SEMAPHORE 0


#define MTC_LOG_FILE_NAME "/var/log/xha.log"
#define MTC_XHA_MODULE_NAME "xha"
Expand All @@ -73,12 +71,7 @@ static FILE *fpLogfile = NULL;
static MTC_BOOLEAN initialized = FALSE;


#if USE_SEMAPHORE
#define MTC_LOG_SEMAPHORE_NAME "/xha_log_semaphore"
sem_t *semaphore = SEM_FAILED;
#else
static pthread_spinlock_t lock;
#endif
static pthread_rwlock_t lock;


PMTC_S8 monthnames[] = {
Expand Down Expand Up @@ -115,17 +108,10 @@ MTC_S32 log_initialize()
syslog(LOG_WARNING, "can't open local log file. (sys %d)", errno);
}

#if USE_SEMAPHORE
semaphore = sem_open(MTC_LOG_SEMAPHORE_NAME, O_CREAT, S_IRUSR | S_IWUSR, 1);
if (semaphore == SEM_FAILED)
{
syslog(LOG_ERR, "can't open semaphore %s. (sys %d)", MTC_LOG_SEMAPHORE_NAME, errno);
#else
ret = pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE);
ret = pthread_rwlock_init(&lock, PTHREAD_PROCESS_PRIVATE);
if (ret)
{
syslog(LOG_ERR, "can't initialize spin lock. (sys %d)", ret);
#endif
syslog(LOG_ERR, "can't initialize rwlock. (sys %d)", ret);
return MTC_ERROR_LOG_PTHREAD;
}

Expand All @@ -141,7 +127,7 @@ MTC_S32 log_initialize()
// This function should be called from ha_log_reopen script
// when log files is rotated.
//
// Smaple logrotate config file </etc/logrotate.d/xha>
// Sample logrotate config file </etc/logrotate.d/xha>
// /var/log/xha.log {
// rotate 5
// size 100k
Expand All @@ -154,17 +140,11 @@ MTC_S32 log_initialize()
// paramaters
//
// return value
// 0: success
// not 0: fail
//

void log_reopen()
{
#if USE_SEMAPHORE
sem_wait(semaphore);
#else
pthread_spin_lock(&lock);
#endif
pthread_rwlock_wrlock(&lock);

if (fpLogfile)
{
Expand All @@ -177,11 +157,7 @@ void log_reopen()
syslog(LOG_WARNING, "can't open local log file. (sys %d)", errno);
}

#if USE_SEMAPHORE
sem_post(semaphore);
#else
pthread_spin_unlock(&lock);
#endif
pthread_rwlock_unlock(&lock);
}


Expand All @@ -199,11 +175,7 @@ void log_terminate()
{
initialized = FALSE;

#if USE_SEMAPHORE
sem_wait(semaphore);
#else
pthread_spin_lock(&lock);
#endif
pthread_rwlock_wrlock(&lock);

if (fpLogfile)
{
Expand All @@ -213,14 +185,8 @@ void log_terminate()

closelog();

#if USE_SEMAPHORE
sem_post(semaphore);
sem_close(semaphore);
sem_unlink(MTC_LOG_SEMAPHORE_NAME);
#else
pthread_spin_unlock(&lock);
pthread_spin_destroy(&lock);
#endif
pthread_rwlock_unlock(&lock);
pthread_rwlock_destroy(&lock);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't checked the order of cleanup/termination, but destroying the lock can be problematic if other threads try to use it afterwards. I realized that the previous code did this too...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll investigate the clean up order to determine if this can safely be destroyed here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log_terminate is used once when the threads haven't been setup yet (e.g. if a license check fails), and again after the clean up once each of the threads have been terminated
Therefore destroying the lock during log_terminate is safe

}


Expand Down Expand Up @@ -253,14 +219,10 @@ void log_message(MTC_S32 priority, PMTC_S8 fmt, ...)
return;
}

#if USE_SEMAPHORE
sem_wait(semaphore);
#else
pthread_spin_lock(&lock);
#endif

if (priority & MTC_LOG_PRIVATELOG && fpLogfile != NULL && privatelogflag)
{
pthread_rwlock_rdlock(&lock);

MTC_S32 i = 0;

while (prioritynames[i].c_val != -1 &&
Expand All @@ -271,13 +233,15 @@ void log_message(MTC_S32 priority, PMTC_S8 fmt, ...)

now = time(NULL);
ptm = localtime(&now);
flockfile(fpLogfile);
fprintf(fpLogfile, "%s %02d %02d:%02d:%02d %s %04d [%s] ",
monthnames[ptm->tm_mon], ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec,
ptm->tm_zone, 1900 + ptm->tm_year, prioritynames[i].c_name);

va_start(ap, fmt);
vfprintf(fpLogfile, fmt, ap);
funlockfile(fpLogfile);
va_end(ap);

fflush(fpLogfile);
Expand All @@ -290,20 +254,14 @@ void log_message(MTC_S32 priority, PMTC_S8 fmt, ...)
// fsync(fileno(fpLogfile));
//


pthread_rwlock_unlock(&lock);
}
if ((logmask & MTC_LOG_MASK_SYSLOG) || (priority & MTC_LOG_SYSLOG))
{
va_start(ap, fmt);
vsyslog(LOG_PRI(priority), fmt, ap);
va_end(ap);
}

#if USE_SEMAPHORE
sem_post(semaphore);
#else
pthread_spin_unlock(&lock);
#endif
}


Expand Down Expand Up @@ -332,14 +290,10 @@ void log_bin(MTC_S32 priority, PMTC_S8 data, MTC_S32 size)
return;
}

#if USE_SEMAPHORE
sem_wait(semaphore);
#else
pthread_spin_lock(&lock);
#endif

if (priority & MTC_LOG_PRIVATELOG && fpLogfile != NULL && privatelogflag)
{
pthread_rwlock_rdlock(&lock);
flockfile(fpLogfile);
for (line = 0, pos = 0; pos < size; line++)
{
fprintf(fpLogfile, "\t%04x: ", line);
Expand All @@ -358,20 +312,16 @@ void log_bin(MTC_S32 priority, PMTC_S8 data, MTC_S32 size)

fprintf(fpLogfile, ": %s\n", asc_dmp);
}
funlockfile(fpLogfile);
fflush(fpLogfile);

//
// We don't use fsync(). See comments in log_message().
//
// fsync(fileno(fpLogfile));
//
pthread_rwlock_unlock(&lock);
}

#if USE_SEMAPHORE
sem_post(semaphore);
#else
pthread_spin_unlock(&lock);
#endif
}

//
Expand Down Expand Up @@ -572,18 +522,10 @@ log_fsync()
return;
}

#if USE_SEMAPHORE
sem_wait(semaphore);
#else
pthread_spin_lock(&lock);
#endif
pthread_rwlock_wrlock(&lock);
if (fpLogfile)
{
fsync(fileno(fpLogfile));
}
#if USE_SEMAPHORE
sem_post(semaphore);
#else
pthread_spin_unlock(&lock);
#endif
pthread_rwlock_unlock(&lock);
}