diff --git a/alib2measurepp/makefile.conf b/alib2measurepp/makefile.conf index 5bf8758b713dbd36168c3ce344c7c1cde17927e5..878ce29f7a4e46b11283cbeee906dc9bb9ce46ea 100644 --- a/alib2measurepp/makefile.conf +++ b/alib2measurepp/makefile.conf @@ -1,5 +1,5 @@ LIBRARY:=alib2measurepp TESTBIN:=alib2test LINK_PATHS=../alib2common/ ../alib2std/ -LINK_LIBRARIES=alib2common alib2std xml2 +LINK_LIBRARIES=alib2common alib2std xml2 rt INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/ diff --git a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp index 5a5b8e0cc3dcf5c30f5de0abec2bb925d250b813..7e859ba784bac23af87a747c954f63dc77b64988 100644 --- a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp +++ b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp @@ -73,11 +73,16 @@ void MeasurementProvisioner::prepareEnvironment ( const MeasurementProvisionerCo MPRPipelineResults MeasurementProvisioner::runPipeline ( const MPPipeline & pipeline, const MPSubstitutionMap & substitutionMap ) { - int measurementsTmpfileFd = open ( "/tmp", O_RDWR | O_TMPFILE, S_IRUSR | S_IWUSR ); - int measurementsFd = measurementsTmpfileFd; + MPUtils::ShmFileHandle measurementsTmpfile; - if ( measurementsTmpfileFd == -1 ) + try { + measurementsTmpfile = MPUtils::openShmFile ( ); + } catch ( ::exception::CommonException & ) { throw::exception::CommonException ( "MeasurementProvisioner: Cannot make measurements tmp file" ); + } + + int measurementsTmpfileFd = measurementsTmpfile.first; + int measurementsFd = measurementsTmpfileFd; // reserve fd 5 for measurements if ( measurementsFd != 5 ) @@ -86,20 +91,19 @@ MPRPipelineResults MeasurementProvisioner::runPipeline ( const MPPipeline & pipe if ( measurementsFd == -1 ) throw::exception::CommonException ( "MeasurementProvisioner: Cannot open measurements file descriptor" ); - int inputTmpfileFd = open ( "/tmp", O_RDWR | O_TMPFILE, S_IRUSR | S_IWUSR ); - int outputTmpfileFd = open ( "/tmp", O_RDWR | O_TMPFILE, S_IRUSR | S_IWUSR ); - int errorTmpfileFd = open ( "/tmp", O_RDWR | O_TMPFILE, S_IRUSR | S_IWUSR ); - - if ( ( inputTmpfileFd == -1 ) || ( outputTmpfileFd == -1 ) || ( errorTmpfileFd == -1 ) ) { - if ( inputTmpfileFd != -1 ) close ( inputTmpfileFd ); - - if ( outputTmpfileFd != -1 ) close ( outputTmpfileFd ); - - if ( errorTmpfileFd != -1 ) close ( errorTmpfileFd ); - + MPUtils::ShmFileHandle inputTmpfile, outputTmpfile, errorTmpfile; + try { + inputTmpfile = MPUtils::openShmFile ( ); + outputTmpfile = MPUtils::openShmFile ( ); + errorTmpfile = MPUtils::openShmFile ( ); + } catch ( ::exception::CommonException & ) { throw::exception::CommonException ( "MeasurementProvisioner: Cannot make io tmp files" ); } + int inputTmpfileFd = inputTmpfile.first; + int outputTmpfileFd = outputTmpfile.first; + int errorTmpfileFd = errorTmpfile.first; + // store handles to stdin, stdout, stderr, we will need to restore them later int curStdinFd = dup ( 0 ); int curStdoutFd = dup ( 1 ); @@ -182,12 +186,12 @@ MPRPipelineResults MeasurementProvisioner::runPipeline ( const MPPipeline & pipe // close tmp files, which results in their deletion if ( measurementsFd != measurementsTmpfileFd ) - close ( measurementsTmpfileFd ); + close ( measurementsFd ); - close ( measurementsFd ); - close ( inputTmpfileFd ); - close ( outputTmpfileFd ); - close ( errorTmpfileFd ); + MPUtils::closeShmFile ( measurementsTmpfile.second ); + MPUtils::closeShmFile ( inputTmpfile.second ); + MPUtils::closeShmFile ( outputTmpfile.second ); + MPUtils::closeShmFile ( errorTmpfile.second ); // restore our main stdin, stdout, stderr close ( 0 ); diff --git a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp index f05c2afc2ff6ea913338072dbf294266eb1bc037..45cf0a6f6031fae968807a19da8b8820f0c947ac 100644 --- a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp +++ b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.cpp @@ -7,6 +7,11 @@ #include <wordexp.h> #include <unistd.h> #include <iostream> +#include <random> +#include <string> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> namespace provisioner { @@ -26,31 +31,58 @@ std::list < std::string > MPUtils::shellExpand ( const std::string & str ) { return results; } -std::string MPUtils::generateTmpfileFromCommand ( const std::string & command ) { - char temppath[] = "/tmp/genXXXXXX"; +std::string MPUtils::randomFilename ( ) { + static std::string randomSeed = std::to_string ( std::random_devices::semirandom ( ) ); + static int randomOrder = 0; + + return randomSeed + "_" + std::to_string ( randomOrder++ ); +} + +MPUtils::ShmFileHandle MPUtils::openShmFile ( ) { + + std::string filename = "/" + randomFilename ( ); + + int shmFd = shm_open ( filename.c_str ( ), O_RDWR | O_CREAT, S_IRWXU ); + + if ( shmFd == -1 ) + throw::exception::CommonException ( "MPUtils: shm_open failed" ); - int tempfd = mkstemp ( temppath ); + filename = "/dev/shm" + filename; - if ( tempfd == -1 ) - throw::exception::CommonException ( "MPUtils: mkstemp failed" ); + if ( access ( filename.c_str ( ), F_OK ) == -1 ) + throw::exception::CommonException ( "MPUtils: can't create shm file in: " + filename ); + + return { + shmFd, std::move ( filename ) + }; +} + +void MPUtils::closeShmFile ( const std::string & shmFilepath ) { + if ( unlink ( shmFilepath.c_str ( ) ) == -1 ) + throw::exception::CommonException ( "MPUtils: can't unlink shm file in: " + shmFilepath ); +} + +std::string MPUtils::generateTmpfileFromCommand ( const std::string & command ) { + ShmFileHandle tempShmFile = openShmFile ( ); int stdoutfd = dup ( 1 ); + close ( 1 ); - dup ( tempfd ); + dup ( tempShmFile.first ); int status = system ( command.c_str ( ) ); close ( 1 ); - close ( tempfd ); + close ( tempShmFile.first ); dup ( stdoutfd ); close ( stdoutfd ); if ( WEXITSTATUS ( status ) != 0 ) { - unlink ( temppath ); + closeShmFile ( tempShmFile.second ); throw::exception::CommonException ( "MPUtils: system call failed" ); } - return std::string ( temppath ); + return tempShmFile.second; } } diff --git a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.hpp b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.hpp index 40c45598377538d510bf8b6278dc450eadf9d04f..10b6e590899d8bed8c61ab04a0ab6a71751c177d 100644 --- a/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.hpp +++ b/alib2measurepp/src/provisioner/MeasurementProvisionerUtils.hpp @@ -13,6 +13,13 @@ namespace provisioner { class MPUtils { public: static std::list < std::string > shellExpand ( const std::string & ); + + static std::string randomFilename ( ); + + using ShmFileHandle = std::pair < int, std::string >; + static ShmFileHandle openShmFile ( ); + static void closeShmFile ( const std::string & ); + static std::string generateTmpfileFromCommand ( const std::string & ); }; diff --git a/alib2measurepp/test-src/provisioner/provisionerTest.cpp b/alib2measurepp/test-src/provisioner/provisionerTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59ec551264c53f6dd9c195d1dc909205a575d7de --- /dev/null +++ b/alib2measurepp/test-src/provisioner/provisionerTest.cpp @@ -0,0 +1,29 @@ +#include "provisionerTest.h" +#include "provisioner/MeasurementProvisionerUtils.hpp" + +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/fcntl.h> + +#define CPPUNIT_IMPLY( x, y ) CPPUNIT_ASSERT ( !( x ) || ( y ) ) + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( provisionerTest, "provisioner" ); +CPPUNIT_TEST_SUITE_REGISTRATION ( provisionerTest ); + +void provisionerTest::setUp ( ) { +} + +void provisionerTest::tearDown ( ) { +} + +void provisionerTest::testMPUtils ( ) { + + std::cout << provisioner::MPUtils::randomFilename ( ) << std::endl; + std::cout << provisioner::MPUtils::randomFilename ( ) << std::endl; + + auto res = provisioner::MPUtils::openShmFile ( ); + + std::cout << res.first << ' ' << res.second << std::endl; + + provisioner::MPUtils::closeShmFile ( res.second ); +} diff --git a/alib2measurepp/test-src/provisioner/provisionerTest.h b/alib2measurepp/test-src/provisioner/provisionerTest.h new file mode 100644 index 0000000000000000000000000000000000000000..597fda3bd80dd37e1021eb77a38a4a375bdc4c34 --- /dev/null +++ b/alib2measurepp/test-src/provisioner/provisionerTest.h @@ -0,0 +1,18 @@ +#ifndef PROVISIONER_TEST_H_ +#define PROVISIONER_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class provisionerTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE ( provisionerTest ); + CPPUNIT_TEST ( testMPUtils ); + CPPUNIT_TEST_SUITE_END ( ); + +public: + void setUp ( ); + void tearDown ( ); + + void testMPUtils ( ); +}; + +#endif // PROVISIONER_TEST_H_ diff --git a/ameasure2/makefile.conf b/ameasure2/makefile.conf index 6559871443c32ec96e01b1729d300f43ecd7bdeb..250e9981b8dc1b8bc6bd1f1f26250fc6718fc8ef 100644 --- a/ameasure2/makefile.conf +++ b/ameasure2/makefile.conf @@ -1,4 +1,4 @@ EXECUTABLE:=ameasure2 LINK_PATHS=../alib2measurepp/ ../alib2common/ ../alib2std/ -LINK_LIBRARIES=alib2measurepp alib2common alib2std xml2 +LINK_LIBRARIES=alib2measurepp alib2common alib2std xml2 rt INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2measurepp/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/ diff --git a/ameasurep2/makefile.conf b/ameasurep2/makefile.conf index 6d9c783e90cf148f7aa5afc1bebb6cf3e6c96c65..ea704000809e6819ad87e779ca5a9d837eaf2185 100644 --- a/ameasurep2/makefile.conf +++ b/ameasurep2/makefile.conf @@ -1,4 +1,4 @@ EXECUTABLE:=ameasurep2 LINK_PATHS=../alib2measurepp/ ../alib2common/ ../alib2std/ -LINK_LIBRARIES=alib2measurepp alib2common alib2std xml2 +LINK_LIBRARIES=alib2measurepp alib2common alib2std xml2 rt INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2measurepp/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/