Commit f7363f5f authored by Matteo Basso's avatar Matteo Basso

disl controller

parent f980069a
Pipeline #9579 failed with stages
in 2 minutes and 53 seconds
......@@ -5,6 +5,7 @@
<classpathentry kind="src" output="output/build/util" path="src-util"/>
<classpathentry kind="src" output="output/build/test" path="src-test"/>
<classpathentry kind="src" output="output/build/shvm-dispatch" path="src-shvm-dispatch"/>
<classpathentry kind="src" output="output/build/disl-controller" path="src-disl-controller"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="output/lib/disl-bypass.jar"/>
<classpathentry kind="lib" path="lib/disl/log4j.jar" sourcepath="lib/devel/log4j-source.jar"/>
......
......@@ -8,6 +8,7 @@ src.bin=bin
src.disl=src-disl
src.disl.bypass=src-disl-bypass
src.disl.agent=src-disl-agent
src.disl.controller=src-disl-controller
src.shvm=src-shvm
src.shvm.agent=src-shvm-agent
src.shvm.dispatch=src-shvm-dispatch
......@@ -31,6 +32,7 @@ build.tools=${build.dir}/tools
build.disl=${build.dir}/disl
build.disl.thread=${build.disl}-thread
build.disl.bypass=${build.disl}-bypass
build.disl.controller=${build.disl}-controller
build.shvm=${build.dir}/shvm
build.shvm.dispatch=${build.shvm}-dispatch
build.test=${build.dir}/test
......@@ -57,6 +59,7 @@ out.doc.jdoc=${out.dir}/jdoc
disl.lib=disl-server.jar
disl.bypass.lib=disl-bypass.jar
disl.agent.lib.base=dislagent
disl.controller.lib=disl-controller.jar
shvm.lib=dislre-server.jar
shvm.dispatch.lib=dislre-dispatch.jar
......
......@@ -268,6 +268,7 @@
<path id="disl.classpath">
<pathelement location="${build.disl}"/>
<pathelement location="${build.disl.controller}"/>
</path>
<path id="disl.bypass.classpath">
......@@ -475,8 +476,18 @@
<!-- DiSL -->
<target name="compile-disl-controller">
<mkdir dir="${build.disl.controller}"/>
<javac destdir="${build.disl.controller}" srcdir="${src.disl.controller}" debug="true"/>
</target>
<target name="compile-disl" depends="compile-util,compile-disl-bypass">
<target name="build-disl-controller" depends="compile-disl-controller">
<jar destfile="${out.lib}/${disl.controller.lib}" basedir="${build.disl.controller}"/>
</target>
<target name="compile-disl" depends="compile-util,compile-disl-bypass,compile-disl-controller">
<mkdir dir="${build.disl}"/>
<javac destdir="${build.disl}" srcdir="${src.disl}" debug="true">
<classpath>
......@@ -489,7 +500,7 @@
</target>
<target name="build-disl" depends="compile-disl,build-disl-bypass">
<target name="build-disl" depends="compile-disl,build-disl-bypass,build-disl-controller">
<local name="server.class"/>
<find-class property="server.class" dir="${build.disl}" name="DiSLServer"/>
......@@ -967,6 +978,9 @@
<fileset dir="${src.disl.bypass}">
<include name="**/DynamicBypass.java"/>
</fileset>
<fileset dir="${src.disl.controller}">
<include name="**/DiSLController.java"/>
</fileset>
<fileset dir="${src.shvm}">
<include name="**/RemoteAnalysis.java"/>
......@@ -1012,6 +1026,7 @@
<zip destfile="${out.src}/src.zip">
<zipfileset dir="${src.disl}"/>
<zipfileset dir="${src.disl.bypass}/dynamic"/>
<zipfileset dir="${src.disl.controller}"/>
<zipfileset dir="${src.shvm}"/>
<zipfileset dir="${src.shvm.dispatch}"/>
<zipfileset dir="${src.util}"/>
......
......@@ -59,6 +59,10 @@
#define DISL_LOADER_UNKNOWN -1
//#define DISL_DEBUG_PRINT_TC_LIST 1 //Uncomment (or define this macro through command line) for verbose printing of type_and_classloader lists
// message types must match the ones defined in DiSLServer.java
// implicit message type 0 = shutdown signal
#define DISL_MESSAGE_INSTRUMENT 1
#define DISL_MESSAGE_CONTROLLER 2
static int nLoadedClasses = 0;
......@@ -86,6 +90,10 @@ static void __free_list_of_strings(struct list_of_strings * root) {
}
// Global JVMTI environment (needed by the Deploy API)
static jvmtiEnv * jvmti;
/* This functions are intended to support critical sections
* during object tagging. At the moment, they are not utilized.
* They are kept here for future needs.
......@@ -582,7 +590,7 @@ __instrument_class (
instrument_class_request__pack (&request, send_buffer);
struct connection * conn = network_acquire_connection ();
message_send (conn, send_buffer, send_size);
message_send (conn, DISL_MESSAGE_INSTRUMENT, send_buffer, send_size);
//
......@@ -1473,17 +1481,87 @@ static struct list_of_strings * __build_fl_exclusion_list (struct config * confi
}
/************************************
/******** DiSL controller ***********
/************************************/
void send_control(JNIEnv * jni, jstring snippetName, ControllerAction action) {
uint8_t * snippetStr = (*jni)->GetStringUTFChars(jni, snippetName, NULL);
check_error(snippetStr == NULL, "Cannot get string from Java");
ControllerRequest request = CONTROLLER_REQUEST__INIT;
request.action = action;
request.snippetname = snippetStr;
size_t send_size = controller_request__get_packed_size (&request);
void * send_buffer = malloc (send_size);
assert (send_buffer != NULL);
controller_request__pack (&request, send_buffer);
struct connection * conn = network_acquire_connection ();
message_send (conn, DISL_MESSAGE_CONTROLLER, send_buffer, send_size);
//
void * recv_buffer;
size_t recv_size = message_recv (conn, &recv_buffer);
network_release_connection (conn);
ControllerResponse * response = controller_response__unpack (NULL, recv_size, recv_buffer);
assert (response != NULL);
free (recv_buffer);
(* jni)->ReleaseStringUTFChars (jni, snippetName, snippetStr);
if (response->result == CONTROLLER_RESULT__KO) {
fprintf (
stderr, "%sinstrumentation server error:\n%s\n",
ERROR_PREFIX, response->errormessage
);
exit (ERROR_SERVER);
}
}
JNIEXPORT void JNICALL VISIBLE
Java_ch_usi_dag_disl_dislcontroller_DiSLController_deploy
(JNIEnv * jni, jclass this_class, jstring snippetName) {
send_control(jni, snippetName, CONTROLLER_ACTION__DEPLOY);
return;
}
JNIEXPORT void JNICALL VISIBLE
Java_ch_usi_dag_disl_dislcontroller_DiSLController_undeploy
(JNIEnv * jni, jclass this_class, jstring snippetName) {
send_control(jni, snippetName, CONTROLLER_ACTION__UNDEPLOY);
return;
}
JNIEXPORT void JNICALL VISIBLE
Java_ch_usi_dag_disl_dislcontroller_DiSLController_retransformClass
(JNIEnv * jni, jclass this_class, jclass klass) {
(*jvmti)->RetransformClasses(jvmti, 1, &klass);
}
/////////////////////////
JNIEXPORT jint JNICALL VISIBLE
Agent_OnLoad (JavaVM * jvm, char * options, void * reserved) {
jvmtiEnv * jvmti = __get_jvmti (jvm);
jvmti = __get_jvmti (jvm);
// add capabilities
jvmtiCapabilities caps = {
.can_redefine_classes = 1,
.can_generate_all_class_hook_events = 1,
.can_tag_objects = 1 //Added capability for supporting classloader tag
.can_tag_objects = 1, //Added capability for supporting classloader tag
.can_retransform_classes = 1, //Needed for the Deploy API
.can_retransform_any_class = 1 //Needed for the Deploy API
};
//
......
......@@ -97,6 +97,96 @@ void instrument_class_response__free_unpacked
assert(message->base.descriptor == &instrument_class_response__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void controller_request__init
(ControllerRequest *message)
{
static const ControllerRequest init_value = CONTROLLER_REQUEST__INIT;
*message = init_value;
}
size_t controller_request__get_packed_size
(const ControllerRequest *message)
{
assert(message->base.descriptor == &controller_request__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t controller_request__pack
(const ControllerRequest *message,
uint8_t *out)
{
assert(message->base.descriptor == &controller_request__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t controller_request__pack_to_buffer
(const ControllerRequest *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &controller_request__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
ControllerRequest *
controller_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (ControllerRequest *)
protobuf_c_message_unpack (&controller_request__descriptor,
allocator, len, data);
}
void controller_request__free_unpacked
(ControllerRequest *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &controller_request__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void controller_response__init
(ControllerResponse *message)
{
static const ControllerResponse init_value = CONTROLLER_RESPONSE__INIT;
*message = init_value;
}
size_t controller_response__get_packed_size
(const ControllerResponse *message)
{
assert(message->base.descriptor == &controller_response__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t controller_response__pack
(const ControllerResponse *message,
uint8_t *out)
{
assert(message->base.descriptor == &controller_response__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t controller_response__pack_to_buffer
(const ControllerResponse *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &controller_response__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
ControllerResponse *
controller_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (ControllerResponse *)
protobuf_c_message_unpack (&controller_response__descriptor,
allocator, len, data);
}
void controller_response__free_unpacked
(ControllerResponse *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &controller_response__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
static const ProtobufCFieldDescriptor instrument_class_request__field_descriptors[6] =
{
{
......@@ -264,6 +354,108 @@ const ProtobufCMessageDescriptor instrument_class_response__descriptor =
(ProtobufCMessageInit) instrument_class_response__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor controller_request__field_descriptors[2] =
{
{
"action",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(ControllerRequest, action),
&controller_action__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"snippetName",
2,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(ControllerRequest, snippetname),
NULL,
&protobuf_c_empty_string,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned controller_request__field_indices_by_name[] = {
0, /* field[0] = action */
1, /* field[1] = snippetName */
};
static const ProtobufCIntRange controller_request__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 2 }
};
const ProtobufCMessageDescriptor controller_request__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"ControllerRequest",
"ControllerRequest",
"ControllerRequest",
"",
sizeof(ControllerRequest),
2,
controller_request__field_descriptors,
controller_request__field_indices_by_name,
1, controller_request__number_ranges,
(ProtobufCMessageInit) controller_request__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor controller_response__field_descriptors[2] =
{
{
"result",
1,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(ControllerResponse, result),
&controller_result__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"errorMessage",
2,
PROTOBUF_C_LABEL_NONE,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(ControllerResponse, errormessage),
NULL,
&protobuf_c_empty_string,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned controller_response__field_indices_by_name[] = {
1, /* field[1] = errorMessage */
0, /* field[0] = result */
};
static const ProtobufCIntRange controller_response__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 2 }
};
const ProtobufCMessageDescriptor controller_response__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"ControllerResponse",
"ControllerResponse",
"ControllerResponse",
"",
sizeof(ControllerResponse),
2,
controller_response__field_descriptors,
controller_response__field_indices_by_name,
1, controller_response__number_ranges,
(ProtobufCMessageInit) controller_response__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCEnumValue instrument_class_result__enum_values_by_number[3] =
{
{ "CLASS_UNMODIFIED", "INSTRUMENT_CLASS_RESULT__CLASS_UNMODIFIED", 0 },
......@@ -294,3 +486,59 @@ const ProtobufCEnumDescriptor instrument_class_result__descriptor =
instrument_class_result__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
static const ProtobufCEnumValue controller_action__enum_values_by_number[2] =
{
{ "DEPLOY", "CONTROLLER_ACTION__DEPLOY", 0 },
{ "UNDEPLOY", "CONTROLLER_ACTION__UNDEPLOY", 1 },
};
static const ProtobufCIntRange controller_action__value_ranges[] = {
{0, 0},{0, 2}
};
static const ProtobufCEnumValueIndex controller_action__enum_values_by_name[2] =
{
{ "DEPLOY", 0 },
{ "UNDEPLOY", 1 },
};
const ProtobufCEnumDescriptor controller_action__descriptor =
{
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"ControllerAction",
"ControllerAction",
"ControllerAction",
"",
2,
controller_action__enum_values_by_number,
2,
controller_action__enum_values_by_name,
1,
controller_action__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
static const ProtobufCEnumValue controller_result__enum_values_by_number[2] =
{
{ "OK", "CONTROLLER_RESULT__OK", 0 },
{ "KO", "CONTROLLER_RESULT__KO", 1 },
};
static const ProtobufCIntRange controller_result__value_ranges[] = {
{0, 0},{0, 2}
};
static const ProtobufCEnumValueIndex controller_result__enum_values_by_name[2] =
{
{ "KO", 1 },
{ "OK", 0 },
};
const ProtobufCEnumDescriptor controller_result__descriptor =
{
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"ControllerResult",
"ControllerResult",
"ControllerResult",
"",
2,
controller_result__enum_values_by_number,
2,
controller_result__enum_values_by_name,
1,
controller_result__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
......@@ -4,7 +4,7 @@
#ifndef PROTOBUF_C_dislserver_2eproto__INCLUDED
#define PROTOBUF_C_dislserver_2eproto__INCLUDED
#include "protobuf-c.h"
#include <protobuf-c/protobuf-c.h>
PROTOBUF_C__BEGIN_DECLS
......@@ -17,6 +17,8 @@ PROTOBUF_C__BEGIN_DECLS
typedef struct _InstrumentClassRequest InstrumentClassRequest;
typedef struct _InstrumentClassResponse InstrumentClassResponse;
typedef struct _ControllerRequest ControllerRequest;
typedef struct _ControllerResponse ControllerResponse;
/* --- enums --- */
......@@ -27,6 +29,16 @@ typedef enum _InstrumentClassResult {
INSTRUMENT_CLASS_RESULT__ERROR = 3
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(INSTRUMENT_CLASS_RESULT)
} InstrumentClassResult;
typedef enum _ControllerAction {
CONTROLLER_ACTION__DEPLOY = 0,
CONTROLLER_ACTION__UNDEPLOY = 1
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CONTROLLER_ACTION)
} ControllerAction;
typedef enum _ControllerResult {
CONTROLLER_RESULT__OK = 0,
CONTROLLER_RESULT__KO = 1
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CONTROLLER_RESULT)
} ControllerResult;
/* --- messages --- */
......@@ -57,6 +69,28 @@ struct _InstrumentClassResponse
, INSTRUMENT_CLASS_RESULT__CLASS_UNMODIFIED, (char *)protobuf_c_empty_string, {0,NULL} }
struct _ControllerRequest
{
ProtobufCMessage base;
ControllerAction action;
char *snippetname;
};
#define CONTROLLER_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&controller_request__descriptor) \
, CONTROLLER_ACTION__DEPLOY, (char *)protobuf_c_empty_string }
struct _ControllerResponse
{
ProtobufCMessage base;
ControllerResult result;
char *errormessage;
};
#define CONTROLLER_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&controller_response__descriptor) \
, CONTROLLER_RESULT__OK, (char *)protobuf_c_empty_string }
/* InstrumentClassRequest methods */
void instrument_class_request__init
(InstrumentClassRequest *message);
......@@ -95,6 +129,44 @@ InstrumentClassResponse *
void instrument_class_response__free_unpacked
(InstrumentClassResponse *message,
ProtobufCAllocator *allocator);
/* ControllerRequest methods */
void controller_request__init
(ControllerRequest *message);
size_t controller_request__get_packed_size
(const ControllerRequest *message);
size_t controller_request__pack
(const ControllerRequest *message,
uint8_t *out);
size_t controller_request__pack_to_buffer
(const ControllerRequest *message,
ProtobufCBuffer *buffer);
ControllerRequest *
controller_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void controller_request__free_unpacked
(ControllerRequest *message,
ProtobufCAllocator *allocator);
/* ControllerResponse methods */
void controller_response__init
(ControllerResponse *message);
size_t controller_response__get_packed_size
(const ControllerResponse *message);
size_t controller_response__pack
(const ControllerResponse *message,
uint8_t *out);
size_t controller_response__pack_to_buffer
(const ControllerResponse *message,
ProtobufCBuffer *buffer);
ControllerResponse *
controller_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void controller_response__free_unpacked
(ControllerResponse *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*InstrumentClassRequest_Closure)
......@@ -103,6 +175,12 @@ typedef void (*InstrumentClassRequest_Closure)
typedef void (*InstrumentClassResponse_Closure)
(const InstrumentClassResponse *message,
void *closure_data);
typedef void (*ControllerRequest_Closure)
(const ControllerRequest *message,
void *closure_data);
typedef void (*ControllerResponse_Closure)
(const ControllerResponse *message,
void *closure_data);
/* --- services --- */
......@@ -110,8 +188,12 @@ typedef void (*InstrumentClassResponse_Closure)
/* --- descriptors --- */
extern const ProtobufCEnumDescriptor instrument_class_result__descriptor;
extern const ProtobufCEnumDescriptor controller_action__descriptor;
extern const ProtobufCEnumDescriptor controller_result__descriptor;
extern const ProtobufCMessageDescriptor instrument_class_request__descriptor;
extern const ProtobufCMessageDescriptor instrument_class_response__descriptor;
extern const ProtobufCMessageDescriptor controller_request__descriptor;
extern const ProtobufCMessageDescriptor controller_response__descriptor;
PROTOBUF_C__END_DECLS
......
......@@ -43,7 +43,7 @@ __send (struct connection * conn, void * header, const size_t header_size, void
* via the given connection. Returns the number of bytes sent.
*/
ssize_t
message_send (struct connection * conn, void * message, const size_t message_size) {
message_send (struct connection * conn, unsigned const char message_type, void * message, const size_t message_size) {
assert (conn != NULL);
assert (message != NULL);
......@@ -51,9 +51,17 @@ message_send (struct connection * conn, void * message, const size_t message_siz
//
size_t message_type_size = sizeof (message_type);
uint32_t message_size_data = htonl (message_size);
size_t header_size = sizeof (message_size_data);
ssize_t sent = __send (conn, &message_size_data, header_size, message, message_size);
size_t body_length_size = sizeof (message_size_data);
size_t header_size = message_type_size + body_length_size;
char header[header_size];
memcpy(header, &message_type, message_type_size);
memcpy(header + message_type_size, &message_size_data, body_length_size);
ssize_t sent = __send (conn, header, header_size, message, message_size);
assert (sent == (ssize_t) (header_size + message_size));
//
......
......@@ -3,7 +3,7 @@
#include "connection.h"
ssize_t message_send (struct connection * conn, void * message, const size_t message_size);
ssize_t message_send (struct connection * conn, unsigned const char message_type, void * message, const size_t message_size);
ssize_t message_recv (struct connection * conn, void ** message_ptr);
#endif /* _MSGCHANNEL_H_ */
......@@ -51,8 +51,12 @@ __connection_close_hook (struct connection * conn) {