EXTRA_CFLAGS := $(extra_cflags)
obj-m := swap_driver.o
-swap_driver-y := device_driver.o ec.o legacy.o module.o probes.o \
+swap_driver-y := error_storage.o device_driver.o ec.o legacy.o module.o probes.o \
probes_manager.o storage.o us_proc_inst.o java_inst.o \
sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_procs.o
result = -1;
break;
}
+ if (has_last_error() == -1) {
+ result = -1;
+ }
break;
}
DPRINTF("Get Size of Predefined User Space Probes");
break;
}
-
+ case EC_IOCTL_GET_LAST_ERROR:
+ {
+ result = get_last_error((void*)arg);
+ break;
+ }
default:
EPRINTF ("Unknown driver command = %u", cmd);
result = -EINVAL;
EC_IOCTL_SET_PID,
+ // error consist of wrong path to apps or libs
+ EC_IOCTL_GET_LAST_ERROR,
} EC_IOCTL_CMD;
typedef struct
--- /dev/null
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+#include "error_storage.h"
+
+static int create_errno_buffer(void);
+static void delete_errno_buffer(void);
+static unsigned int get_max_error_buffer_size(void);
+
+static struct errno_struct
+{
+ unsigned int size;
+ char *buffer;
+};
+
+static struct errno_struct *last_error = NULL;
+
+static int create_errno_buffer(void)
+{
+ struct errno_struct *error = NULL;
+ if (last_error != NULL){
+ return -1;
+ }
+ error = (struct errno_struct*)vmalloc(sizeof(struct errno_struct));
+ if (error == NULL){
+ return -1;
+ }
+ error->buffer = vmalloc(MAX_ERROR_BUF_PATH);
+ if (error->buffer == NULL)
+ {
+ vfree(error);
+ return -1;
+ }
+ error->buffer[0] = '\0';
+ error->size = 0;
+ last_error = (struct errno_struct*) error;
+
+ return 0;
+}
+
+static unsigned int get_max_error_buffer_size(void)
+{
+ return (unsigned int)MAX_ERROR_BUF_PATH;
+}
+
+int update_errno_buffer(const char *buffer)
+{
+ unsigned int size;
+
+ if (last_error == NULL)
+ {
+ if (create_errno_buffer() != 0)
+ return -1;
+ }
+
+ size = strlen(buffer);
+
+ if (last_error->size + size + 1 >= get_max_error_buffer_size()) {
+ return -1;
+ }
+
+ strncat((char*)(last_error->buffer), buffer, size);
+
+ last_error->size += size + 1;
+ last_error->buffer[last_error->size - 1] = ',';
+ last_error->buffer[last_error->size] = '\0';
+
+ return 0;
+}
+
+static void delete_errno_buffer(void)
+{
+ if (last_error == NULL)
+ return;
+
+ vfree((char*)last_error->buffer);
+ vfree(last_error);
+
+ last_error = NULL;
+
+ return;
+}
+
+int get_last_error(void* u_addr)
+{
+ int result;
+
+ if (last_error == NULL)
+ return -1;
+
+ result = copy_to_user ((void*)u_addr, (void*)(last_error->buffer), last_error->size + 1);
+ if (result) {
+ result = -EFAULT;
+ }
+
+ delete_errno_buffer();
+
+ return result;
+}
+
+int has_last_error()
+{
+ if(last_error == NULL)
+ return 0;
+ return -1;
+}
--- /dev/null
+#define MAX_ERROR_BUF_PATH 256
+
+// copy error buffer from kernelspace to userspace
+int get_last_error(void* u_addr);
+int has_last_error(void);
+int update_errno_buffer(const char *buffer);
if (strcmp(us_proc_info.path, "*")) {
us_proc_info.m_f_dentry = dentry_by_path(us_proc_info.path);
if (us_proc_info.m_f_dentry == NULL) {
+ update_errno_buffer(us_proc_info.path);
return -1;
}
}
{
if (strcmp(d_lib->path_dyn, "") == 0) {
EPRINTF("Cannot find path for lib %s!", d_lib->path);
+ update_errno_buffer(d_lib->path);
/* Just skip all the IPs and go to next lib */
p += d_lib->ips_count * 3 * sizeof(u_int32_t);
d_lib->ips_count = 0;
d_lib->m_f_dentry = dentry_by_path(d_lib->path);
if (d_lib->m_f_dentry == NULL) {
EPRINTF ("failed to lookup dentry for path %s!", d_lib->path);
+ update_errno_buffer(d_lib->path);
/* Just skip all the IPs and go to next lib */
p += d_lib->ips_count * 3 * sizeof(u_int32_t);
d_lib->ips_count = 0;
#include "probes.h"
#include "event_tmpl.h"
+extern int update_errno_buffer(const char *buffer);
+extern int get_last_error(void* u_addr);
+extern int has_last_error(void);
///////////////////////////////////////////////////////////////////////////////////////////////////
extern int EnableContinuousRetrieval(void);
/* Set most links from us_proc_info to data in the bundle */
int link_bundle(void);
-
/* Undo the actions of link_bundle() */
void unlink_bundle(void);