Commit 26c4f23e authored by Vít Kabele's avatar Vít Kabele

Sending instrumentation to server

parent 1013d5c7
......@@ -739,7 +739,7 @@ Agent_OnLoad (JavaVM * jvm, char * options, void * reserved) {
// configure agent and init connections
__configure_from_options (options, &agent_config);
__configure_from_options (NULL, &agent_config);
__configure_from_properties (jvmti, &agent_config);
jvm_is_started = false;
......@@ -749,7 +749,7 @@ Agent_OnLoad (JavaVM * jvm, char * options, void * reserved) {
rdaprintf ("agent loaded, initializing connections\n");
network_init (agent_config.server_host, agent_config.server_port);
int32_t sid = session_start();
int32_t sid = session_start(options);
rdaprintf("Obtained session id is %i\n", sid);
......
......@@ -610,14 +610,26 @@ const ProtobufCMessageDescriptor session_init_response__descriptor =
(ProtobufCMessageInit) session_init_response__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor instrumentation_delivery__field_descriptors[1] =
static const ProtobufCFieldDescriptor instrumentation_delivery__field_descriptors[2] =
{
{
"sizes",
1,
PROTOBUF_C_LABEL_REPEATED,
PROTOBUF_C_TYPE_INT32,
offsetof(InstrumentationDelivery, n_sizes),
offsetof(InstrumentationDelivery, sizes),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"instrumentation",
2,
PROTOBUF_C_LABEL_REPEATED,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_BYTES,
offsetof(InstrumentationDelivery, n_instrumentation),
0, /* quantifier_offset */
offsetof(InstrumentationDelivery, instrumentation),
NULL,
NULL,
......@@ -626,12 +638,13 @@ static const ProtobufCFieldDescriptor instrumentation_delivery__field_descriptor
},
};
static const unsigned instrumentation_delivery__field_indices_by_name[] = {
0, /* field[0] = instrumentation */
1, /* field[1] = instrumentation */
0, /* field[0] = sizes */
};
static const ProtobufCIntRange instrumentation_delivery__number_ranges[1 + 1] =
{
{ 2, 0 },
{ 0, 1 }
{ 1, 0 },
{ 0, 2 }
};
const ProtobufCMessageDescriptor instrumentation_delivery__descriptor =
{
......@@ -641,7 +654,7 @@ const ProtobufCMessageDescriptor instrumentation_delivery__descriptor =
"InstrumentationDelivery",
"",
sizeof(InstrumentationDelivery),
1,
2,
instrumentation_delivery__field_descriptors,
instrumentation_delivery__field_indices_by_name,
1, instrumentation_delivery__number_ranges,
......
......@@ -96,12 +96,13 @@ struct _SessionInitResponse
struct _InstrumentationDelivery
{
ProtobufCMessage base;
size_t n_instrumentation;
ProtobufCBinaryData *instrumentation;
size_t n_sizes;
int32_t *sizes;
ProtobufCBinaryData instrumentation;
};
#define INSTRUMENTATION_DELIVERY__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&instrumentation_delivery__descriptor) \
, 0,NULL }
, 0,NULL, {0,NULL} }
/*
......
......@@ -6,8 +6,11 @@
* Created by Vit Kabele on 12/10/2018.
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include "sessions.h"
......@@ -46,29 +49,133 @@ receive_server_message(struct connection * conn) {
return (response);
}
struct inst_jar {
char * name;
FILE * file;
long filesize;
};
static size_t
substr_count(const char * string, const char * substr) {
size_t count = 0;
for(const char * token = string; (token = strstr(token, substr)) != NULL; ++token)
++count;
return (count);
}
/*
* Free the return value after use.
*/
static char **
split_string(char * string, const char * separator) {
size_t tokens = substr_count(string, separator) + 1;
assert(tokens > 0);
char ** arr = malloc(tokens * sizeof(char *));
arr[0] = strtok(string, separator);
for(size_t i = 1; i < tokens; ++i)
arr[i] = strtok(NULL, separator);
return (arr);
}
/*
* Get filesize
*/
static long
get_filesize(FILE * file){
assert(fseek(file, 0L, SEEK_END) == 0);
long size = ftell(file);
fseek(file, 0L, SEEK_SET);
return size;
}
/*
* Load the instrumentation.
* Options should be field of paths pointing to a *.jar files separated by semicolon (:)
*/
InstrumentationDelivery
load_instrumentation(char * options){
size_t tokens = substr_count(options, ":") + 1;
struct inst_jar * jars = malloc(tokens * sizeof(struct inst_jar));
size_t total_size = 0;
InstrumentationDelivery delivery = INSTRUMENTATION_DELIVERY__INIT;
delivery.n_sizes = tokens;
delivery.sizes = malloc( tokens * sizeof(int32_t));
// Allocate an array of filenames/paths
char ** arr = split_string(options,":");
for(size_t i = 0; i < tokens; ++i){
jars[i].name = arr[i];
}
free(arr);
assert(tokens > 0);
// Open the files and ensure that all of them exists
for(size_t i = 0; i < tokens; ++i){
jars[i].file = fopen(jars[i].name,"r");
assert(jars[i].file != NULL);
jars[i].filesize = get_filesize(jars[i].file);
total_size += jars[i].filesize;
delivery.sizes[i] = (int32_t) jars[i].filesize; // Crop conversion size_t -> int32_t
warn("Size of instrumentation file %s is %li\n", jars[i].name, get_filesize(jars[i].file));
}
assert(total_size > 0);
delivery.instrumentation.len = total_size;
delivery.instrumentation.data = malloc(total_size);
void * buffer = delivery.instrumentation.data;
for(size_t i = 0; i < tokens; ++i){
fread(buffer, 1, (size_t)jars[i].filesize, jars[i].file);
buffer += jars[i].filesize;
fclose(jars[i].file);
}
free(jars);
return (delivery);
}
int32_t
session_start() {
session_start(char * options) {
struct connection * conn = network_acquire_connection();
int32_t sid = 0;
/* Create, pack and send the session init request */
ClientMessage message = CLIENT_MESSAGE__INIT;
SessionInitRequest req = SESSION_INIT_REQUEST__INIT;
message.request_case = CLIENT_MESSAGE__REQUEST_SESSION_INIT_REQUEST;
message.session_init_request = &req;
message.session_init_request->code = 42;
{ /* Create, pack and send the session init request */
ClientMessage message = CLIENT_MESSAGE__INIT;
SessionInitRequest req = SESSION_INIT_REQUEST__INIT;
message.request_case = CLIENT_MESSAGE__REQUEST_SESSION_INIT_REQUEST;
message.session_init_request = &req;
message.session_init_request->code = 42;
send_client_message(message, conn);
send_client_message(message, conn);
/* Receive the response and set the session_id */
ServerMessage * response = receive_server_message(conn);
/* Receive the response and set the session_id */
ServerMessage * response = receive_server_message(conn);
assert(response->response_case == SERVER_MESSAGE__RESPONSE_SESSION_INIT_RESPONSE);
assert(response->response_case == SERVER_MESSAGE__RESPONSE_SESSION_INIT_RESPONSE);
sid = response->session_init_response->session_id;
assert(sid != 0);
session_id = sid;
int32_t sid = response->session_init_response->session_id;
session_id = sid;
server_message__free_unpacked(response, NULL);
}
server_message__free_unpacked(response, NULL);
{
ClientMessage message = CLIENT_MESSAGE__INIT;
InstrumentationDelivery delivery = load_instrumentation(options);
message.request_case = CLIENT_MESSAGE__REQUEST_INSTRUMENTATION_DELIVERY;
message.session_id = sid;
message.instrumentation_delivery = &delivery;
send_client_message(message, conn);
}
network_release_connection(conn);
......
......@@ -35,7 +35,7 @@ receive_server_message(struct connection * conn);
* @return Obtained session id.
*/
int32_t
session_start();
session_start(char * options);
/*
* Announce the end of the session to the server.
......
......@@ -29,7 +29,8 @@ message SessionInitResponse {
// When the client obtains the session_id, next step should be sending
// the instrumentation jar (or more of them) to the instrumentation server.
message InstrumentationDelivery {
repeated bytes instrumentation = 2;
repeated int32 sizes = 1;
bytes instrumentation = 2;
}
// This is server response to InstrumentationDelivery message
......
......@@ -11,6 +11,7 @@ import ch.usi.dag.util.logging.Logger;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.Console;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
......@@ -20,6 +21,7 @@ import java.nio.channels.SocketChannel;
import ch.usi.dag.dislserver.Protocol.ClientMessage;
import ch.usi.dag.dislserver.Protocol.ServerMessage;
import ch.usi.dag.dislserver.Protocol.SessionInitResponse;
import ch.usi.dag.dislserver.Protocol.InstrumentationDelivery;
/**
......@@ -112,6 +114,18 @@ final class ConnectionHandler implements Runnable {
sendMessage (response, timer);
break;
case INSTRUMENTATION_DELIVERY:
InstrumentationDelivery delivery = request.getInstrumentationDelivery ();
credentials = __server.getSession (request.getSessionId ());
int off = 0;
for(int i = 0; i < delivery.getSizesCount (); ++i){
byte[] bytes = new byte[ delivery.getSizes(i) ];
delivery.getInstrumentation ().copyTo (bytes, off, 0, delivery.getSizes (i));
off += delivery.getSizes (i);
credentials.Instrumentations.add (bytes);
}
System.out.println (
String.format ("Received %d inst, of total size %d", delivery.getSizesCount (), delivery.getSizes (0))
);
break;
case INSTRUMENT_CLASS_REQUEST:
timer.mark (DiSLServer.ElapsedTime.UNPACK);
......
......@@ -6,6 +6,10 @@
*/
package ch.usi.dag.dislserver;
import java.util.ArrayList;
import java.util.List;
/**
* Pack the values related to one session.
*/
......@@ -44,6 +48,11 @@ public class SessionCredentials {
*/
public SessionState State = SessionState.INITIALIZED;
/**
* Byte arrays representing files with instrumentation.
*/
List<byte[]> Instrumentations = new ArrayList<>();
/**
* Construct the class
* @param session_id
......
Markdown is supported
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