Blame libmultipath/log.c

Packit Service 0af388
/*
Packit Service 0af388
 * Copyright (c) 2005 Christophe Varoqui
Packit Service 0af388
 * Copyright (c) 2005 Benjamin Marzinski, Redhat
Packit Service 0af388
 * Copyright (c) 2005 Jun'ichi Nomura, NEC
Packit Service 0af388
 */
Packit Service 0af388
#include <stdio.h>
Packit Service 0af388
#include <stdlib.h>
Packit Service 0af388
#include <stdarg.h>
Packit Service 0af388
#include <string.h>
Packit Service 0af388
#include <syslog.h>
Packit Service 0af388
#include <time.h>
Packit Service 0af388
Packit Service 0af388
#include "memory.h"
Packit Service 0af388
#include "log.h"
Packit Service 0af388
Packit Service 0af388
#define ALIGN(len, s) (((len)+(s)-1)/(s)*(s))
Packit Service 0af388
Packit Service 0af388
struct logarea* la;
Packit Service 0af388
Packit Service 0af388
#if LOGDBG
Packit Service 0af388
static void dump_logarea (void)
Packit Service 0af388
{
Packit Service 0af388
	struct logmsg * msg;
Packit Service 0af388
Packit Service 0af388
	logdbg(stderr, "\n==== area: start addr = %p, end addr = %p ====\n",
Packit Service 0af388
		la->start, la->end);
Packit Service 0af388
	logdbg(stderr, "|addr     |next     |prio|msg\n");
Packit Service 0af388
Packit Service 0af388
	for (msg = (struct logmsg *)la->head; (void *)msg != la->tail;
Packit Service 0af388
	     msg = msg->next)
Packit Service 0af388
		logdbg(stderr, "|%p |%p |%i   |%s\n", (void *)msg, msg->next,
Packit Service 0af388
				msg->prio, (char *)&msg->str);
Packit Service 0af388
Packit Service 0af388
	logdbg(stderr, "|%p |%p |%i   |%s\n", (void *)msg, msg->next,
Packit Service 0af388
			msg->prio, (char *)&msg->str);
Packit Service 0af388
Packit Service 0af388
	logdbg(stderr, "\n\n");
Packit Service 0af388
}
Packit Service 0af388
#endif
Packit Service 0af388
Packit Service 0af388
static int logarea_init (int size)
Packit Service 0af388
{
Packit Service 0af388
	logdbg(stderr,"enter logarea_init\n");
Packit Service 0af388
	la = (struct logarea *)MALLOC(sizeof(struct logarea));
Packit Service 0af388
Packit Service 0af388
	if (!la)
Packit Service 0af388
		return 1;
Packit Service 0af388
Packit Service 0af388
	if (size < MAX_MSG_SIZE)
Packit Service 0af388
		size = DEFAULT_AREA_SIZE;
Packit Service 0af388
Packit Service 0af388
	la->start = MALLOC(size);
Packit Service 0af388
	if (!la->start) {
Packit Service 0af388
		FREE(la);
Packit Service 0af388
		return 1;
Packit Service 0af388
	}
Packit Service 0af388
	memset(la->start, 0, size);
Packit Service 0af388
Packit Service 0af388
	la->empty = 1;
Packit Service 0af388
	la->end = la->start + size;
Packit Service 0af388
	la->head = la->start;
Packit Service 0af388
	la->tail = la->start;
Packit Service 0af388
Packit Service 0af388
	la->buff = MALLOC(MAX_MSG_SIZE + sizeof(struct logmsg));
Packit Service 0af388
Packit Service 0af388
	if (!la->buff) {
Packit Service 0af388
		FREE(la->start);
Packit Service 0af388
		FREE(la);
Packit Service 0af388
		return 1;
Packit Service 0af388
	}
Packit Service 0af388
	return 0;
Packit Service 0af388
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
int log_init(char *program_name, int size)
Packit Service 0af388
{
Packit Service 0af388
	logdbg(stderr,"enter log_init\n");
Packit Service 0af388
	openlog(program_name, 0, LOG_DAEMON);
Packit Service 0af388
Packit Service 0af388
	if (logarea_init(size))
Packit Service 0af388
		return 1;
Packit Service 0af388
Packit Service 0af388
	return 0;
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
void free_logarea (void)
Packit Service 0af388
{
Packit Service 0af388
	FREE(la->start);
Packit Service 0af388
	FREE(la->buff);
Packit Service 0af388
	FREE(la);
Packit Service 0af388
	return;
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
void log_close (void)
Packit Service 0af388
{
Packit Service 0af388
	free_logarea();
Packit Service 0af388
	closelog();
Packit Service 0af388
Packit Service 0af388
	return;
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
void log_reset (char *program_name)
Packit Service 0af388
{
Packit Service 0af388
	closelog();
Packit Service 0af388
	tzset();
Packit Service 0af388
	openlog(program_name, 0, LOG_DAEMON);
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
int log_enqueue (int prio, const char * fmt, va_list ap)
Packit Service 0af388
{
Packit Service 0af388
	int len, fwd;
Packit Service 0af388
	char buff[MAX_MSG_SIZE];
Packit Service 0af388
	struct logmsg * msg;
Packit Service 0af388
	struct logmsg * lastmsg;
Packit Service 0af388
Packit Service 0af388
	lastmsg = (struct logmsg *)la->tail;
Packit Service 0af388
Packit Service 0af388
	if (!la->empty) {
Packit Service 0af388
		fwd = sizeof(struct logmsg) +
Packit Service 0af388
		      strlen((char *)&lastmsg->str) * sizeof(char) + 1;
Packit Service 0af388
		la->tail += ALIGN(fwd, sizeof(void *));
Packit Service 0af388
	}
Packit Service 0af388
	vsnprintf(buff, MAX_MSG_SIZE, fmt, ap);
Packit Service 0af388
	len = ALIGN(sizeof(struct logmsg) + strlen(buff) * sizeof(char) + 1,
Packit Service 0af388
		    sizeof(void *));
Packit Service 0af388
Packit Service 0af388
	/* not enough space on tail : rewind */
Packit Service 0af388
	if (la->head <= la->tail && len > (la->end - la->tail)) {
Packit Service 0af388
		logdbg(stderr, "enqueue: rewind tail to %p\n", la->tail);
Packit Service 0af388
		if (la->head == la->start ) {
Packit Service 0af388
			logdbg(stderr, "enqueue: can not rewind tail, drop msg\n");
Packit Service 0af388
			la->tail = lastmsg;
Packit Service 0af388
			return 1;  /* can't reuse */
Packit Service 0af388
		}
Packit Service 0af388
		la->tail = la->start;
Packit Service 0af388
Packit Service 0af388
		if (la->empty)
Packit Service 0af388
			la->head = la->start;
Packit Service 0af388
	}
Packit Service 0af388
Packit Service 0af388
	/* not enough space on head : drop msg */
Packit Service 0af388
	if (la->head > la->tail && len >= (la->head - la->tail)) {
Packit Service 0af388
		logdbg(stderr, "enqueue: log area overrun, drop msg\n");
Packit Service 0af388
Packit Service 0af388
		if (!la->empty)
Packit Service 0af388
			la->tail = lastmsg;
Packit Service 0af388
Packit Service 0af388
		return 1;
Packit Service 0af388
	}
Packit Service 0af388
Packit Service 0af388
	/* ok, we can stage the msg in the area */
Packit Service 0af388
	la->empty = 0;
Packit Service 0af388
	msg = (struct logmsg *)la->tail;
Packit Service 0af388
	msg->prio = prio;
Packit Service 0af388
	memcpy((void *)&msg->str, buff, strlen(buff) + 1);
Packit Service 0af388
	lastmsg->next = la->tail;
Packit Service 0af388
	msg->next = la->head;
Packit Service 0af388
Packit Service 0af388
	logdbg(stderr, "enqueue: %p, %p, %i, %s\n", (void *)msg, msg->next,
Packit Service 0af388
		msg->prio, (char *)&msg->str);
Packit Service 0af388
Packit Service 0af388
#if LOGDBG
Packit Service 0af388
	dump_logarea();
Packit Service 0af388
#endif
Packit Service 0af388
	return 0;
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
int log_dequeue (void * buff)
Packit Service 0af388
{
Packit Service 0af388
	struct logmsg * src = (struct logmsg *)la->head;
Packit Service 0af388
	struct logmsg * dst = (struct logmsg *)buff;
Packit Service 0af388
	struct logmsg * lst = (struct logmsg *)la->tail;
Packit Service 0af388
Packit Service 0af388
	if (la->empty)
Packit Service 0af388
		return 1;
Packit Service 0af388
Packit Service 0af388
	int len = strlen((char *)&src->str) * sizeof(char) +
Packit Service 0af388
		  sizeof(struct logmsg) + 1;
Packit Service 0af388
Packit Service 0af388
	dst->prio = src->prio;
Packit Service 0af388
	memcpy(dst, src,  len);
Packit Service 0af388
Packit Service 0af388
	if (la->tail == la->head)
Packit Service 0af388
		la->empty = 1; /* we purge the last logmsg */
Packit Service 0af388
	else {
Packit Service 0af388
		la->head = src->next;
Packit Service 0af388
		lst->next = la->head;
Packit Service 0af388
	}
Packit Service 0af388
	logdbg(stderr, "dequeue: %p, %p, %i, %s\n",
Packit Service 0af388
		(void *)src, src->next, src->prio, (char *)&src->str);
Packit Service 0af388
Packit Service 0af388
	memset((void *)src, 0,  len);
Packit Service 0af388
Packit Service 0af388
	return 0;
Packit Service 0af388
}
Packit Service 0af388
Packit Service 0af388
/*
Packit Service 0af388
 * this one can block under memory pressure
Packit Service 0af388
 */
Packit Service 0af388
void log_syslog (void * buff)
Packit Service 0af388
{
Packit Service 0af388
	struct logmsg * msg = (struct logmsg *)buff;
Packit Service 0af388
Packit Service 0af388
	syslog(msg->prio, "%s", (char *)&msg->str);
Packit Service 0af388
}