lib: compile liblttng-ctl as C++
[lttng-tools.git] / src / lib / lttng-ctl / snapshot.cpp
diff --git a/src/lib/lttng-ctl/snapshot.cpp b/src/lib/lttng-ctl/snapshot.cpp
new file mode 100644 (file)
index 0000000..543861d
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#define _LGPL_SOURCE
+#include <string.h>
+
+#include <common/sessiond-comm/sessiond-comm.h>
+#include <lttng/lttng-error.h>
+#include <lttng/snapshot.h>
+#include <lttng/snapshot-internal.h>
+
+#include "lttng-ctl-helper.h"
+
+/*
+ * Add an output object to a session identified by name.
+ *
+ * Return 0 on success or else a negative LTTNG_ERR code.
+ */
+int lttng_snapshot_add_output(const char *session_name,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+       struct lttcomm_lttng_output_id *reply;
+
+       if (!session_name || !output) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_SNAPSHOT_ADD_OUTPUT;
+
+       ret = lttng_strncpy(lsm.session.name, session_name,
+                       sizeof(lsm.session.name));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memcpy(&lsm.u.snapshot_output.output, output,
+                       sizeof(lsm.u.snapshot_output.output));
+
+       ret = lttng_ctl_ask_sessiond(&lsm, (void **) &reply);
+       if (ret < 0) {
+               goto end;
+       }
+
+       output->id = reply->id;
+       free(reply);
+       ret = 0;
+end:
+       return ret;
+}
+
+/*
+ * Delete an output object to a session identified by name.
+ *
+ * Return 0 on success or else a negative LTTNG_ERR code.
+ */
+int lttng_snapshot_del_output(const char *session_name,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+
+       if (!session_name || !output) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_SNAPSHOT_DEL_OUTPUT;
+
+       ret = lttng_strncpy(lsm.session.name, session_name,
+                           sizeof(lsm.session.name));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memcpy(&lsm.u.snapshot_output.output, output,
+                       sizeof(lsm.u.snapshot_output.output));
+
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+end:
+       return ret;
+}
+
+/*
+ * List all snapshot output(s) of a session identified by name. The output list
+ * object is populated and can be iterated over with the get_next call below.
+ *
+ * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
+ * is untouched.
+ */
+int lttng_snapshot_list_output(const char *session_name,
+               struct lttng_snapshot_output_list **list)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+       struct lttng_snapshot_output_list *new_list = NULL;
+
+       if (!session_name || !list) {
+               ret = -LTTNG_ERR_INVALID;
+               goto error;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_SNAPSHOT_LIST_OUTPUT;
+
+       ret = lttng_strncpy(lsm.session.name, session_name,
+                           sizeof(lsm.session.name));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto error;
+       }
+
+       new_list = (lttng_snapshot_output_list *) zmalloc(sizeof(*new_list));
+       if (!new_list) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto error;
+       }
+
+       ret = lttng_ctl_ask_sessiond(&lsm, (void **) &new_list->array);
+       if (ret < 0) {
+               goto free_error;
+       }
+
+       new_list->count = ret / sizeof(struct lttng_snapshot_output);
+       *list = new_list;
+       return 0;
+
+free_error:
+       free(new_list);
+error:
+       return ret;
+}
+
+/*
+ * Return the next available snapshot output object in the given list. A list
+ * output command MUST have been done before.
+ *
+ * Return the next object on success or else NULL indicating the end of the
+ * list.
+ */
+struct lttng_snapshot_output *lttng_snapshot_output_list_get_next(
+               struct lttng_snapshot_output_list *list)
+{
+       struct lttng_snapshot_output *output = NULL;
+
+       if (!list) {
+               goto error;
+       }
+
+       /* We've reached the end. */
+       if (list->index == list->count) {
+               goto end;
+       }
+
+       output = &list->array[list->index];
+       list->index++;
+
+end:
+error:
+       return output;
+}
+
+/*
+ * Free an output list object.
+ */
+void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list *list)
+{
+       if (!list) {
+               return;
+       }
+
+       free(list->array);
+       free(list);
+}
+
+/*
+ * Snapshot a trace for the given session.
+ *
+ * The output object can be NULL but an add output MUST be done prior to this
+ * call. If it's not NULL, it will be used to snapshot a trace.
+ *
+ * The wait parameter is ignored for now. The snapshot record command will
+ * ALWAYS wait for the snapshot to complete before returning meaning the
+ * snapshot has been written on disk or streamed over the network to a relayd.
+ *
+ * Return 0 on success or else a negative LTTNG_ERR value.
+ */
+int lttng_snapshot_record(const char *session_name,
+               struct lttng_snapshot_output *output, int wait)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+
+       if (!session_name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_SNAPSHOT_RECORD;
+
+       ret = lttng_strncpy(lsm.session.name, session_name,
+                       sizeof(lsm.session.name));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       /*
+        * Not having an output object will use the default one of the session that
+        * would need to be set by a call to add output prior to calling snapshot
+        * record.
+        */
+       if (output) {
+               memcpy(&lsm.u.snapshot_record.output, output,
+                               sizeof(lsm.u.snapshot_record.output));
+       }
+
+       /* The wait param is ignored. */
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+end:
+       return ret;
+}
+
+/*
+ * Return an newly allocated snapshot output object or NULL on error.
+ */
+struct lttng_snapshot_output *lttng_snapshot_output_create(void)
+{
+       struct lttng_snapshot_output *output;
+
+       output = (lttng_snapshot_output *) zmalloc(sizeof(struct lttng_snapshot_output));
+       if (!output) {
+               goto error;
+       }
+
+       output->max_size = (uint64_t) -1ULL;
+
+error:
+       return output;
+}
+
+/*
+ * Free a given snapshot output object.
+ */
+void lttng_snapshot_output_destroy(struct lttng_snapshot_output *obj)
+{
+       if (obj) {
+               free(obj);
+       }
+}
+
+/*
+ * Getter family functions of snapshot output.
+ */
+
+uint32_t lttng_snapshot_output_get_id(const struct lttng_snapshot_output *output)
+{
+       return output->id;
+}
+
+const char *lttng_snapshot_output_get_name(
+               const struct lttng_snapshot_output *output)
+{
+       return output->name;
+}
+
+const char *lttng_snapshot_output_get_data_url(const struct lttng_snapshot_output *output)
+{
+       return output->data_url;
+}
+
+const char *lttng_snapshot_output_get_ctrl_url(const struct lttng_snapshot_output *output)
+{
+       return output->ctrl_url;
+}
+
+uint64_t lttng_snapshot_output_get_maxsize(
+               const struct lttng_snapshot_output *output)
+{
+       return output->max_size;
+}
+
+/*
+ * Setter family functions for snapshot output.
+ */
+
+int lttng_snapshot_output_set_id(uint32_t id,
+               struct lttng_snapshot_output *output)
+{
+       if (!output || id == 0) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       output->id = id;
+       return 0;
+}
+
+int lttng_snapshot_output_set_size(uint64_t size,
+               struct lttng_snapshot_output *output)
+{
+       if (!output) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       output->max_size = size;
+       return 0;
+}
+
+int lttng_snapshot_output_set_name(const char *name,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+
+       if (!output || !name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->name, name, sizeof(output->name));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+int lttng_snapshot_output_set_ctrl_url(const char *url,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+
+       if (!output || !url) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->ctrl_url, url, sizeof(output->ctrl_url));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+int lttng_snapshot_output_set_data_url(const char *url,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+
+       if (!output || !url) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->data_url, url, sizeof(output->data_url));
+       if (ret) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+int lttng_snapshot_output_set_local_path(const char *path,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+       struct lttng_uri *uris = NULL;
+       ssize_t num_uris;
+
+       if (!path || !output) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       num_uris = uri_parse_str_urls(path, NULL, &uris);
+       if (num_uris != 1) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (uris[0].dtype != LTTNG_DST_PATH) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->ctrl_url, path, sizeof(output->ctrl_url));
+       if (ret != 0) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       free(uris);
+       return ret;
+}
+
+int lttng_snapshot_output_set_network_url(const char *url,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+       struct lttng_uri *uris = NULL;
+       ssize_t num_uris;
+
+       if (!url || !output) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       num_uris = uri_parse_str_urls(url, NULL, &uris);
+       if (num_uris != 2) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (uris[0].dtype != LTTNG_DST_IPV4 &&
+                       uris[0].dtype != LTTNG_DST_IPV6) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (uris[1].dtype != LTTNG_DST_IPV4 &&
+                       uris[1].dtype != LTTNG_DST_IPV6) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->ctrl_url, url, sizeof(output->ctrl_url));
+       if (ret != 0) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       free(uris);
+       return ret;
+}
+
+int lttng_snapshot_output_set_network_urls(
+               const char *ctrl_url, const char *data_url,
+               struct lttng_snapshot_output *output)
+{
+       int ret;
+       struct lttng_uri *uris = NULL;
+       ssize_t num_uris;
+
+       if (!ctrl_url || !data_url || !output) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       num_uris = uri_parse_str_urls(ctrl_url, data_url, &uris);
+       if (num_uris != 2) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (uris[0].dtype != LTTNG_DST_IPV4 &&
+                       uris[0].dtype != LTTNG_DST_IPV6) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (uris[1].dtype != LTTNG_DST_IPV4 &&
+                       uris[1].dtype != LTTNG_DST_IPV6) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->ctrl_url, ctrl_url, sizeof(output->ctrl_url));
+       if (ret != 0) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ret = lttng_strncpy(output->data_url, data_url, sizeof(output->data_url));
+       if (ret != 0) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+end:
+       free(uris);
+       return ret;
+}
This page took 0.027196 seconds and 4 git commands to generate.