zpd->monitor = monitor;
zpd->prev_read_ts = monitor ? get_zlog_clock() : 0;
zpd->this_read_ts = zpd->prev_read_ts;
+ zpd->read_everything = !monitor;
return 0;
}
*items = item;
}
-static void load_single_device(volatile struct zlogger_block *zb, struct zlog_entry_list **items, uint64_t min_timestamp, uint64_t max_timestamp)
+static void load_single_device(volatile struct zlogger_block *zb, struct zlog_entry_list **items, uint64_t min_timestamp, uint64_t max_timestamp, char *bitmap)
{
/* TODO: document this mumbo jumbo.
* Requires expert earth magic to understand, probably. */
static size_t const BLOCK_COUNT = ZLOGGER_MAP_SIZE / sizeof *zb;
for (size_t i = 0; i < BLOCK_COUNT; i++, zb++) {
+ bool enabled = bitmap[i / CHAR_BIT] & (1 << (i % CHAR_BIT));
+ if (!enabled)
+ continue;
+
if (zb->head.offset > ZLOGGER_DATA_MAX)
continue;
zpd->prev_read_ts = zpd->this_read_ts;
zpd->this_read_ts = now;
+ __attribute__((cleanup(free_ptr))) char *bitmap = malloc(ZLOGGER_BITMAP_SIZE);
+ if (!bitmap)
+ return -ENOMEM;
+
+ int ret = ioctl(fdi->fd, ZLOGGER_IOCTL_COMMAND_GET_BITMAP, bitmap);
+ if (ret < 0)
+ return -errno;
+
+ if (zpd->read_everything) {
+ /* We want to read everything to see all the logs since the startup
+ * and not only all logs since opening. We still call the ioctl so that
+ * the next ioctl will know that we have read the existing logs. */
+ memset(bitmap, ~(char)0, ZLOGGER_BITMAP_SIZE);
+ zpd->read_everything = false;
+ }
+
for (size_t i = 0; i < ZLOGGER_DEVICE_COUNT; ++i) {
volatile void *const addr = mmap(NULL, ZLOGGER_MAP_SIZE, PROT_READ, MAP_SHARED, fdi->fd, ZLOGGER_MAP_SIZE * i);
if (addr == MAP_FAILED)
break;
- load_single_device(addr, &zpd->items, zpd->prev_read_ts, now);
+ load_single_device(addr, &zpd->items, zpd->prev_read_ts, now, bitmap + (ZLOGGER_BLOCK_MAP_COUNT / CHAR_BIT) * i);
munmap((void *) addr, ZLOGGER_MAP_SIZE);
}