diff options
-rw-r--r-- | lib/log.c | 178 | ||||
-rw-r--r-- | lib/log.h | 6 | ||||
-rw-r--r-- | lib/privs.c | 94 | ||||
-rw-r--r-- | lib/privs.h | 4 | ||||
-rw-r--r-- | lib/zassert.h | 16 |
5 files changed, 183 insertions, 115 deletions
@@ -34,26 +34,15 @@ #ifdef HAVE_UCONTEXT_H #include <ucontext.h> #endif -#include <pthread.h> -#include <assert.h> - -/* logging needs to be pthread safe */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -#if 0 -static int lock_count = 0; -#define LOCK if(lock_count++ != 0){printf("Lock count: %d\n", lock_count);assert(0);} -#define UNLOCK if(--lock_count != 0){printf("Unlock count: %d\n", lock_count);assert(0);} -#elif defined(NDEBUG) -#define LOCK pthread_mutex_lock(&mutex); -#define UNLOCK pthread_mutex_unlock(&mutex); -#else -#define LOCK if(pthread_mutex_lock(&mutex)!= 0){assert(0);}; -#define UNLOCK if(pthread_mutex_unlock(&mutex)!= 0){assert(0);}; -#endif +#include "qpthreads.h" + +/* Needs to be qpthread safe */ +static qpt_mutex_t* mx = NULL; /* prototypes */ static int do_reset_file (struct zlog *zl); static size_t do_timestamp(int timestamp_precision, char *buf, size_t buflen); +static void zlog_abort (const char *mess) __attribute__ ((noreturn)); static int logfile_fd = -1; /* Used in signal handler. */ @@ -87,6 +76,17 @@ const char *zlog_priority[] = NULL, }; +void +zlog_init_r(void) +{ + mx = qpt_mutex_init(mx, qpt_mutex_quagga); +} + +void +zlog_destroy_r(void) +{ + mx = qpt_mutex_destroy(mx, 1); +} /* For time string format. */ @@ -95,9 +95,9 @@ size_t quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) { size_t result; - LOCK + qpt_mutex_lock(mx); result = do_timestamp(timestamp_precision, buf, buflen); - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -189,7 +189,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) struct timestamp_control tsctl; tsctl.already_rendered = 0; - LOCK + qpt_mutex_lock(mx); /* If zlog is not specified, use default one. */ if (zl == NULL) @@ -257,12 +257,12 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args) const char *priority_name = (zl->record_priority ? zlog_priority[priority] : NULL); const char *proto_name = zlog_proto_names[zl->protocol]; - UNLOCK + qpt_mutex_unlock(mx); vty_log (priority_name, proto_name, format, &tsctl, args); return; } } - UNLOCK + qpt_mutex_unlock(mx); } static char * @@ -654,19 +654,65 @@ PLOG_FUNC(plog_debug, LOG_DEBUG) void _zlog_assert_failed (const char *assertion, const char *file, - unsigned int line, const char *function) + unsigned int line, const char *function) +{ + const static size_t buff_size = 1024; + char buff[buff_size]; + snprintf(buff, buff_size, + "Assertion `%s' failed in file %s, line %u, function %s", + assertion, file, line, (function ? function : "?")); + zlog_abort(buff); +} + +/* Abort with message */ +void +_zlog_abort_mess (const char *mess, const char *file, + unsigned int line, const char *function) +{ + const static size_t buff_size = 1024; + char buff[buff_size]; + snprintf(buff, buff_size, "%s, in file %s, line %u, function %s", + mess, file, line, (function ? function : "?")); + zlog_abort(buff); +} + +/* Abort with message and errno and strerror() thereof */ +void +_zlog_abort_errno (const char *mess, const char *file, + unsigned int line, const char *function) +{ + _zlog_abort_err(mess, errno, file, line, function); +} + +/* Abort with message and given error and strerror() thereof */ +void +_zlog_abort_err (const char *mess, int err, const char *file, + unsigned int line, const char *function) +{ + const static size_t buff_size = 1024; + char buff[buff_size]; + char err_mess[buff_size]; + strerror_r(err, err_mess, buff_size); + snprintf(buff, buff_size, + "%s, in file %s, line %u, function %s, error %d \"%s\"", + mess, file, line, (function ? function : "?"), + err, err_mess); + zlog_abort(buff); +} + + +static void +zlog_abort (const char *mess) { /* Force fallback file logging? */ - LOCK + qpt_mutex_lock(mx); if (zlog_default && !zlog_default->fp && ((logfile_fd = open_crashlog()) >= 0) && ((zlog_default->fp = fdopen(logfile_fd, "w")) != NULL)) zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR; - UNLOCK - - zlog(NULL, LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s", - assertion,file,line,(function ? function : "?")); + qpt_mutex_unlock(mx); + zlog(NULL, LOG_CRIT, "%s", mess); zlog_backtrace(LOG_CRIT); abort(); } @@ -701,7 +747,7 @@ openzlog (const char *progname, zlog_proto_t protocol, void closezlog (struct zlog *zl) { - LOCK + qpt_mutex_lock(mx); closelog(); @@ -710,14 +756,14 @@ closezlog (struct zlog *zl) XFREE (MTYPE_ZLOG, zl); - UNLOCK + qpt_mutex_unlock(mx); } /* Called from command.c. */ void zlog_set_level (struct zlog *zl, zlog_dest_t dest, int log_level) { - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -727,7 +773,7 @@ zlog_set_level (struct zlog *zl, zlog_dest_t dest, int log_level) zl->maxlvl[dest] = log_level; } - UNLOCK + qpt_mutex_unlock(mx); } int @@ -737,7 +783,7 @@ zlog_set_file (struct zlog *zl, const char *filename, int log_level) mode_t oldumask; int result = 1; - LOCK + qpt_mutex_lock(mx); /* There is opend file. */ do_reset_file (zl); @@ -764,7 +810,7 @@ zlog_set_file (struct zlog *zl, const char *filename, int log_level) } } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -773,9 +819,9 @@ int zlog_reset_file (struct zlog *zl) { int result; - LOCK + qpt_mutex_lock(mx); result = do_reset_file(zl); - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -807,7 +853,7 @@ zlog_rotate (struct zlog *zl) { int level; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -834,7 +880,7 @@ zlog_rotate (struct zlog *zl) { /* can't call logging while locked */ char *fname = strdup(zl->filename); - UNLOCK + qpt_mutex_unlock(mx); zlog_err("Log rotate failed: cannot open file %s for append: %s", fname, safe_strerror(save_errno)); free(fname); @@ -847,7 +893,7 @@ zlog_rotate (struct zlog *zl) } } } - UNLOCK + qpt_mutex_unlock(mx); return 1; } @@ -856,7 +902,7 @@ zlog_get_default_lvl (struct zlog *zl) { int result = LOG_DEBUG; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -866,14 +912,14 @@ zlog_get_default_lvl (struct zlog *zl) result = zl->default_lvl; } - UNLOCK + qpt_mutex_unlock(mx); return result; } void zlog_set_default_lvl (struct zlog *zl, int level) { - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -883,7 +929,7 @@ zlog_set_default_lvl (struct zlog *zl, int level) zl->default_lvl = level; } - UNLOCK + qpt_mutex_unlock(mx); } /* Set logging level and default for all destinations */ @@ -892,7 +938,7 @@ zlog_set_default_lvl_dest (struct zlog *zl, int level) { int i; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -906,7 +952,7 @@ zlog_set_default_lvl_dest (struct zlog *zl, int level) zl->maxlvl[i] = level; } - UNLOCK + qpt_mutex_unlock(mx); } int @@ -914,7 +960,7 @@ zlog_get_maxlvl (struct zlog *zl, zlog_dest_t dest) { int result = ZLOG_DISABLED; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -924,7 +970,7 @@ zlog_get_maxlvl (struct zlog *zl, zlog_dest_t dest) result = zl->maxlvl[dest]; } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -933,7 +979,7 @@ zlog_get_facility (struct zlog *zl) { int result = LOG_DAEMON; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -943,14 +989,14 @@ zlog_get_facility (struct zlog *zl) result = zl->facility; } - UNLOCK + qpt_mutex_unlock(mx); return result; } void zlog_set_facility (struct zlog *zl, int facility) { - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -960,7 +1006,7 @@ zlog_set_facility (struct zlog *zl, int facility) zl->facility = facility; } - UNLOCK + qpt_mutex_unlock(mx); } int @@ -968,7 +1014,7 @@ zlog_get_record_priority (struct zlog *zl) { int result = 0; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -978,14 +1024,14 @@ zlog_get_record_priority (struct zlog *zl) result = zl->record_priority; } - UNLOCK + qpt_mutex_unlock(mx); return result; } void zlog_set_record_priority (struct zlog *zl, int record_priority) { - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -994,7 +1040,7 @@ zlog_set_record_priority (struct zlog *zl, int record_priority) { zl->record_priority = record_priority; } - UNLOCK + qpt_mutex_unlock(mx); } int @@ -1002,7 +1048,7 @@ zlog_get_timestamp_precision (struct zlog *zl) { int result = 0; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1011,14 +1057,14 @@ zlog_get_timestamp_precision (struct zlog *zl) { result = zl->timestamp_precision; } - UNLOCK + qpt_mutex_unlock(mx); return result; } void zlog_set_timestamp_precision (struct zlog *zl, int timestamp_precision) { - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1028,7 +1074,7 @@ zlog_set_timestamp_precision (struct zlog *zl, int timestamp_precision) zl->timestamp_precision = timestamp_precision; } - UNLOCK + qpt_mutex_unlock(mx); } /* returns name of ZLOG_NONE if no zlog given and no default set */ @@ -1037,7 +1083,7 @@ zlog_get_proto_name (struct zlog *zl) { zlog_proto_t protocol = ZLOG_NONE; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1047,7 +1093,7 @@ zlog_get_proto_name (struct zlog *zl) protocol = zl->protocol; } - UNLOCK + qpt_mutex_unlock(mx); return zlog_proto_names[protocol]; } @@ -1057,7 +1103,7 @@ zlog_get_filename (struct zlog *zl) { char * result = NULL; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1067,7 +1113,7 @@ zlog_get_filename (struct zlog *zl) result = strdup(zl->filename); } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -1076,7 +1122,7 @@ zlog_get_ident (struct zlog *zl) { const char * result = NULL; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1086,7 +1132,7 @@ zlog_get_ident (struct zlog *zl) result = zl->ident; } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -1096,7 +1142,7 @@ zlog_is_file (struct zlog *zl) { int result = 0; - LOCK + qpt_mutex_lock(mx); if (zl == NULL) zl = zlog_default; @@ -1106,7 +1152,7 @@ zlog_is_file (struct zlog *zl) result = (zl->fp != NULL); } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -93,7 +93,11 @@ struct message const char *str; }; -/* Default logging strucutre. */ +/* module initialization */ +extern void zlog_init_r(void); +extern void zlog_destroy_r(void); + +/* Default logging structure. */ extern struct zlog *zlog_default; /* Open zlog function */ diff --git a/lib/privs.c b/lib/privs.c index a6592bea..68757340 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -25,21 +25,10 @@ #include "log.h" #include "privs.h" #include "memory.h" -#include <pthread.h> - -/* needs to be pthread safe */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -#if 0 -static int lock_count = 0; -#define LOCK if(lock_count++ != 0){printf("Lock count: %d\n", lock_count);assert(0);} -#define UNLOCK if(--lock_count != 0){printf("Unlock count: %d\n", lock_count);assert(0);} -#elif defined(NDEBUG) -#define LOCK pthread_mutex_lock(&mutex); -#define UNLOCK pthread_mutex_unlock(&mutex); -#else -#define LOCK if(pthread_mutex_lock(&mutex)!= 0){assert(0);}; -#define UNLOCK if(pthread_mutex_unlock(&mutex)!= 0){assert(0);}; -#endif +#include "qpthreads.h" + +/* Needs to be qpthread safe */ +static qpt_mutex_t* mx = NULL; #ifdef HAVE_CAPABILITIES /* sort out some generic internal types for: @@ -206,13 +195,13 @@ zprivs_change_caps (zebra_privs_ops_t op) int result = 0; int change = 0; - LOCK + qpt_mutex_lock(mx); /* should be no possibility of being called without valid caps */ assert (zprivs_state.syscaps_p && zprivs_state.caps); if (! (zprivs_state.syscaps_p && zprivs_state.caps)) { - UNLOCK + qpt_mutex_unlock(mx); exit (1); } @@ -237,7 +226,7 @@ zprivs_change_caps (zebra_privs_ops_t op) cflag)) result = cap_set_proc (zprivs_state.caps); - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -248,13 +237,13 @@ zprivs_state_caps (void) cap_flag_value_t val; zebra_privs_current_t result = ZPRIVS_LOWERED; - LOCK + qpt_mutex_lock(mx); /* should be no possibility of being called without valid caps */ assert (zprivs_state.syscaps_p && zprivs_state.caps); if (! (zprivs_state.syscaps_p && zprivs_state.caps)) { - UNLOCK + qpt_mutex_unlock(mx); exit (1); } @@ -275,7 +264,7 @@ zprivs_state_caps (void) } } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -423,14 +412,14 @@ zprivs_change_caps (zebra_privs_ops_t op) { int result = 0; - LOCK + qpt_mutex_lock(mx); /* should be no possibility of being called without valid caps */ assert (zprivs_state.syscaps_p); if (!zprivs_state.syscaps_p) { fprintf (stderr, "%s: Eek, missing caps!", __func__); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } @@ -458,7 +447,7 @@ zprivs_change_caps (zebra_privs_ops_t op) else result = -1; - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -470,7 +459,7 @@ zprivs_state_caps (void) zebra_privs_current_t result = ZPRIVS_UNKNOWN; pset_t *effective; - LOCK + qpt_mutex_lock(mx); if ( (effective = priv_allocset()) == NULL) { @@ -497,7 +486,7 @@ zprivs_state_caps (void) priv_freeset (effective); } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -628,7 +617,7 @@ zprivs_change_uid (zebra_privs_ops_t op) { int result = 0; - LOCK + qpt_mutex_lock(mx); if (op == ZPRIVS_RAISE) { @@ -649,7 +638,7 @@ zprivs_change_uid (zebra_privs_ops_t op) result = -1; } - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -658,9 +647,9 @@ zprivs_state_uid (void) { zebra_privs_current_t result; - LOCK + qpt_mutex_lock(mx); result = ( (zprivs_state.zuid == geteuid()) ? ZPRIVS_LOWERED : ZPRIVS_RAISED); - UNLOCK + qpt_mutex_unlock(mx); return result; } @@ -675,13 +664,26 @@ zprivs_state_null (void) { int result; - LOCK + qpt_mutex_lock(mx); result = zprivs_null_state; - UNLOCK + qpt_mutex_unlock(mx); return result; } void +zprivs_init_r(struct zebra_privs_t *zprivs) +{ + mx = qpt_mutex_init(mx, qpt_mutex_quagga); + zprivs_init(zprivs); +} + +void +zprivs_destroy_r(void) +{ + mx = qpt_mutex_destroy(mx, 1); +} + +void zprivs_init(struct zebra_privs_t *zprivs) { struct passwd *pwentry = NULL; @@ -693,7 +695,7 @@ zprivs_init(struct zebra_privs_t *zprivs) exit (1); } - LOCK + qpt_mutex_lock(mx); /* NULL privs */ if (! (zprivs->user || zprivs->group @@ -701,7 +703,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { zprivs->change = zprivs_change_null; zprivs->current_state = zprivs_state_null; - UNLOCK + qpt_mutex_unlock(mx); return; } @@ -716,7 +718,7 @@ zprivs_init(struct zebra_privs_t *zprivs) /* cant use log.h here as it depends on vty */ fprintf (stderr, "privs_init: could not lookup user %s\n", zprivs->user); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -733,7 +735,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { fprintf (stderr, "privs_init: could not setgroups, %s\n", safe_strerror (errno) ); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -741,7 +743,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { fprintf (stderr, "privs_init: could not lookup vty group %s\n", zprivs->vty_group); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -756,7 +758,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { fprintf (stderr, "privs_init: could not lookup group %s\n", zprivs->group); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } /* change group now, forever. uid we do later */ @@ -764,7 +766,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { fprintf (stderr, "zprivs_init: could not setregid, %s\n", safe_strerror (errno) ); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -785,7 +787,7 @@ zprivs_init(struct zebra_privs_t *zprivs) { fprintf (stderr, "privs_init (uid): could not setreuid, %s\n", safe_strerror (errno)); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -794,7 +796,7 @@ zprivs_init(struct zebra_privs_t *zprivs) zprivs->current_state = zprivs_state_uid; #endif /* HAVE_CAPABILITIES */ - UNLOCK + qpt_mutex_unlock(mx); } void @@ -806,7 +808,7 @@ zprivs_terminate (struct zebra_privs_t *zprivs) exit (0); } - LOCK + qpt_mutex_lock(mx); #ifdef HAVE_CAPABILITIES zprivs_caps_terminate(); @@ -817,7 +819,7 @@ zprivs_terminate (struct zebra_privs_t *zprivs) { fprintf (stderr, "privs_terminate: could not setreuid, %s", safe_strerror (errno) ); - UNLOCK + qpt_mutex_unlock(mx); exit (1); } } @@ -828,14 +830,14 @@ zprivs_terminate (struct zebra_privs_t *zprivs) zprivs_null_state = ZPRIVS_LOWERED; raise_count = 0; - UNLOCK + qpt_mutex_unlock(mx); return; } void zprivs_get_ids(struct zprivs_ids_t *ids) { - LOCK + qpt_mutex_lock(mx); ids->uid_priv = getuid(); (zprivs_state.zuid) ? (ids->uid_normal = zprivs_state.zuid) @@ -845,6 +847,6 @@ zprivs_get_ids(struct zprivs_ids_t *ids) (zprivs_state.vtygrp) ? (ids->gid_vty = zprivs_state.vtygrp) : (ids->gid_vty = -1); - UNLOCK + qpt_mutex_unlock(mx); return; } diff --git a/lib/privs.h b/lib/privs.h index 46d614e0..18d35d8d 100644 --- a/lib/privs.h +++ b/lib/privs.h @@ -81,9 +81,13 @@ struct zprivs_ids_t }; /* initialise zebra privileges */ +extern void zprivs_init_r (struct zebra_privs_t *zprivs); extern void zprivs_init (struct zebra_privs_t *zprivs); +extern void zprivs_destroy_r (void); + /* drop all and terminate privileges */ extern void zprivs_terminate (struct zebra_privs_t *); + /* query for runtime uid's and gid's, eg vty needs this */ extern void zprivs_get_ids(struct zprivs_ids_t *); diff --git a/lib/zassert.h b/lib/zassert.h index 26b67da6..424688b9 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -8,6 +8,18 @@ extern void _zlog_assert_failed (const char *assertion, const char *file, unsigned int line, const char *function) __attribute__ ((noreturn)); +extern void _zlog_abort_mess (const char *mess, const char *file, + unsigned int line, const char *function) + __attribute__ ((noreturn)); + +extern void _zlog_abort_errno (const char *mess, const char *file, + unsigned int line, const char *function) + __attribute__ ((noreturn)); + +extern void _zlog_abort_err (const char *mess, int err, const char *file, + unsigned int line, const char *function) + __attribute__ ((noreturn)); + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __ASSERT_FUNCTION __func__ @@ -42,11 +54,11 @@ extern void _zlog_assert_failed (const char *assertion, const char *file, __ASSERT_FUNCTION) /* Abort with message and errno and strerror() thereof */ -#define zabort_errno(MS) _zlog_assert_failed(MS, __FILE__, __LINE__, \ +#define zabort_errno(MS) _zlog_abort_errno(MS, __FILE__, __LINE__, \ __ASSERT_FUNCTION) /* Abort with message and given error and strerror() thereof */ -#define zabort_err(MS, ERR) _zlog_assert_failed(MS, __FILE__, __LINE__, \ +#define zabort_err(MS, ERR) _zlog_abort_err(MS, ERR, __FILE__, __LINE__, \ __ASSERT_FUNCTION) /*============================================================================== |