return ret;
}
+static
+int save_session_rotation_schedule(struct config_writer *writer,
+ enum lttng_rotation_schedule_type type, uint64_t value)
+{
+ int ret = 0;
+ const char *element_name;
+ const char *value_name;
+
+ switch (type) {
+ case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
+ element_name = config_element_rotation_schedule_periodic;
+ value_name = config_element_rotation_schedule_periodic_time_us;
+ break;
+ case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
+ element_name = config_element_rotation_schedule_size_threshold;
+ value_name = config_element_rotation_schedule_size_threshold_bytes;
+ break;
+ default:
+ ret = -1;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer, element_name);
+ if (ret) {
+ goto end;
+ }
+
+ ret = config_writer_write_element_unsigned_int(writer,
+ value_name, value);
+ if (ret) {
+ goto end;
+ }
+
+ /* Close schedule descriptor element. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ goto end;
+ }
+end:
+ return ret;
+}
+
+static
+int save_session_rotation_schedules(struct config_writer *writer,
+ struct ltt_session *session)
+{
+ int ret;
+
+ ret = config_writer_open_element(writer,
+ config_element_rotation_schedules);
+ if (session->rotate_timer_period) {
+ ret = save_session_rotation_schedule(writer,
+ LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC,
+ session->rotate_timer_period);
+ if (ret) {
+ goto close_schedules;
+ }
+ }
+ if (session->rotate_size) {
+ ret = save_session_rotation_schedule(writer,
+ LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD,
+ session->rotate_size);
+ if (ret) {
+ goto close_schedules;
+ }
+ }
+
+close_schedules:
+ /* Close rotation schedules element. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ goto end;
+ }
+end:
+ return ret;
+}
+
/*
* Save the given session.
*
goto end;
}
}
- if (session->rotate_timer_period) {
- ret = config_writer_write_element_unsigned_int(writer,
- config_element_rotation_timer_interval,
- session->rotate_timer_period);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
- }
-
- if (session->rotate_size) {
- ret = config_writer_write_element_unsigned_int(writer,
- config_element_rotation_size,
- session->rotate_size);
+ if (session->rotate_timer_period || session->rotate_size) {
+ ret = save_session_rotation_schedules(writer,
+ session);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
const char * const config_element_targets = "targets";
const char * const config_element_target_pid = "pid_target";
-LTTNG_HIDDEN const char * const config_element_rotation_timer_interval = "rotation_schedule_timer_period";
-LTTNG_HIDDEN const char * const config_element_rotation_size = "rotation_schedule_size";
-LTTNG_HIDDEN const char * const config_element_rotation_schedule = "rotation_schedule";
+LTTNG_HIDDEN const char * const config_element_rotation_schedules = "rotation_schedules";
+LTTNG_HIDDEN const char * const config_element_rotation_schedule_periodic = "periodic";
+LTTNG_HIDDEN const char * const config_element_rotation_schedule_periodic_time_us = "time_us";
+LTTNG_HIDDEN const char * const config_element_rotation_schedule_size_threshold = "size_threshold";
+LTTNG_HIDDEN const char * const config_element_rotation_schedule_size_threshold_bytes = "bytes";
const char * const config_domain_type_kernel = "KERNEL";
const char * const config_domain_type_ust = "UST";
status = lttng_session_add_rotation_schedule(name, periodic);
switch (status) {
case LTTNG_ROTATION_STATUS_OK:
- ret = LTTNG_OK;
+ ret = 0;
break;
case LTTNG_ROTATION_STATUS_SCHEDULE_ALREADY_SET:
case LTTNG_ROTATION_STATUS_INVALID:
status = lttng_session_add_rotation_schedule(name, size);
switch (status) {
case LTTNG_ROTATION_STATUS_OK:
- ret = LTTNG_OK;
+ ret = 0;
break;
case LTTNG_ROTATION_STATUS_SCHEDULE_ALREADY_SET:
case LTTNG_ROTATION_STATUS_INVALID:
return ret;
}
+static
+int process_session_rotation_schedules_node(
+ xmlNodePtr schedules_node,
+ uint64_t *rotation_timer_interval,
+ uint64_t *rotation_size)
+{
+ int ret = 0;
+ xmlNodePtr child;
+
+ for (child = xmlFirstElementChild(schedules_node);
+ child;
+ child = xmlNextElementSibling(child)) {
+ if (!strcmp((const char *) child->name,
+ config_element_rotation_schedule_periodic)) {
+ xmlChar *content;
+ xmlNodePtr time_us_node;
+
+ /* periodic rotation schedule */
+ time_us_node = xmlFirstElementChild(child);
+ if (!time_us_node ||
+ strcmp((const char *) time_us_node->name,
+ config_element_rotation_schedule_periodic_time_us)) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ /* time_us child */
+ content = xmlNodeGetContent(time_us_node);
+ if (!content) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ ret = parse_uint(content, rotation_timer_interval);
+ free(content);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ } else if (!strcmp((const char *) child->name,
+ config_element_rotation_schedule_size_threshold)) {
+ xmlChar *content;
+ xmlNodePtr bytes_node;
+
+ /* size_threshold rotation schedule */
+ bytes_node = xmlFirstElementChild(child);
+ if (!bytes_node ||
+ strcmp((const char *) bytes_node->name,
+ config_element_rotation_schedule_size_threshold_bytes)) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
+ /* bytes child */
+ content = xmlNodeGetContent(bytes_node);
+ if (!content) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ ret = parse_uint(content, rotation_size);
+ free(content);
+ if (ret) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ }
+ }
+
+end:
+ return ret;
+}
+
static
int process_session_node(xmlNodePtr session_node, const char *session_name,
int overwrite,
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
goto error;
}
- }
- if (!strcmp((const char *) attributes_child->name,
- config_element_rotation_timer_interval)) {
- /* rotation_timer_interval */
- xmlChar *timer_interval_content =
- xmlNodeGetContent(attributes_child);
- if (!timer_interval_content) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
-
- ret = parse_uint(timer_interval_content, &rotation_timer_interval);
- free(timer_interval_content);
+ } else if (!strcmp((const char *) attributes_child->name,
+ config_element_rotation_schedules)) {
+ ret = process_session_rotation_schedules_node(
+ attributes_child,
+ &rotation_timer_interval,
+ &rotation_size);
if (ret) {
ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
goto error;
}
- }
- if (!strcmp((const char *) attributes_child->name,
- config_element_rotation_size)) {
- /* rotation_size */
- xmlChar *rotation_size_content =
- xmlNodeGetContent(attributes_child);
- if (!rotation_size_content) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
- ret = parse_uint(rotation_size_content, &rotation_size);
- free(rotation_size_content);
- if (ret) {
- ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto error;
- }
}
}
}
</xs:all>
</xs:complexType>
+<xs:complexType name="periodic_rotation_schedule_type">
+ <xs:all>
+ <xs:element name="time_us" type="uint64_type" minOccurs="0" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="size_threshold_rotation_schedule_type">
+ <xs:all>
+ <xs:element name="bytes" type="uint64_type" minOccurs="0" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="rotation_schedule_type">
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="periodic" type="periodic_rotation_schedule_type" maxOccurs="unbounded" />
+ <xs:element name="size_threshold" type="size_threshold_rotation_schedule_type" maxOccurs="unbounded" />
+ </xs:choice>
+ </xs:sequence>
+</xs:complexType>
+
<xs:complexType name="session_attributes_type">
<xs:all>
<xs:element name="snapshot_mode" type="xs:boolean" minOccurs="0"/>
<xs:element name="live_timer_interval" type="uint32_type" minOccurs="0"/> <!-- usec -->
- <xs:element name="rotation_schedule_timer_period" type="uint64_type" minOccurs="0"/> <!-- usec -->
- <xs:element name="rotation_schedule_size" type="uint64_type" minOccurs="0"/> <!-- bytes -->
+ <xs:element name="rotation_schedules" type="rotation_schedule_type" minOccurs="0" />
</xs:all>
</xs:complexType>