+
+ lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+ memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
+
+ lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+ sizeof(lsm.session.name));
+ lsm.u.enable.exclusion_count = exclusion_count;
+ lsm.u.enable.bytecode_len = 0;
+
+ /*
+ * For the JUL domain, a filter is enforced except for the enable all
+ * event. This is done to avoid having the event in all sessions thus
+ * filtering by logger name.
+ */
+ if (exclusion_count == 0 && filter_expression == NULL &&
+ handle->domain.type != LTTNG_DOMAIN_JUL) {
+ goto ask_sessiond;
+ }
+
+ /*
+ * We have either a filter or some exclusions, so we need to set up
+ * a variable-length memory block from where to send the data
+ */
+
+ /* Parse filter expression */
+ if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL) {
+ if (handle->domain.type == LTTNG_DOMAIN_JUL) {
+ char *jul_filter;
+
+ /* Setup JUL filter if needed. */
+ jul_filter = set_jul_filter(filter_expression, ev);
+ if (!jul_filter) {
+ if (!filter_expression) {
+ /* No JUL and no filter, just skip everything below. */
+ goto ask_sessiond;
+ }
+ } else {
+ /*
+ * With a JUL filter, the original filter has been added to it
+ * thus replace the filter expression.
+ */
+ filter_expression = jul_filter;
+ free_filter_expression = 1;
+ }
+ }
+
+ ret = generate_filter(filter_expression, &lsm, &ctx);
+ if (ret) {
+ goto filter_error;
+ }
+ }
+
+ varlen_data = zmalloc(lsm.u.enable.bytecode_len
+ + lsm.u.enable.expression_len
+ + LTTNG_SYMBOL_NAME_LEN * exclusion_count);
+ if (!varlen_data) {
+ ret = -LTTNG_ERR_EXCLUSION_NOMEM;
+ goto filter_error;
+ }
+
+ /* Put exclusion names first in the data */
+ while (exclusion_count--) {
+ strncpy(varlen_data + LTTNG_SYMBOL_NAME_LEN * exclusion_count,
+ *(exclusion_list + exclusion_count), LTTNG_SYMBOL_NAME_LEN);
+ }
+ /* Add filter expression next */
+ if (lsm.u.enable.expression_len != 0) {
+ memcpy(varlen_data
+ + LTTNG_SYMBOL_NAME_LEN * lsm.u.enable.exclusion_count,
+ filter_expression,
+ lsm.u.enable.expression_len);
+ }
+ /* Add filter bytecode next */
+ if (ctx && lsm.u.enable.bytecode_len != 0) {
+ memcpy(varlen_data
+ + LTTNG_SYMBOL_NAME_LEN * lsm.u.enable.exclusion_count
+ + lsm.u.enable.expression_len,
+ &ctx->bytecode->b,
+ lsm.u.enable.bytecode_len);
+ }
+
+ ret = lttng_ctl_ask_sessiond_varlen(&lsm, varlen_data,
+ (LTTNG_SYMBOL_NAME_LEN * lsm.u.enable.exclusion_count) +
+ lsm.u.enable.bytecode_len + lsm.u.enable.expression_len, NULL);
+ free(varlen_data);
+
+filter_error:
+ if (filter_expression) {
+ filter_bytecode_free(ctx);
+ filter_ir_free(ctx);
+ filter_parser_ctx_free(ctx);
+ if (free_filter_expression) {
+ /*
+ * The filter expression has been replaced and must be
+ * freed as it is not the original filter expression
+ * received as a parameter.
+ */
+ free(filter_expression);
+ }
+ }
+error:
+ /*
+ * Return directly to the caller and don't ask the sessiond since something
+ * went wrong in the parsing of data above.
+ */
+ return ret;
+
+ask_sessiond:
+ ret = lttng_ctl_ask_sessiond(&lsm, NULL);