+
+static struct lttng_rate_policy *parse_rate_policy(const char *policy_str)
+{
+ int num_token;
+ char **tokens = NULL;
+ struct lttng_rate_policy *policy = NULL;
+ enum lttng_rate_policy_type policy_type;
+ unsigned long long value;
+ char *policy_type_str;
+ char *policy_value_str;
+
+ assert(policy_str);
+
+ /*
+ * rate policy fields are separated by ':'.
+ */
+ tokens = strutils_split(policy_str, ':', 1);
+ num_token = strutils_array_of_strings_len(tokens);
+
+ /*
+ * Early sanity check that the number of parameter is exactly 2.
+ * i.e : type:value
+ */
+ if (num_token != 2) {
+ ERR("Rate policy format is invalid.");
+ goto end;
+ }
+
+ policy_type_str = tokens[0];
+ policy_value_str = tokens[1];
+
+ /* Parse the type. */
+ if (strcmp(policy_type_str, "once-after") == 0) {
+ policy_type = LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N;
+ } else if (strcmp(policy_type_str, "every") == 0) {
+ policy_type = LTTNG_RATE_POLICY_TYPE_EVERY_N;
+ } else {
+ ERR("Rate policy type `%s` unknown.", policy_type_str);
+ goto end;
+ }
+
+ /* Parse the value. */
+ if (utils_parse_unsigned_long_long(policy_value_str, &value) != 0) {
+ ERR("Failed to parse rate policy value `%s` as an integer.",
+ policy_value_str);
+ goto end;
+ }
+
+ if (value == 0) {
+ ERR("Rate policy value `%s` must be > 0.", policy_value_str);
+ goto end;
+ }
+
+ switch (policy_type) {
+ case LTTNG_RATE_POLICY_TYPE_EVERY_N:
+ policy = lttng_rate_policy_every_n_create(value);
+ break;
+ case LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N:
+ policy = lttng_rate_policy_once_after_n_create(value);
+ break;
+ default:
+ abort();
+ }
+
+ if (policy == NULL) {
+ ERR("Failed to create rate policy `%s`.", policy_str);
+ }
+
+end:
+ strutils_free_null_terminated_array_of_strings(tokens);
+ return policy;
+}
+