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 all 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
206 changes: 81 additions & 125 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,13 @@
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
/*
* lock exists to protect fpLogfile
* Readers should hold the lock when access fpLogfile and the FILE it points to
* Writers should hold the lock when assigning fpLogfile or when freeing the
* object it points to
*/
static pthread_rwlock_t lock;


PMTC_S8 monthnames[] = {
Expand Down Expand Up @@ -115,17 +114,10 @@
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 +133,7 @@
// 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 +146,11 @@
// 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 +163,7 @@
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 +181,7 @@
{
initialized = FALSE;

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

if (fpLogfile)
{
Expand All @@ -213,14 +191,8 @@

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,61 +225,56 @@
return;
}

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

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

while (prioritynames[i].c_val != -1 &&
prioritynames[i].c_val != LOG_PRI(priority))
if (fpLogfile != NULL)
{
i++;
}
MTC_S32 i = 0;

while (prioritynames[i].c_val != -1 &&
prioritynames[i].c_val != LOG_PRI(priority))
{
i++;
}

now = time(NULL);
ptm = localtime(&now);
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);
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);
va_end(ap);

fflush(fpLogfile);

//
// Sometime, fsync() takes seconds or more.
// It may cause unexpected watchdog timeout.
// So we deceided that we do not use fsync().
//
// fsync(fileno(fpLogfile));
//

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

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors

Check warning

Code scanning / CodeChecker

format string is not a string literal Warning

format string is not a string literal
funlockfile(fpLogfile);
va_end(ap);

fflush(fpLogfile);

//
// Sometime, fsync() takes seconds or more.
// It may cause unexpected watchdog timeout.
// So we deceided that we do not use fsync().
//
// 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
}


// log_bin

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
//
// Log binary data
//
Expand All @@ -316,7 +283,7 @@
// priority - only MTC_LOG_PRIVATE_LOG flag is valid. The other flags
// are ignored.
// data - pointer to the data to be dumped
// size - size of dump data

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
//
// return value
//
Expand All @@ -332,46 +299,43 @@
return;
}

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

if (priority & MTC_LOG_PRIVATELOG && fpLogfile != NULL && privatelogflag)
if (priority & MTC_LOG_PRIVATELOG && privatelogflag)
{
for (line = 0, pos = 0; pos < size; line++)
{
fprintf(fpLogfile, "\t%04x: ", line);

for (col = 0; col < MAX_COL && pos < size; col++, pos++)
{
fprintf(fpLogfile, "%02x ", (MTC_U8) data[pos]);
asc_dmp[col] = (isprint(data[pos]))? data[pos]: '.';
}
asc_dmp[col] = '\0';
pthread_rwlock_rdlock(&lock);

for (; col < MAX_COL; col++)
if (fpLogfile != NULL)
{
flockfile(fpLogfile);
for (line = 0, pos = 0; pos < size; line++)
{
fprintf(fpLogfile, " ");
fprintf(fpLogfile, "\t%04x: ", line);

for (col = 0; col < MAX_COL && pos < size; col++, pos++)
{
fprintf(fpLogfile, "%02x ", (MTC_U8) data[pos]);
asc_dmp[col] = (isprint(data[pos]))? data[pos]: '.';
}
asc_dmp[col] = '\0';

for (; col < MAX_COL; col++)
{
fprintf(fpLogfile, " ");

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
}

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

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
}

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

//
// We don't use fsync(). See comments in log_message().
//
// fsync(fileno(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 All @@ -385,11 +349,11 @@
// log the logmask value.
//
// FORMAL PARAMETERS:
//

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
// none
//
// RETURN VALUE:
//

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
// none
//
// ENVIRONMENT:
Expand All @@ -401,7 +365,7 @@
void
log_logmask(void)
{
MTC_U32 logmask_index;

Check warning

Code scanning / CodeChecker

the value returned by this function should not be disregarded; neglecting it may lead to errors Warning

the value returned by this function should not be disregarded; neglecting it may lead to errors
char *logmask_name[LOG_MASK_BITS] = LOG_MASK_NAMES;

log_message(MTC_LOG_INFO, "LOG: logmask = %x\n", logmask);
Expand Down Expand Up @@ -572,18 +536,10 @@
return;
}

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