LTTNG_ERR_ROTATION_PENDING_RELAY_FAIL_CONSUMER = 144, /* Rotation pending check (relay) failure on consumer */
LTTNG_ERR_MKDIR_FAIL_CONSUMER = 145, /* mkdir failure on consumer */
LTTNG_ERR_CHAN_NOT_FOUND = 146, /* Channel not found */
-
+ LTTNG_ERR_SNAPSHOT_UNSUPPORTED = 147, /* Session configuration does not allow the use of snapshots */
/* MUST be last element */
LTTNG_ERR_NR, /* Last element */
attr->attr.overwrite = !!ksession->snapshot_mode;
}
- /* Enforce mmap output for snapshot sessions. */
- if (ksession->snapshot_mode) {
- attr->attr.output = LTTNG_EVENT_MMAP;
- }
-
/* Validate common channel properties. */
if (channel_validate(attr) < 0) {
ret = LTTNG_ERR_INVALID;
kchan = trace_kernel_get_channel_by_name(attr->name,
session->kernel_session);
if (kchan == NULL) {
+ if (session->snapshot.nb_output > 0 ||
+ session->snapshot_mode) {
+ /* Enforce mmap output for snapshot sessions. */
+ attr->attr.output = LTTNG_EVENT_MMAP;
+ }
ret = channel_kernel_create(session->kernel_session, attr, wpipe);
if (attr->name[0] != '\0') {
session->kernel_session->has_non_default_channel = 1;
goto error;
}
+ if (ret == LTTNG_OK && attr->attr.output != LTTNG_EVENT_MMAP) {
+ session->has_non_mmap_channel = true;
+ }
error:
rcu_read_unlock();
end:
goto error;
}
+ if (session->has_non_mmap_channel) {
+ ret = LTTNG_ERR_SNAPSHOT_UNSUPPORTED;
+ goto error;
+ }
+
/* Only one output is allowed until we have the "tee" feature. */
if (session->snapshot.nb_output == 1) {
ret = LTTNG_ERR_SNAPSHOT_OUTPUT_EXIST;
* creation defaults.
*/
unsigned int snapshot_mode;
+ /*
+ * A session that has channels that don't use 'mmap' output can't be
+ * used to capture snapshots. This is set to true whenever a
+ * 'splice' kernel channel is enabled.
+ */
+ bool has_non_mmap_channel;
/*
* Timer set when the session is created for live reading.
*/
int ret;
if (argc < 2 && (!opt_data_url || !opt_ctrl_url)) {
+ ERR("An output destination must be specified to add a snapshot output.");
ret = CMD_ERROR;
goto end;
}
ret = add_output(argv[1]);
+ if (ret < 0) {
+ switch (-ret) {
+ case LTTNG_ERR_SNAPSHOT_UNSUPPORTED:
+ ERR("Session \"%s\" contains a channel that is incompatible with the snapshot functionality.\nMake sure all channels are configured in 'mmap' output mode.",
+ current_session_name);
+ ret = CMD_ERROR;
+ break;
+ default:
+ break;
+ }
+ }
end:
return ret;
result = cmd->func(argc, argv);
if (result) {
- switch (-result) {
- case LTTNG_ERR_SNAPSHOT_NODATA:
+ switch (result) {
+ case CMD_ERROR:
+ case CMD_UNDEFINED:
+ case CMD_FATAL:
+ case CMD_WARNING:
+ case CMD_UNSUPPORTED:
+ /*
+ * Sub-commands mix lttng_error_codes
+ * and cmd_error_codes. This should be
+ * cleaned-up, but in the meantime this
+ * hack works since the values of the
+ * two enums do not intersect.
+ */
+ cmd_ret = result;
+ break;
+ case -LTTNG_ERR_SNAPSHOT_NODATA:
WARN("%s", lttng_strerror(result));
/* A warning is fine since the user has no control on
[ ERROR_INDEX(LTTNG_ERR_ROTATION_PENDING_RELAY_FAIL_CONSUMER) ] = "Rotation pending check (relay) failure on consumer",
[ ERROR_INDEX(LTTNG_ERR_MKDIR_FAIL_CONSUMER) ] = "mkdir failure on consumer",
[ ERROR_INDEX(LTTNG_ERR_CHAN_NOT_FOUND) ] = "Channel not found",
+ [ ERROR_INDEX(LTTNG_ERR_SNAPSHOT_UNSUPPORTED) ] = "Session configuration does not allow the use of snapshots",
/* Last element */
[ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"