-#ifndef _ALLOC_C_ /* -*- linux-c -*- */
+/* Memory allocation functions
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _ALLOC_C_
#define _ALLOC_C_
/** @file alloc.c
* that memory allocation errors will call a handler. The default will
* send a signal to the user-space daemon that will trigger the module to
* be unloaded.
- * @todo Need error handling for memory allocations
* @{
*/
-enum errorcode { ERR_NONE=0, ERR_NO_MEM };
-enum errorcode _stp_error = ERR_NONE;
-
/** Allocates memory within a probe.
* This is used for small allocations from within a running
* probe where the process cannot sleep.
{
void *ptr = kmalloc(len, GFP_ATOMIC);
if (unlikely(ptr == NULL))
- _stp_error = ERR_NO_MEM;
+ _stp_error("_stp_alloc failed.\n");
return ptr;
}
if (likely(ptr))
memset(ptr, 0, len);
else
- _stp_error = ERR_NO_MEM;
+ _stp_error("_stp_valloc failed.\n");
return ptr;
}
-#ifndef _IO_C_ /* -*- linux-c -*- */
+/* I/O for printing warnings, errors and debug messages
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _IO_C_
#define _IO_C_
#include "transport/transport.c"
/** @file io.c
- * @brief I/O functions
+ * @brief I/O for printing warnings, errors and debug messages.
*/
/** @addtogroup io I/O
- * I/O functions
* @{
*/
/** private buffer for _stp_log() */
#define STP_LOG_BUF_LEN 2047
+#define WARN_STRING "\033[33mWARNING: \033[0m"
+#define ERR_STRING "\033[31mERROR: \033[0m"
+
static char _stp_lbuf[NR_CPUS][STP_LOG_BUF_LEN + 1];
+enum code { INFO=0, WARN, ERROR, DBUG };
+
+void _stp_print_flush (void);
+void _stp_string_cat_cstr (String str1, const char *str2);
+
+static void _stp_vlog (enum code type, char *func, int line, const char *fmt, va_list args)
+{
+ int num, ret;
+ char *buf = &_stp_lbuf[get_cpu()][0];
+ int start = 0;
+
+ if (type == DBUG) {
+ start = scnprintf(buf, STP_LOG_BUF_LEN, "\033[36m%s:%d:\033[0m ", func, line);
+ } else if (type == WARN) {
+ strcpy (buf, WARN_STRING);
+ start = sizeof(WARN_STRING) - 1;
+ } else if (type == ERROR) {
+ strcpy (buf, ERR_STRING);
+ start = sizeof(ERR_STRING) - 1;
+ }
+
+ num = vscnprintf (buf + start, STP_LOG_BUF_LEN - start, fmt, args);
+ if (num + start) {
+ if (buf[num + start - 1] != '\n') {
+ buf[num + start] = '\n';
+ num++;
+ }
+ buf[num + start] = '\0';
+
+ ret = _stp_ctrl_send(STP_REALTIME_DATA, buf, start + num + 1, t->pid);
+ if (ret < 0)
+ atomic_inc(&_stp_transport_failures);
+#ifndef STP_NETLINK_ONLY
+ _stp_string_cat_cstr(_stp_stdout,buf);
+ _stp_print_flush();
+#endif
+ }
+ put_cpu();
+}
+
/** Logs Data.
- * This function sends the message immediately to stpd.
+ * This function sends the message immediately to stpd. It
+ * will also be sent over the bulk transport (relayfs) if it is
+ * being used. If the last character is not a newline, then one
+ * is added. This function is not as efficient as _stp_printf()
+ * and should only be used for urgent messages. You probably want
+ * dbug(), or _stp_warn().
* @param fmt A variable number of args.
- * @note Lines are limited in length by printk buffer. If there is
- * no newline in the format string, then other syslog output could
- * get appended to the SystemTap line.
* @todo Evaluate if this function is necessary.
*/
-
void _stp_log (const char *fmt, ...)
{
- int num, ret;
- char *buf = &_stp_lbuf[get_cpu()][0];
va_list args;
va_start(args, fmt);
- num = vscnprintf (buf, STP_LOG_BUF_LEN, fmt, args);
+ _stp_vlog (INFO, NULL, 0, fmt, args);
va_end(args);
- buf[num] = '\0';
+}
- ret = _stp_ctrl_send(STP_REALTIME_DATA, buf, num + 1, t->pid);
- if (ret < 0)
- atomic_inc (&_stp_transport_failures);
- put_cpu();
+/** Prints warning.
+ * This function sends a warning message immediately to stpd. It
+ * will also be sent over the bulk transport (relayfs) if it is
+ * being used. If the last character is not a newline, then one
+ * is added.
+ * @param fmt A variable number of args.
+ */
+void _stp_warn (const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ _stp_vlog (WARN, NULL, 0, fmt, args);
+ va_end(args);
+}
+
+/** Exits and unloads the module.
+ * This function sends a signal to stpd to tell it to
+ * unload the module and exit.
+ */
+void _stp_exit (void)
+{
+ schedule_work (&stp_exit);
+}
+
+/** Prints error message and exits.
+ * This function sends an error message immediately to stpd. It
+ * will also be sent over the bulk transport (relayfs) if it is
+ * being used. If the last character is not a newline, then one
+ * is added.
+ *
+ * After the error message is displayed, the module will be unloaded.
+ * @param fmt A variable number of args.
+ */
+void _stp_error (const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ _stp_vlog (ERROR, NULL, 0, fmt, args);
+ va_end(args);
+ _stp_exit();
+}
+
+static void _stp_dbug (char *func, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ _stp_vlog (DBUG, func, line, fmt, args);
+ va_end(args);
}
/** @} */