fp = fopen("/proc/mounts", "r");
if (!fp) {
log(ALL, LOG_INFO, "Can't open /proc/mounts");
- return errno;
+ return -errno;
}
do {
if (rc < 0)
return rc;
- return open(fname, flags);
+ rc = open(fname, flags);
+ if (rc)
+ return -errno;
+
+ return 0;
}
static int get_tracing_dir(struct ras_events *ras)
dir = opendir(fname);
if (!dir)
- return -1;
+ return -EINVAL;
for (entry = readdir(dir); entry; entry = readdir(dir)) {
if (strstr(entry->d_name, "instances")) {
log(ALL, LOG_INFO,
"Unable to create " TOOL_NAME " instance at %s\n",
ras->tracing);
- return -1;
+ return -EINVAL;
}
}
return 0;
}
-static int is_disabled_event(char *group, char *event)
+static bool is_disabled_event(char *group, char *event)
{
char ras_event_name[MAX_PATH + 1];
if (choices_disable && strlen(choices_disable) != 0 &&
strstr(choices_disable, ras_event_name)) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/*
fd = open_trace(ras, "set_event", O_RDWR | O_APPEND);
if (fd < 0) {
log(ALL, LOG_WARNING, "Can't open set_event\n");
- return errno;
+ return -errno;
}
rc = write(fd, fname, strlen(fname));
close(fd);
if (!rc) {
log(ALL, LOG_WARNING, "Nothing was written on set_event\n");
- return EIO;
+ return -EIO;
}
log(ALL, LOG_INFO, "%s:%s event %s\n",
ras = calloc(1, sizeof(*ras));
if (!ras) {
log(TERM, LOG_ERR, "Can't allocate memory for ras struct\n");
- return errno;
+ return -errno;
}
rc = get_tracing_dir(ras);
free_ras:
free(ras);
- return rc;
+ if (rc)
+ return -EINVAL;
+
+ return 0;
}
static void setup_event_trigger(char *event)
fd = open_trace(ras, fname, O_RDWR | O_APPEND);
if (fd < 0) {
log(ALL, LOG_WARNING, "Can't open filter file\n");
- return errno;
+ return -errno;
}
rc = write(fd, filter_str, strlen(filter_str));
close(fd);
if (!rc) {
log(ALL, LOG_WARNING, "Nothing was written on filter file\n");
- return EIO;
+ return -EIO;
}
return 0;
static int get_num_cpus(struct ras_events *ras)
{
- return sysconf(_SC_NPROCESSORS_ONLN);
+ int cpus;
+
+ cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ assert(cpus > 0);
+ return cpus;
}
static int set_buffer_percent(struct ras_events *ras, int percent)
size = write(fd, buf, strlen(buf));
if (size <= 0) {
log(TERM, LOG_WARNING, "can't write to buffer_percent\n");
- res = -1;
+ res = -EINVAL;
}
close(fd);
} else {
log(TERM, LOG_WARNING, "Can't open buffer_percent\n");
- res = -1;
+ res = -EINVAL;
}
return res;
}
+/*
+ * Kernel tracepoint had an incompatible change in 2019, causing polling
+ * tracepoints to fail. Rasdaemon can support both legacy and newer versions,
+ * with the help of a backup-compatibility legacy kernel mode.
+ *
+ * The LEGACY_KERNEL flag indicates the need to enable such code.
+ */
+#define LEGACY_KERNEL 255
+
static int read_ras_event_all_cpus(struct pthread_data *pdata,
unsigned int n_cpus)
{
}
if (legacy_kernel)
- return -255;
- else
- return -1;
+ return LEGACY_KERNEL;
+
+ return -EINVAL;
}
static int read_ras_event(int fd,
size = read(fd, page, pdata->ras->page_size);
if (size < 0) {
log(TERM, LOG_WARNING, "read\n");
- return -1;
+ return -EINVAL;
} else if (size > 0) {
kbuffer_load_subbuffer(kbuf, page);
fd = open_trace(ras, "trace_clock", O_RDONLY);
if (fd < 0) {
log(TERM, LOG_ERR, "Can't open trace_clock\n");
- return -1;
+ return -EINVAL;
}
size = read(fd, buf, sizeof(buf));
close(fd);
if (!size) {
log(TERM, LOG_ERR, "trace_clock is empty!\n");
- return -1;
+ return -EINVAL;
}
if (!strstr(buf, UPTIME)) {
fclose(fp);
if (rc <= 0) {
log(TERM, LOG_ERR, "Can't parse /proc/uptime!\n");
- return -1;
+ return -EINVAL;
}
now = time(NULL);
return 0;
}
+#define EVENT_DISABLED 1
+
static int add_event_handler(struct ras_events *ras, struct tep_handle *pevent,
unsigned int page_size, char *group, char *event,
tep_event_handler_func func, char *filter_str, int id)
log(TERM, LOG_ERR,
"Can't get %s:%s traces. Perhaps this feature is not supported on your system.\n",
group, event);
- return errno;
+ return -errno;
}
page = malloc(page_size);
if (!page) {
log(TERM, LOG_ERR, "Can't allocate page to read %s:%s format\n",
group, event);
- rc = errno;
+ rc = -errno;
close(fd);
return rc;
}
log(TERM, LOG_ERR, "Can't register event handler for %s:%s\n",
group, event);
free(page);
- return EINVAL;
+ return -EINVAL;
}
rc = tep_parse_event(pevent, page, size, group);
if (rc) {
log(TERM, LOG_ERR, "Can't parse event %s:%s\n", group, event);
free(page);
- return EINVAL;
+ return -EINVAL;
}
if (filter_str) {
log(TERM, LOG_ERR,
"Failed to allocate filter for %s/%s.\n", group, event);
free(page);
- return EINVAL;
+ return -EINVAL;
}
rc = tep_filter_add_filter_str(filter, filter_str);
if (rc < 0) {
if (is_disabled_event(group, event)) {
log(ALL, LOG_INFO, "Disabled %s:%s tracing from config\n",
group, event);
- return -EINVAL;
+ return EVENT_DISABLED;
}
/* Enable RAS events */
log(TERM, LOG_ERR, "Can't enable %s:%s tracing\n",
group, event);
- return EINVAL;
+ return -EINVAL;
}
setup_event_trigger(event);
ras = calloc(1, sizeof(*ras));
if (!ras) {
log(TERM, LOG_ERR, "Can't allocate memory for ras struct\n");
- return errno;
+ return -errno;
}
rc = get_tracing_dir(ras);
pevent = tep_alloc();
if (!pevent) {
log(TERM, LOG_ERR, "Can't allocate pevent\n");
- rc = errno;
+ rc = -errno;
goto err;
}
ras_mc_event_handler, NULL, MC_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "mc_event");
ras_aer_event_handler, NULL, AER_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "aer_event");
#endif
ras_non_standard_event_handler, NULL, NON_STANDARD_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "non_standard_event");
#endif
ras_arm_event_handler, NULL, ARM_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "arm_event");
#endif
/* tell kernel we are listening, so don't printk to console */
(void)open("/sys/kernel/debug/ras/daemon_active", 0);
num_events++;
- } else if (rc != -EINVAL)
+ } else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "extlog_mem_event");
#endif
ras_devlink_event_handler, filter_str, DEVLINK_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"devlink", "devlink_health_report");
#endif
NULL, DISKERROR_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"block", "block_rq_error");
#else
NULL, DISKERROR_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"block", "block_rq_complete");
}
ras_memory_failure_event_handler, NULL, MF_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "memory_failure_event");
#endif
ras_cxl_poison_event_handler, NULL, CXL_POISON_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_poison");
ras_cxl_aer_ue_event_handler, NULL, CXL_AER_UE_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_aer_uncorrectable_error");
ras_cxl_aer_ce_event_handler, NULL, CXL_AER_CE_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_aer_correctable_error");
ras_cxl_overflow_event_handler, NULL, CXL_OVERFLOW_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_overflow");
ras_cxl_generic_event_handler, NULL, CXL_GENERIC_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_generic_event");
ras_cxl_general_media_event_handler, NULL, CXL_GENERAL_MEDIA_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_general_media");
ras_cxl_dram_event_handler, NULL, CXL_DRAM_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "cxl_dram");
ras_cxl_memory_module_event_handler, NULL, CXL_MEMORY_MODULE_EVENT);
if (!rc)
num_events++;
- else if (rc != -EINVAL)
+ else if (rc != EVENT_DISABLED)
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"cxl", "memory_module");
#endif
rc = read_ras_event_all_cpus(data, cpus);
/* Poll doesn't work on this kernel. Fallback to pthread way */
- if (rc == -255) {
+ if (rc == LEGACY_KERNEL) {
if (pthread_mutex_init(&ras->db_lock, NULL) != 0) {
log(SYSLOG, LOG_INFO, "sqlite db lock init has failed\n");
goto err;