From b73e93ff6db654e8df53ea2b7f1d80d08c62a4f6 Mon Sep 17 00:00:00 2001
From: Claudio Bisegni <Claudio.Bisegni@lnf.infn.it>
Date: Tue, 25 Nov 2014 18:26:10 +0100
Subject: [PATCH] complete the two api delete and get from snapshot. Get api
 need to be improved.

---
 ChaosDataService/QueryDataConsumer.cpp        | 68 ++++++++++++-
 ChaosDataService/QueryDataConsumer.h          |  4 +-
 ChaosDataService/db_system/DBDriver.h         |  4 +-
 ChaosDataService/db_system/MongoDBDriver.cpp  | 38 ++++++-
 ChaosSnapshotUtility/main.cpp                 | 98 ++++++++++++++-----
 .../channel/DirectIODeviceChannelGlobal.h     | 13 +--
 .../DirectIOSystemAPIClientChannel.cpp        |  4 +-
 .../channel/DirectIOSystemAPIClientChannel.h  |  2 +
 .../DirectIOSystemAPIServerChannel.cpp        | 23 +++--
 .../channel/DirectIOSystemAPIServerChannel.h  |  4 +-
 10 files changed, 214 insertions(+), 44 deletions(-)

diff --git a/ChaosDataService/QueryDataConsumer.cpp b/ChaosDataService/QueryDataConsumer.cpp
index 386ae1b28..8f6b26314 100644
--- a/ChaosDataService/QueryDataConsumer.cpp
+++ b/ChaosDataService/QueryDataConsumer.cpp
@@ -312,12 +312,76 @@ int QueryDataConsumer::consumeNewSnapshotEvent(opcode_headers::DirectIOSystemAPI
 // Manage the delete operation on an existing snapshot
 int QueryDataConsumer::consumeDeleteSnapshotEvent(opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeader *header,
 												  DirectIOSystemAPISnapshotResult *api_result) {
-	
+	int err = 0;
+	if(settings->cache_only) {
+		//data service is in cache only mode throw the error
+		api_result->error = -1;
+		std::strncpy(api_result->error_message, "Chaos Data Service is in cache only", 255);
+		//delete header
+		if(header) free(header);
+		return 0;
+	}
+	if((err = db_driver->snapshotDeleteWithName(header->field.snap_name))) {
+		api_result->error = err;
+		std::strcpy(api_result->error_message, "Error deleteing the snapshot");
+		QDCERR_ << api_result->error_message << "->" << header->field.snap_name;
+	} else {
+		api_result->error = 0;
+		std::strcpy(api_result->error_message, "Snapshot deleted");
+	}
+	return err;
 }
 
 // Return the dataset for a producerkey ona specific snapshot
 int QueryDataConsumer::consumeGetDatasetSnapshotEvent(opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeader *header,
 													  const std::string& producer_id,
-													  DirectIOSystemAPIGetDatasetSnapshotResult *api_result) {
+													  void **channel_found_data,
+													  uint32_t& channel_found_data_length,
+													  DirectIOSystemAPISnapshotResult *api_result) {
+	int err = 0;
+	std::string channel_type;
+	if(settings->cache_only) {
+		//data service is in cache only mode throw the error
+		api_result->error = -1;
+		std::strncpy(api_result->error_message, "Chaos Data Service is in cache only", 255);
+		//delete header
+		if(header) free(header);
+		return -1;
+	}
 	
+	//trduce int to postfix channel type
+	switch(header->field.channel_type) {
+		case 0:
+			channel_type = DataPackPrefixID::OUTPUT_DATASE_PREFIX;
+			break;
+		case 1:
+			channel_type = DataPackPrefixID::INPUT_DATASE_PREFIX;
+			break;
+		case 2:
+			channel_type = DataPackPrefixID::CUSTOM_DATASE_PREFIX;
+			break;
+		case 3:
+			channel_type = DataPackPrefixID::SYSTEM_DATASE_PREFIX;
+			break;
+	}
+	
+	if((err = db_driver->snapshotGetDatasetForProducerKey(header->field.snap_name,
+														  producer_id,
+														  channel_type,
+														  channel_found_data,
+														  channel_found_data_length))) {
+		api_result->error = err;
+		std::strcpy(api_result->error_message, "Error retriving the snapshoted dataaset for producer key");
+		QDCERR_ << api_result->error_message << "[" << header->field.snap_name << "/" << producer_id<<"]";
+	} else {
+		if(*channel_found_data) {
+			api_result->error = 0;
+			std::strcpy(api_result->error_message, "Snapshot found");
+		} else {
+			api_result->error = -2;
+			std::strcpy(api_result->error_message, "Channel data not found in snapshot");
+			
+		}
+	}
+	return err;
 }
diff --git a/ChaosDataService/QueryDataConsumer.h b/ChaosDataService/QueryDataConsumer.h
index 945f57d85..e6cea9a22 100644
--- a/ChaosDataService/QueryDataConsumer.h
+++ b/ChaosDataService/QueryDataConsumer.h
@@ -107,7 +107,9 @@ namespace chaos{
 			// Return the dataset for a producerkey ona specific snapshot
 			int consumeGetDatasetSnapshotEvent(opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeader *header,
 											   const std::string& producer_id,
-											   DirectIOSystemAPIGetDatasetSnapshotResult *api_result);
+											   void **channel_found_data,
+											   uint32_t& channel_found_data_length,
+											   DirectIOSystemAPISnapshotResult *api_result);
 			//async central timer hook
 			void timeout();
         public:
diff --git a/ChaosDataService/db_system/DBDriver.h b/ChaosDataService/db_system/DBDriver.h
index 26e4cf0a2..001a2d315 100644
--- a/ChaosDataService/db_system/DBDriver.h
+++ b/ChaosDataService/db_system/DBDriver.h
@@ -227,7 +227,7 @@ namespace chaos {
 				 \param working_job_unique_id the identification of the job
 				 \param snapshot_name the name of the snapshot where put the element
 				 \param producer_unique_key the unique key of the producer
-				 \param dataset_type the type of the dataset, refer to @DataPackCommonKey::DPCK_DATASET_TYPE field of the dataset
+				 \param dataset_type the type of the dataset, refer to @DataPackPrefixID field of the dataset
 				 \param data the serialized data of the dataset
 				 \param data_len the length of the serialized data
 				 */
@@ -255,7 +255,7 @@ namespace chaos {
 				 snapshot
 				 \param snapshot_name the name of the snapshot to delete
 				 \param producer_unique_key the unique key of the producer
-				 \param dataset_type the type of the dataset, refer to @DataPackCommonKey::DPCK_DATASET_TYPE field of the dataset
+				 \param dataset_type the type of the dataset, refer to @DataPackPrefixID field of the dataset
 				 \param channel_data the data of the channel;
 				 \param channel_data_size the size of the channel data
 				 */
diff --git a/ChaosDataService/db_system/MongoDBDriver.cpp b/ChaosDataService/db_system/MongoDBDriver.cpp
index a12df3f5d..f503648f1 100644
--- a/ChaosDataService/db_system/MongoDBDriver.cpp
+++ b/ChaosDataService/db_system/MongoDBDriver.cpp
@@ -939,7 +939,40 @@ int MongoDBDriver::snapshotGetDatasetForProducerKey(const std::string& snapshot_
 													const std::string& dataset_type,
 													void **channel_data,
 													uint32_t& channel_data_size) {
-	
+	int err = 0;
+	mongo::BSONObj			result;
+	mongo::BSONObjBuilder	search_snapshot;
+	try{
+		//search for snapshot name and producer unique key
+		search_snapshot << MONGO_DB_FIELD_SNAPSHOT_DATA_SNAPSHOT_NAME << snapshot_name
+		<< MONGO_DB_FIELD_SNAPSHOT_DATA_PRODUCER_ID << producer_unique_key;
+		
+		mongo::BSONObj q = search_snapshot.obj();
+		DEBUG_CODE(MDBID_LDBG_ << "snapshotGetDatasetForProducerKey findOne ---------------------------------------------";)
+		DEBUG_CODE(MDBID_LDBG_ << "condition" << q;)
+		DEBUG_CODE(MDBID_LDBG_ << "snapshotGetDatasetForProducerKey findOne ---------------------------------------------";)
+		
+		//update and waith until the data is on the server
+		if((err = ha_connection_pool->findOne(result, MONGO_DB_COLLECTION_NAME(db_name, MONGO_DB_COLLECTION_SNAPSHOT_DATA), q))) {
+			MDBID_LERR_ << "Errore finding the snapshot "<< snapshot_name << " for the unique key "<< producer_unique_key <<"with error "<<err;
+		} else {
+			std::string channel_unique_key = producer_unique_key+dataset_type;
+			if(result.hasField(channel_unique_key)) {
+				//! get data
+				mongo::BSONObj channel_data_obj = result.getObjectField(channel_unique_key);
+				if((channel_data_size = channel_data_obj.objsize())) {
+					*channel_data = malloc(channel_data_size);
+					if(*channel_data) {
+						std::memcpy(*channel_data, (void*)channel_data_obj.objdata(), channel_data_size);
+					}
+				}
+			}
+		}
+	} catch( const mongo::DBException &e ) {
+		MDBID_LERR_ << e.what();
+		err = -1;
+	}
+	return 0;
 }
 
 //! Delete a snapshot where no job is working
@@ -950,10 +983,9 @@ int MongoDBDriver::snapshotDeleteWithName(const std::string& snapshot_name) {
 	try{
 		//search for snapshot name and producer unique key
 		search_snapshot << MONGO_DB_FIELD_SNAPSHOT_DATA_SNAPSHOT_NAME << snapshot_name;
-
+		
 		mongo::BSONObj q = search_snapshot.obj();
 		DEBUG_CODE(MDBID_LDBG_ << "snapshotDeleteWithName count ---------------------------------------------";)
-
 		DEBUG_CODE(MDBID_LDBG_ << "condition" << q;)
 		DEBUG_CODE(MDBID_LDBG_ << "snapshotDeleteWithName count ---------------------------------------------";)
 		
diff --git a/ChaosSnapshotUtility/main.cpp b/ChaosSnapshotUtility/main.cpp
index 237c3962c..19cd6ffdd 100644
--- a/ChaosSnapshotUtility/main.cpp
+++ b/ChaosSnapshotUtility/main.cpp
@@ -25,13 +25,14 @@
 #include <chaos/ui_toolkit/LowLevelApi/LLRpcApi.h>
 #include <chaos/ui_toolkit/HighLevelApi/HLDataApi.h>
 
-#define OPT_CU_ID			"device-id"
-#define OPT_CDS_ADDRESS	"cds-address"
-#define OPT_SNAP_NAME		"snapshot-name"
-#define OPT_SNAPSHOT_OP	"op"
-
+#define OPT_CU_ID				"device-id"
+#define OPT_CDS_ADDRESS			"cds-address"
+#define OPT_SNAP_NAME			"snapshot-name"
+#define OPT_SNAPSHOT_OP			"op"
+#define OPT_SNAPSHOT_DS_TYPE	"dataset_type"
 using namespace chaos;
 using namespace chaos::ui;
+using namespace chaos::common::data;
 
 int main(int argc, char * argv[]) {
 	int64_t err = 0;
@@ -39,12 +40,14 @@ int main(int argc, char * argv[]) {
 	std::vector<std::string> device_id_list;
 	std::string snap_name;
 	std::string cds_addr;
+	uint32_t ds_type;
 	unsigned int operation;
 	try{
 		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption<std::string>(OPT_CDS_ADDRESS, "CDS address", &cds_addr);
 		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption< std::vector<std::string> >(OPT_CU_ID, "The identification string of the device to snapshuot", &device_id_list);
 		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption<std::string>(OPT_SNAP_NAME, "The name of the snapshot", &snap_name);
-		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption<unsigned int>(OPT_SNAPSHOT_OP, "Operation on snapshot [create(0), delete(1)]", 0, &operation);
+		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption<unsigned int>(OPT_SNAPSHOT_OP, "Operation on snapshot [create(0), delete(1), get(2)]", 0, &operation);
+		ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->addOption<unsigned int>(OPT_SNAPSHOT_DS_TYPE, "Dataset type [output(0), input(1), custom(2), system(3)]", 0, &ds_type);
 		
 		ChaosUIToolkit::getInstance()->init(argc, argv);
 		//! [UIToolkit Init]
@@ -55,27 +58,78 @@ int main(int argc, char * argv[]) {
 		if(!ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->hasOption(OPT_SNAP_NAME)){
 			throw CException(-2, "Invalid snapshot name set", "check param");
 		}
-		
-		if(!snap_name.size()) throw CException(-3, "Snapshot name can't zero-length", "check param");
+		if(!ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->hasOption(OPT_SNAPSHOT_OP)){
+			throw CException(-3, "Invalid operation set", "check param");
+		}
+		if(!snap_name.size()) throw CException(-4, "Snapshot name can't zero-length", "check param");
 		
 		SystemApiChannel *system_api_channel = LLRpcApi::getInstance()->getSystemApiClientChannel(cds_addr);
+		if(!system_api_channel) throw CException(-5, "Invalid system api channel instance", "getSystemApiClientChannel");
 		
 		chaos::common::direct_io::channel::opcode_headers::DirectIOSystemAPISnapshotResultPtr system_api_result = NULL;
-		
-		//!make snap on device
-		if(!(err = system_api_channel->system_api_channel->makeNewDatasetSnapshot(snap_name,
-																			device_id_list,
-																			&system_api_result))){
-			if(system_api_result) {
-				std::cout << "Snapshot creation report: " << std::endl;
-				std::cout << "Error code:" << system_api_result->error << std::endl;
-				std::cout << "Error message:" << system_api_result->error_message << std::endl;
-				free(system_api_result);
-			} else {
-				std::cout << "no result received" << std::endl;
+		switch(operation) {
+			case 0:{//new
+				//!make snap on device
+				if(!(err = system_api_channel->system_api_channel->makeNewDatasetSnapshot(snap_name,
+																						  device_id_list,
+																						  &system_api_result))){
+					if(system_api_result) {
+						std::cout << "Snapshot creation report: " << std::endl;
+						std::cout << "Error code:" << system_api_result->error << std::endl;
+						std::cout << "Error message:" << system_api_result->error_message << std::endl;
+						free(system_api_result);
+					} else {
+						std::cout << "no result received" << std::endl;
+					}
+				} else {
+					std::cout << "Error executing directio call" << std::endl;
+				}
+				break;
+			}
+			case 1:{//delete
+				if(!(err = system_api_channel->system_api_channel->deleteDatasetSnapshot(snap_name,
+																						 &system_api_result))){
+					if(system_api_result) {
+						std::cout << "Snapshot delete report: " << std::endl;
+						std::cout << "Error code:" << system_api_result->error << std::endl;
+						std::cout << "Error message:" << system_api_result->error_message << std::endl;
+						free(system_api_result);
+					} else {
+						std::cout << "no result received" << std::endl;
+					}
+				} else {
+					std::cout << "Error executing directio call" << std::endl;
+				}
+				break;
+			}
+			case 2:{//get
+				if(device_id_list.size()!=1) throw CException(-6, "For get oepration only a single producer key is required", "Get snapshot dataset operation");
+				if(!ChaosUIToolkit::getInstance()->getGlobalConfigurationInstance()->hasOption(OPT_SNAPSHOT_DS_TYPE)){
+					throw CException(-7, "The type of dataset is mandatory in get operation", "Get dataset from snapshot");
+				}
+				chaos::common::direct_io::channel::opcode_headers::DirectIOSystemAPIGetDatasetSnapshotResultPtr get_system_api_result = NULL;
+				if(!(err = system_api_channel->system_api_channel->getDatasetSnapshotForProducerKey(snap_name,
+																									device_id_list[0],
+																									ds_type,
+																									&get_system_api_result))){
+					if(get_system_api_result) {
+						std::cout << "Snapshot delete report: " << std::endl;
+						std::cout << "Error code:" << get_system_api_result->api_result.error << std::endl;
+						std::cout << "Error message:" << get_system_api_result->api_result.error_message << std::endl;
+						if(get_system_api_result->channel_data) {
+							auto_ptr<CDataWrapper> data(new CDataWrapper(((char*)get_system_api_result+sizeof(chaos::common::direct_io::channel::opcode_headers::DirectIOSystemAPISnapshotResult) + 4)));
+							std::cout << "Data found-------------------------"<< std::endl;
+							std::cout << data->getJSONString() << std::endl;
+						}
+						free(get_system_api_result);
+					} else {
+						std::cout << "no result received" << std::endl;
+					}
+				} else {
+					std::cout << "Error executing directio call" << std::endl;
+				}
+				break;
 			}
-		} else {
-			std::cout << "Error executing directio call" << std::endl;
 		}
 		
 		if(system_api_channel) {
diff --git a/chaos/common/direct_io/channel/DirectIODeviceChannelGlobal.h b/chaos/common/direct_io/channel/DirectIODeviceChannelGlobal.h
index 661191acf..3f5bed71a 100644
--- a/chaos/common/direct_io/channel/DirectIODeviceChannelGlobal.h
+++ b/chaos/common/direct_io/channel/DirectIODeviceChannelGlobal.h
@@ -223,7 +223,7 @@ namespace chaos {
 					
 					//-----------------------------------SYSTEM CHANNEL--------------------------------
 #pragma mark System Channel
-#define SYSTEM_API_CHANNEL_NEW_Snapshot 256+4
+#define SYSTEM_API_CHANNEL_NEW_Snapshot 256+4+4
 
 					//! Header for the snapshot system api managment for new, delete and get managment
 					/*!
@@ -240,6 +240,10 @@ namespace chaos {
 						struct header {
 							//!is the snapshot name
 							char		snap_name[256];
+							
+							//! the type of channel
+							uint32_t	channel_type;
+							
 							//! is the lenght of comma separated list of the
 							//! producer to include on the snapshot, if it is
 							//! empty all the producer are snapped. The list is
@@ -262,13 +266,10 @@ namespace chaos {
 						DirectIOSystemAPISnapshotResult api_result;
 						
 						//channels lenght
-						uint32_t output_channel_len;
-						uint32_t input_channel_len;
-						uint32_t custom_channel_len;
-						uint32_t system_channel_len;
+						uint32_t channel_len;
 						
 						//!concatenated channels data in order [o,i,c,s]
-						void* channels_data;
+						void* channel_data;
 					}DirectIOSystemAPIGetDatasetSnapshotResult,
 					*DirectIOSystemAPIGetDatasetSnapshotResultPtr;
                 }
diff --git a/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.cpp b/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.cpp
index b1eed03c2..1cb78b8b6 100644
--- a/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.cpp
+++ b/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.cpp
@@ -148,6 +148,7 @@ int64_t DirectIOSystemAPIClientChannel::deleteDatasetSnapshot(const std::string&
 //! get the snapshot for one or more producer key
 int64_t DirectIOSystemAPIClientChannel::getDatasetSnapshotForProducerKey(const std::string& snapshot_name,
 																		 const std::string& producer_key,
+																		 uint32_t channel_type,
 																		 DirectIOSystemAPIGetDatasetSnapshotResult **api_result_handle) {
 	int64_t err = 0;
 	DirectIOSynchronousAnswer *answer = NULL;
@@ -167,6 +168,7 @@ int64_t DirectIOSystemAPIClientChannel::getDatasetSnapshotForProducerKey(const s
 	
 	//copy the snapshot name to the header
 	std::memcpy(get_snapshot_opcode_header->field.snap_name, snapshot_name.c_str(), snapshot_name.size());
+	get_snapshot_opcode_header->field.channel_type = channel_type;
 	
 	//set header
 	DIRECT_IO_SET_CHANNEL_HEADER(data_pack, get_snapshot_opcode_header, sizeof(DirectIOSystemAPIChannelOpcodeNDGSnapshotHeader))
@@ -187,7 +189,7 @@ int64_t DirectIOSystemAPIClientChannel::getDatasetSnapshotForProducerKey(const s
 		if(answer && answer->answer_data) free(answer->answer_data);
 	} else {
 		//we got answer
-		if(answer && answer->answer_size == sizeof(DirectIOSystemAPISnapshotResult)) {
+		if(answer) {
 			*api_result_handle  = static_cast<DirectIOSystemAPIGetDatasetSnapshotResult*>(answer->answer_data);
 			(*api_result_handle)->api_result.error = FROM_LITTLE_ENDNS_NUM(int32_t, (*api_result_handle)->api_result.error);
 		} else {
diff --git a/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.h b/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.h
index 87bc2ac4e..780cf7529 100644
--- a/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.h
+++ b/chaos/common/direct_io/channel/DirectIOSystemAPIClientChannel.h
@@ -78,10 +78,12 @@ namespace chaos {
 					 Retrieve the dataset form the snapshot for one or more producer key.
 					 Is possible to decide the type of the snapshot to get
 					 \param snapshot_name the name of the snapshot to delete
+					 \param channel_type the type of the channel [0-output, 1-input, 2-custom, 3-system]]
 					 \param producer_key the key of the producer for wich return the datasets
 					 */
 					int64_t getDatasetSnapshotForProducerKey(const std::string& snapshot_name,
 															 const std::string& producer_key,
+															 uint32_t channel_type,
 															 DirectIOSystemAPIGetDatasetSnapshotResult **api_result_handle);
 				};
 			}
diff --git a/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.cpp b/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.cpp
index 5bea5ea04..f8c375713 100644
--- a/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.cpp
+++ b/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.cpp
@@ -87,27 +87,38 @@ int DirectIOSystemAPIServerChannel::consumeDataPack(DirectIODataPack *dataPack,
 			
 		case opcode::SystemAPIChannelOpcodeGetSnapshotDatasetForAKey: {
 			std::string producer_key;
-			//set the answer pointer
-			synchronous_answer->answer_data = std::calloc(sizeof(DirectIOSystemAPIGetDatasetSnapshotResult), 1);
-			synchronous_answer->answer_size = sizeof(DirectIOSystemAPIGetDatasetSnapshotResult);
+			void *channel_found_data = NULL;
+			uint32_t channel_found_data_length = 0;
 			
 			//get the header
+			DirectIOSystemAPIGetDatasetSnapshotResult *result_data = (DirectIOSystemAPIGetDatasetSnapshotResult*)std::calloc(sizeof(DirectIOSystemAPIGetDatasetSnapshotResult), 1);
 			opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeaderPtr header = reinterpret_cast< opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeaderPtr >(dataPack->channel_header_data);
 			header->field.producer_key_set_len = FROM_LITTLE_ENDNS_NUM(uint32_t, header->field.producer_key_set_len);
 			
 			//chec if a producere key has been forwarded
-			if(!dataPack->header.channel_data_size) {
+			if(dataPack->header.channel_data_size) {
 				//set error
 				producer_key.assign((const char*)dataPack->channel_data, dataPack->header.channel_data_size);
 				//delete the memory where is located producer key
 				free(dataPack->channel_data);
 			}
 			
-			
 			//call the handler
 			handler->consumeGetDatasetSnapshotEvent(header,
 													producer_key,
-													(DirectIOSystemAPIGetDatasetSnapshotResult*)synchronous_answer->answer_data);
+													&channel_found_data,
+													channel_found_data_length,
+													&result_data->api_result);
+			//set the answer pointer
+			if(channel_found_data) {
+				//whe have data to return
+				result_data = (DirectIOSystemAPIGetDatasetSnapshotResult*)std::realloc(result_data, (synchronous_answer->answer_size = (channel_found_data_length+sizeof(DirectIOSystemAPIGetDatasetSnapshotResult))));
+				synchronous_answer->answer_data = result_data;
+
+				std::memcpy(((char*)result_data+sizeof(DirectIOSystemAPISnapshotResult)+4), channel_found_data, channel_found_data_length);
+				((DirectIOSystemAPIGetDatasetSnapshotResult*)synchronous_answer->answer_data)->channel_len = channel_found_data_length;
+				free(channel_found_data);
+			}
 			//fix endianes into api result
 			((DirectIOSystemAPIGetDatasetSnapshotResult*)synchronous_answer->answer_data)->api_result.error =
 			TO_LITTE_ENDNS_NUM(int32_t, ((DirectIOSystemAPIGetDatasetSnapshotResult*)synchronous_answer->answer_data)->api_result.error);
diff --git a/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.h b/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.h
index 2f1d3101a..1bad177a8 100644
--- a/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.h
+++ b/chaos/common/direct_io/channel/DirectIOSystemAPIServerChannel.h
@@ -80,7 +80,9 @@ namespace chaos {
 						 */
 						virtual int consumeGetDatasetSnapshotEvent(opcode_headers::DirectIOSystemAPIChannelOpcodeNDGSnapshotHeader *header,
 																   const std::string& producer_id,
-																   DirectIOSystemAPIGetDatasetSnapshotResult *api_result)
+																   void **channel_found_data,
+																   uint32_t& channel_found_data_length,
+																   DirectIOSystemAPISnapshotResult *api_result)
 						{DELETE_HEADER(header) return 0;};
 					} DirectIOSystemAPIServerChannelHandler;
 					
-- 
GitLab