#define RING_BUFFER_GET_MMAP_READ_OFFSET _IOR(0xF6, 0x0B, unsigned long)
/* flush the current sub-buffer */
#define RING_BUFFER_FLUSH _IO(0xF6, 0x0C)
+/* Get the current version of the metadata cache (after a get_next). */
+#define RING_BUFFER_GET_METADATA_VERSION _IOR(0xF6, 0x0D, uint64_t)
#ifdef CONFIG_COMPAT
/* Get a snapshot of the current ring buffer producer and consumer positions */
#define RING_BUFFER_COMPAT_GET_MMAP_READ_OFFSET _IOR(0xF6, 0x0B, compat_ulong_t)
/* flush the current sub-buffer */
#define RING_BUFFER_COMPAT_FLUSH RING_BUFFER_FLUSH
+/* Get the current version of the metadata cache (after a get_next). */
+#define RING_BUFFER_COMPAT_GET_METADATA_VERSION RING_BUFFER_GET_METADATA_VERSION
#endif /* CONFIG_COMPAT */
#endif /* _LIB_RING_BUFFER_VFS_H */
static const struct file_operations lttng_event_fops;
static struct file_operations lttng_stream_ring_buffer_file_operations;
+static int put_u64(uint64_t val, unsigned long arg);
+
/*
* Teardown management: opened file descriptors keep a refcount on the module,
* so it can only exit when all file descriptors are closed.
return lttng_session_untrack_pid(session, (int) arg);
case LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS:
return lttng_session_list_tracker_pids(session);
+ case LTTNG_KERNEL_SESSION_METADATA_REGEN:
+ return lttng_session_metadata_regenerate(session);
default:
return -ENOIOCTLCMD;
}
goto err;
break;
}
+ case RING_BUFFER_GET_METADATA_VERSION:
+ {
+ struct lttng_metadata_stream *stream = filp->private_data;
+
+ return put_u64(stream->version, arg);
+ }
default:
break;
}
cmd, arg);
break;
}
+ case RING_BUFFER_GET_METADATA_VERSION:
+ {
+ struct lttng_metadata_stream *stream = filp->private_data;
+
+ return put_u64(stream->version, arg);
+ }
default:
break;
}
#define LTTNG_KERNEL_SESSION_UNTRACK_PID \
_IOR(0xF6, 0x59, int32_t)
#define LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS _IO(0xF6, 0x58)
+#define LTTNG_KERNEL_SESSION_METADATA_REGEN _IO(0xF6, 0x59)
/* Channel FD ioctl */
#define LTTNG_KERNEL_STREAM _IO(0xF6, 0x62)
return ret;
}
+int lttng_session_metadata_regenerate(struct lttng_session *session)
+{
+ int ret = 0;
+ struct lttng_channel *chan;
+ struct lttng_event *event;
+ struct lttng_metadata_cache *cache = session->metadata_cache;
+ struct lttng_metadata_stream *stream;
+
+ mutex_lock(&sessions_mutex);
+ if (!session->active) {
+ ret = -EBUSY;
+ goto end;
+ }
+
+ mutex_lock(&cache->lock);
+ memset(cache->data, 0, cache->cache_alloc);
+ cache->metadata_written = 0;
+ cache->version++;
+ list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list) {
+ stream->metadata_out = 0;
+ stream->metadata_in = 0;
+ }
+ mutex_unlock(&cache->lock);
+
+ session->metadata_dumped = 0;
+ list_for_each_entry(chan, &session->chan, list) {
+ chan->metadata_dumped = 0;
+ }
+
+ list_for_each_entry(event, &session->events, list) {
+ event->metadata_dumped = 0;
+ }
+
+ ret = _lttng_session_metadata_statedump(session);
+
+end:
+ mutex_unlock(&sessions_mutex);
+ return ret;
+}
+
+
+
int lttng_channel_enable(struct lttng_channel *channel)
{
int ret = 0;
if (stream->metadata_in != stream->metadata_out)
goto end;
+ /* Metadata regenerated, change the version. */
+ if (stream->metadata_cache->version != stream->version)
+ stream->version = stream->metadata_cache->version;
+
len = stream->metadata_cache->metadata_written -
stream->metadata_in;
if (!len)
wait_queue_head_t read_wait; /* Reader buffer-level wait queue */
struct list_head list; /* Stream list */
struct lttng_transport *transport;
+ uint64_t version; /* Current version of the metadata cache */
};
struct kref refcount; /* Metadata cache usage */
struct list_head metadata_stream; /* Metadata stream list */
uuid_le uuid; /* Trace session unique ID (copy) */
- struct mutex lock;
+ struct mutex lock; /* Produce/consume lock */
+ uint64_t version; /* Current version of the metadata */
};
void lttng_lock_sessions(void);
int lttng_session_enable(struct lttng_session *session);
int lttng_session_disable(struct lttng_session *session);
void lttng_session_destroy(struct lttng_session *session);
+int lttng_session_metadata_regenerate(struct lttng_session *session);
void metadata_cache_destroy(struct kref *kref);
struct lttng_channel *lttng_channel_create(struct lttng_session *session,