summaryrefslogtreecommitdiff
path: root/emulator/vhci.c
diff options
context:
space:
mode:
authorManish Mandlik <mmandlik@google.com>2023-03-29 23:08:02 -0700
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-03-30 10:46:21 -0700
commit8bd2f29617743a5587ca9679957c2e4bf3b78aa9 (patch)
tree21a0163b0b090d2f9c052c7b3f6e6ae90db2e507 /emulator/vhci.c
parent2b022fa5297a56875f06c2b5612258cd99dcbe74 (diff)
downloadbluez-8bd2f29617743a5587ca9679957c2e4bf3b78aa9.tar.gz
vhci: Add support to trigger devcoredump and read the dump file
Add vhci support to trigger the hci devcoredump by writing to force_devcoredump debugfs entry and read the generated devcoredump file.
Diffstat (limited to 'emulator/vhci.c')
-rw-r--r--emulator/vhci.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/emulator/vhci.c b/emulator/vhci.c
index a12b11e0f..ecf1db3c7 100644
--- a/emulator/vhci.c
+++ b/emulator/vhci.c
@@ -22,6 +22,7 @@
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
+#include <dirent.h>
#include "lib/bluetooth.h"
#include "lib/hci.h"
@@ -32,6 +33,7 @@
#include "vhci.h"
#define DEBUGFS_PATH "/sys/kernel/debug/bluetooth"
+#define DEVCORE_PATH "/sys/class/devcoredump"
struct vhci {
enum btdev_type type;
@@ -184,7 +186,7 @@ struct btdev *vhci_get_btdev(struct vhci *vhci)
return vhci->btdev;
}
-static int vhci_debugfs_write(struct vhci *vhci, char *option, void *data,
+static int vhci_debugfs_write(struct vhci *vhci, char *option, const void *data,
size_t len)
{
char path[64];
@@ -267,3 +269,60 @@ int vhci_set_force_static_address(struct vhci *vhci, bool enable)
return vhci_debugfs_write(vhci, "force_static_address", &val,
sizeof(val));
}
+
+int vhci_force_devcd(struct vhci *vhci, const void *data, size_t len)
+{
+ return vhci_debugfs_write(vhci, "force_devcoredump", data, len);
+}
+
+int vhci_read_devcd(struct vhci *vhci, void *buf, size_t size)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char filename[PATH_MAX];
+ int fd;
+ int ret;
+
+ dir = opendir(DEVCORE_PATH);
+ if (dir == NULL)
+ return -errno;
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strstr(entry->d_name, "devcd"))
+ break;
+ }
+
+ if (entry == NULL) {
+ ret = -ENOENT;
+ goto close_dir;
+ }
+
+ sprintf(filename, DEVCORE_PATH "/%s/data", entry->d_name);
+ fd = open(filename, O_RDWR);
+ if (fd < 0) {
+ ret = -errno;
+ goto close_dir;
+ }
+
+ ret = read(fd, buf, size);
+ if (ret < 0) {
+ ret = -errno;
+ goto close_file;
+ }
+
+ /* Once the devcoredump is read, write anything to it to mark it for
+ * cleanup.
+ */
+ if (write(fd, "0", 1) < 0) {
+ ret = -errno;
+ goto close_file;
+ }
+
+close_file:
+ close(fd);
+
+close_dir:
+ closedir(dir);
+
+ return ret;
+}