[igt-dev] [PATCH i-g-t 2/2] i915/kms_chamelium: Pull chameleond logs for debugging
Stuart Summers
stuart.summers at intel.com
Fri Feb 15 00:40:43 UTC 2019
IGT currently logs some state information when passing commands
to the Chamelium. There is a daemon running on the Chamelium itself,
chameleond, which logs some additional information locally. Add
a new set of libssh calls to extract those logs to be used in CI
debug.
Signed-off-by: Stuart Summers <stuart.summers at intel.com>
---
Dockerfile.debian | 1 +
Dockerfile.fedora | 1 +
lib/igt_chamelium.c | 150 +++++++++++++++++++++++++++++++++++++++++++-
lib/meson.build | 4 ++
meson.build | 4 +-
5 files changed, 158 insertions(+), 2 deletions(-)
diff --git a/Dockerfile.debian b/Dockerfile.debian
index b9c3be394..77928a9ef 100644
--- a/Dockerfile.debian
+++ b/Dockerfile.debian
@@ -18,6 +18,7 @@ RUN apt-get install -y \
libudev-dev \
libgsl-dev \
libasound2-dev \
+ libssh-dev \
libxmlrpc-core-c3-dev \
libjson-c-dev \
libcurl4-openssl-dev \
diff --git a/Dockerfile.fedora b/Dockerfile.fedora
index 08a4bd224..b041bf252 100644
--- a/Dockerfile.fedora
+++ b/Dockerfile.fedora
@@ -16,6 +16,7 @@ RUN dnf install -y gcc \
json-c-devel \
libdrm-devel \
libudev-devel \
+ libssh-devel \
xmlrpc-c-devel \
elfutils-devel \
libunwind-devel \
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 32b859eac..61b563e08 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -30,6 +30,7 @@
#include <errno.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
+#include <libssh/libssh.h>
#include <pthread.h>
#include <glib.h>
#include <pixman.h>
@@ -120,6 +121,8 @@ struct chamelium {
struct chamelium_edid *edids;
struct chamelium_port *ports;
int port_count;
+
+ ssh_session session;
};
static struct chamelium *cleanup_instance;
@@ -256,6 +259,56 @@ static void *chamelium_fsm_mon(void *data)
return NULL;
}
+static void
+chamelium_send_ssh_command(struct chamelium *chamelium, const char *cmd,
+ bool print_result)
+{
+ int rc;
+ ssh_channel channel;
+
+ channel = ssh_channel_new(chamelium->session);
+ if (channel == NULL)
+ return;
+
+ rc = ssh_channel_open_session(channel);
+ if (rc != SSH_OK)
+ goto free;
+
+ rc = ssh_channel_request_exec(channel, cmd);
+ if (rc != SSH_OK)
+ goto free;
+
+ if (print_result) {
+ int nbytes;
+ char buffer[256];
+
+ nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
+ while (nbytes > 0) {
+ igt_debug("%s", buffer);
+ nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
+ }
+ igt_debug("\n");
+ ssh_channel_send_eof(channel);
+ }
+
+ ssh_channel_close(channel);
+
+free:
+ ssh_channel_free(channel);
+}
+
+static void
+chamelium_clear_chameleond(struct chamelium *chamelium)
+{
+ chamelium_send_ssh_command(chamelium, "> /var/log/chameleond", false);
+}
+
+static void
+chamelium_dump_chameleond(struct chamelium *chamelium)
+{
+ chamelium_send_ssh_command(chamelium, "cat /var/log/chameleond", true);
+}
+
static xmlrpc_value *chamelium_rpc(struct chamelium *chamelium,
struct chamelium_port *fsm_port,
const char *method_name,
@@ -298,9 +351,11 @@ static xmlrpc_value *chamelium_rpc(struct chamelium *chamelium,
igt_cleanup_hotplug(monitor_args.mon);
}
+ chamelium_dump_chameleond(chamelium);
igt_assert_f(!chamelium->env.fault_occurred,
"Chamelium RPC call failed: %s\n",
chamelium->env.fault_string);
+ chamelium_clear_chameleond(chamelium);
return res;
}
@@ -1510,7 +1565,7 @@ out:
return ret;
}
-static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd)
+static bool chamelium_get_url(struct chamelium *chamelium)
{
GError *error = NULL;
@@ -1527,6 +1582,11 @@ static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd)
return false;
}
+ return true;
+}
+
+static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd)
+{
return chamelium_read_port_mappings(chamelium, drm_fd);
}
@@ -1551,6 +1611,84 @@ static void chamelium_exit_handler(int sig)
chamelium_deinit(cleanup_instance);
}
+/*
+ * Extract the IP address from the URL in the form:
+ * http://<ip addr>:<port>
+ *
+ * Expect caller to free the resulting string.
+ */
+static char *
+get_ip_addr_from_url(struct chamelium *chamelium)
+{
+ char *tmp;
+ char *ip_addr;
+ char *port;
+
+ tmp = strrchr(chamelium->url, '/');
+ if (!tmp)
+ return NULL;
+ tmp++;
+
+ port = strrchr(chamelium->url, ':');
+ if (!port)
+ return NULL;
+
+ ip_addr = malloc(strlen(tmp));
+ if (!ip_addr)
+ return NULL;
+
+ strcpy(ip_addr, tmp);
+ ip_addr[port - tmp] = '\0';
+
+ return ip_addr;
+}
+
+static int
+chamelium_ssh_init(struct chamelium *chamelium)
+{
+ int rc;
+ char *ip_addr = get_ip_addr_from_url(chamelium);
+ if (!ip_addr)
+ return false;
+
+ chamelium->session = ssh_new();
+ if (chamelium->session == NULL) {
+ free(ip_addr);
+ return false;
+ }
+
+ ssh_options_set(chamelium->session, SSH_OPTIONS_HOST, ip_addr);
+ ssh_options_set(chamelium->session, SSH_OPTIONS_USER, "root");
+
+ rc = ssh_connect(chamelium->session);
+ if (rc != SSH_OK)
+ goto free;
+
+ /* Currently assuming no password is set */
+ rc = ssh_userauth_none(chamelium->session, NULL);
+ if (rc != SSH_AUTH_SUCCESS)
+ goto disconnect;
+
+ free(ip_addr);
+
+ return true;
+
+disconnect:
+ ssh_disconnect(chamelium->session);
+free:
+ ssh_free(chamelium->session);
+ free(ip_addr);
+
+ return false;
+}
+
+static void
+chamelium_ssh_deinit(struct chamelium *chamelium)
+{
+ ssh_disconnect(chamelium->session);
+ ssh_free(chamelium->session);
+}
+
/**
* chamelium_init:
* @chamelium: The Chamelium instance to use
@@ -1592,6 +1730,14 @@ struct chamelium *chamelium_init(int drm_fd)
goto error;
}
+ if (!chamelium_get_url(chamelium))
+ goto error;
+
+ if (!chamelium_ssh_init(chamelium))
+ goto error;
+
+ chamelium_clear_chameleond(chamelium);
+
if (!chamelium_read_config(chamelium, drm_fd))
goto error;
@@ -1636,6 +1782,8 @@ void chamelium_deinit(struct chamelium *chamelium)
free(pos);
}
+ chamelium_ssh_deinit(chamelium);
+
xmlrpc_client_destroy(chamelium->client);
xmlrpc_env_clean(&chamelium->env);
diff --git a/lib/meson.build b/lib/meson.build
index dd36f8180..40d1cb65e 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -97,6 +97,10 @@ if alsa.found()
lib_sources += 'igt_alsa.c'
endif
+if libssh.found()
+ lib_deps += libssh
+endif
+
if chamelium.found()
lib_deps += chamelium
lib_sources += 'igt_chamelium.c'
diff --git a/meson.build b/meson.build
index 356a54142..3b4e40ce5 100644
--- a/meson.build
+++ b/meson.build
@@ -166,6 +166,8 @@ cairo = dependency('cairo', version : '>1.12.0', required : true)
libudev = dependency('libudev', required : true)
glib = dependency('glib-2.0', required : true)
+libssh = dependency('libssh', required : true)
+
gsl = null_dep
alsa = null_dep
if _build_audio or _build_chamelium
@@ -205,7 +207,7 @@ endif
chamelium = null_dep
chameliuminfo = 'No'
-if _build_chamelium and gsl.found() and xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found()
+if _build_chamelium and gsl.found() and libssh.found() and xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found()
chamelium = declare_dependency(dependencies : [ xmlrpc,
xmlrpc_util, xmlrpc_client])
config.set('HAVE_CHAMELIUM', 1)
--
2.20.1
More information about the igt-dev
mailing list