Commit f58454f6 authored by Lubomir Bulej's avatar Lubomir Bulej
Browse files

Cleanup session initiation in unified agent

parent 42a486a9
......@@ -26,7 +26,7 @@ __parse_instrumentations (char * list, struct config * config) {
char ** jar_paths = split_string (list, LIST_SEPARATOR, &jar_count);
config->jar_count = jar_count;
config->instrumentation_jars = jar_paths;
config->jar_paths = jar_paths;
}
static void
......@@ -202,3 +202,8 @@ config_get_session_id () {
return agent_config.session_id;
}
void
config_set_session_id (int32_t session_id) {
agent_config.session_id = session_id;
}
......@@ -118,7 +118,7 @@ struct config {
// Instrumentation jars.
size_t jar_count;
char ** instrumentation_jars;
char ** jar_paths;
// Code generation.
enum bypass_mode bypass_mode;
......@@ -174,4 +174,10 @@ bool config_disl_debug ();
*/
int32_t config_get_session_id ();
/**
* Sets the session id.
*/
void config_set_session_id(int32_t session_id);
#endif // _CONFIG_H
......@@ -93,57 +93,27 @@ __disl_add_jvmti_capabilities (jvmtiEnv * jvmti) {
jvmti_add_capabilities (jvmti, &caps);
}
/*
* Instrumentation jar structure
*/
struct inst_jar {
char * name;
void * buffer;
size_t filesize;
};
/*
* Get filesize
*/
static long
get_filesize (const char * filename) {
struct stat buffer;
int result = stat (filename, &buffer);
check_std_error (result != 0, "failed to determine size of %s", filename);
return (buffer.st_size);
static off_t
__get_file_size (const char * restrict name) {
struct stat statbuf;
int result = stat (name, &statbuf);
check_std_error (result != 0, "failed to determine size of %s", name);
return statbuf.st_size;
}
static void
__load_file (const char * name, void ** buffer, size_t * size) {
static size_t
__load_file (const char * name, void * restrict buffer, const size_t size) {
FILE * file = fopen (name, "r");
check_std_error (file == NULL, "failed to open %s", name);
size_t file_size = (size_t) get_filesize (name);
void * file_data = malloc (file_size);
check_std_error (file_data == NULL, "failed to allocate buffer for %s", name);
size_t bytes_read = fread (file_data, 1, file_size, file);
check_std_error (bytes_read != file_size, "failed to load %s", name);
size_t bytes_read = fread (buffer, 1, size, file);
check_std_error (bytes_read != size, "failed to load %s", name);
fclose (file);
*buffer = file_data;
*size = file_size;
}
/*
* Load the files to the buffers.
* @return
*/
static void
load_files_to_buffers (struct inst_jar * jars, const size_t count) {
// Load all instrumentation jars or fail.
for (size_t i = 0; i < count; ++i) {
struct inst_jar * jar = &(jars [i]);
__load_file (jar->name, &(jar->buffer), &(jar->filesize));
}
return bytes_read;
}
......@@ -153,52 +123,63 @@ load_files_to_buffers (struct inst_jar * jars, const size_t count) {
* for jar sizes and jar data.
*/
static InstrumentationDelivery
instrumentationDeliveryInit (const struct config * config) {
InstrumentationDelivery delivery = INSTRUMENTATION_DELIVERY__INIT;
size_t jarCount = config->jar_count;
size_t total_size = 0;
InstrumentationDelivery_create (const size_t jar_count, char ** jar_names) {
// First load all the jar files into a contiguous buffer.
int32_t * jar_sizes = malloc (jar_count * sizeof (int32_t));
check_std_error (jar_sizes == NULL, "failed to allocate memory for instrumentation sizes");
size_t jar_sizes_total = 0;
for (size_t i = 0; i < jar_count; i++) {
off_t size = __get_file_size (jar_names [i]);
jar_sizes [i] = (int32_t) size;
jar_sizes_total += size;
}
struct inst_jar * jars = malloc (jarCount * sizeof (struct inst_jar));
assert (jar_sizes_total > 0);
delivery.n_sizes = jarCount;
delivery.sizes = malloc (jarCount * sizeof (int32_t));
void * jar_data = malloc (jar_sizes_total);
check_std_error (jar_data == NULL, "failed to allocate memory for instrumentation data");
for (size_t i = 0; i < jarCount; ++i) {
jars [i].name = config->instrumentation_jars [i];
void * jar_buffer = jar_data;
for (size_t i = 0; i < jar_count; ++i) {
jar_buffer += __load_file (jar_names [i], jar_buffer, jar_sizes [i]);
}
load_files_to_buffers (jars, jarCount);
// Initialize the instrumentation message.
InstrumentationDelivery delivery = INSTRUMENTATION_DELIVERY__INIT;
delivery.n_sizes = jar_count;
delivery.sizes = jar_sizes;
delivery.instrumentation.len = jar_sizes_total;
delivery.instrumentation.data = jar_data;
// Open the files and ensure that all of them exists
for (size_t i = 0; i < jarCount; ++i) {
delivery.sizes [i] = (int32_t) jars [i].filesize;
total_size += delivery.sizes [i];
}
return delivery;
}
assert (total_size > 0);
delivery.instrumentation.len = total_size;
delivery.instrumentation.data = malloc (total_size);
static void
InstrumentationDelivery_destroy (InstrumentationDelivery * delivery) {
assert (delivery != NULL);
void * buffer = delivery.instrumentation.data;
for (size_t i = 0; i < jarCount; ++i) {
memcpy (buffer, jars [i].buffer, jars [i].filesize);
buffer += jars [i].filesize;
free (jars [i].buffer);
if (delivery->sizes != NULL) {
free (delivery->sizes);
delivery->sizes = NULL;
}
free (jars);
return delivery;
if (delivery->instrumentation.data != NULL) {
free (delivery->instrumentation.data);
delivery->instrumentation.data = NULL;
}
}
static void
send_instrumentation (const struct config * agent_config) {
send_instrumentation (const int32_t session_id, const size_t jar_count, char ** jar_paths) {
// Create message with instrumentation.
InstrumentationDelivery delivery = InstrumentationDelivery_create (jar_count, jar_paths);
ClientMessage message = CLIENT_MESSAGE__INIT;
InstrumentationDelivery delivery = instrumentationDeliveryInit (agent_config);
message.request_case = CLIENT_MESSAGE__REQUEST_INSTRUMENTATION_DELIVERY;
message.session_id = agent_config->session_id;
message.session_id = session_id;
message.instrumentation_delivery = &delivery;
// Send the request and await response.
......@@ -214,7 +195,9 @@ send_instrumentation (const struct config * agent_config) {
"instrumentation was not accepted by the server"
);
// Release messages.
server_message__free_unpacked (response, NULL);
InstrumentationDelivery_destroy (&delivery);
}
......@@ -226,18 +209,12 @@ disl_init (const struct config * config, jvmtiEnv * jvmti) {
agent_config = config;
agent_code_flags = __calc_code_flags (config, true /* jvm_is_booting */);
send_instrumentation (config);
send_instrumentation (config->session_id, config->jar_count, config->jar_paths);
__disl_add_jvmti_capabilities (jvmti);
}
void
disl_finish () {
// Empty for now.
}
static inline const char *
__safe (const char * class_name) {
return (class_name != NULL) ? class_name : "<unknown class>";
......
......@@ -12,7 +12,6 @@
void disl_init (const struct config * config, jvmtiEnv * jvmti);
void disl_finish ();
// ****************************************************************************
......
......@@ -29,7 +29,6 @@
#include "debug.h"
#include "sessions.h"
static const struct config * agent_cfg;
/*
* Handle the class load event.
......@@ -206,7 +205,6 @@ Agent_OnLoad (JavaVM * jvm, char * options, void * reserved) {
// Get agent configuration.
struct config * agent_config = config_init (jvmti, options);
agent_cfg = agent_config;
// Request JVMTI capabilities:
jvmtiCapabilities caps = {
......@@ -282,7 +280,10 @@ Agent_OnLoad (JavaVM * jvm, char * options, void * reserved) {
//
// Init session
//
session_start (agent_config);
rdaprintf ("agent initialized, starting server session\n");
int32_t session_id = session_start (config_do_disl (), config_do_shvm ());
config_set_session_id (session_id);
rdaprintf ("received session id %d\n", session_id);
if (config_do_disl ()) {
disl_init (agent_config, jvmti);
......@@ -302,9 +303,5 @@ Agent_OnUnload (JavaVM * jvm) {
//
// Just close all the connections.
//
session_end (agent_cfg);
if (config_do_disl ()) {
disl_finish ();
}
session_end (config_get_session_id ());
}
......@@ -14,41 +14,36 @@
#include "network/sender.h"
#include "protocol/main.pb-c.h"
void
session_start (struct config * config) {
int32_t sid = 0;
/* Create, pack and send the session init request */
int32_t
session_start (bool require_disl, bool require_shvm) {
// Create a session init request.
SessionInitRequest req = SESSION_INIT_REQUEST__INIT;
req.require_disl = config->disl_functionality;
req.require_shvm = config->shvm_functionality;
req.require_disl = require_disl;
req.require_shvm = require_shvm;
ClientMessage message = CLIENT_MESSAGE__INIT;
message.request_case = CLIENT_MESSAGE__REQUEST_SESSION_INIT_REQUEST;
message.session_init_request = &req;
/* Receive the response and set the session_id */
// Send the request and await response.
ServerMessage * response = send_n_receive (&message);
switch (response->response_case) {
case SERVER_MESSAGE__RESPONSE_ERROR:
log_server_error (response->error->message);
exit (1);
case SERVER_MESSAGE__RESPONSE_SESSION_INIT_RESPONSE:
sid = response->session_init_response->session_id;
assert (sid != 0);
break;
default:
log_client_error ("Wrong response to the session init request");
exit (1);
// Check the response and return the session_id.
if (SERVER_MESSAGE__RESPONSE_SESSION_INIT_RESPONSE == response->response_case) {
int32_t session_id = response->session_init_response->session_id;
server_message__free_unpacked (response, NULL);
check_error (session_id == 0, "received invalid session id");
return session_id;
}
server_message__free_unpacked (response, NULL);
// Hard failure.
if (SERVER_MESSAGE__RESPONSE_ERROR == response->response_case) {
log_server_error (response->error->message);
} else {
log_client_error ("invalid response to the session init request");
}
config->session_id = sid;
exit (1);
}
......@@ -56,14 +51,16 @@ session_start (struct config * config) {
* Send a session-closing message to the server.
*/
void
session_end (const struct config * config) {
session_end (int32_t session_id) {
// Create session close request.
CloseConnection cc = CLOSE_CONNECTION__INIT;
cc.reason = CLOSE_CONNECTION__CLOSE_REASON__FINISHED;
ClientMessage message = CLIENT_MESSAGE__INIT;
message.request_case = CLIENT_MESSAGE__REQUEST_CLOSE_CONNECTION;
message.session_id = config->session_id;
message.session_id = session_id;
message.close_connection = &cc;
// Just send the message, there is no response.
send_client_message (&message);
}
......@@ -6,7 +6,7 @@
#ifndef _SESSIONS_H
#define _SESSIONS_H
#include "config.h"
#include <stdbool.h>
/**
......@@ -14,11 +14,11 @@
*
* @return Obtained session id.
*/
void session_start (struct config * config);
int32_t session_start (const bool require_disl, const bool require_shvm);
/**
* Announce the end of the session to the server.
*/
void session_end (const struct config * config);
void session_end (const int32_t session_id);
#endif // _SESSIONS_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment