diff --git a/CMakeLists.txt b/CMakeLists.txt index ad7536c0841cad156334f581497398cdd06098fd..d7d847b6f54f901ee0069216fcbc55aa35d65e88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ FIND_PACKAGE(MX) FIND_PACKAGE(OpenMX) FIND_PACKAGE(Dolphin) FIND_PACKAGE(NDS2Client) -FIND_PACKAGE(Boost COMPONENTS system) +FIND_PACKAGE(Boost COMPONENTS filesystem system) FIND_PACKAGE(RapidJSON) FIND_PACKAGE(RPC) FIND_PACKAGE(libcds-pubsub) diff --git a/NEWS b/NEWS index ada64cd4423e7446bd520e34bb641c9a28b4d5ad..d5efae48c517095a86bbf78d986503c1a865b63f 100644 --- a/NEWS +++ b/NEWS @@ -17,9 +17,16 @@ Changes for 4.0 (NOT YET RELEASED) - Implemented a standalone_edc. - An edcu as a regular program, not a non-rt model. - Can record data into multiple types (short, int, float, double) -- Implemented fix for FRX 13791 +- Implemented fix for FRS 13791 - Increase the number of connections allowed on a daqd circular buffer past 32. - Generalize the data structure to allow changing the max number easier. Currently set to 128. +- Updated the nds process + - run dir defaults to /var/run/nds + - the name of the socket has changed from pipe to daqd_socket + - the command line is changed to specifying the run dir instead of the pipe/socket filename + - ie nds --rundir /var/run/nds + - gives a jobs dir of /var/run/nds/jobs and a socket at /var/run/nds/daqd_socket + - the nds process will attempt to create the 'jobs' directory if it does not exist ================================================================================================== Changes for 3.6 (NOT YET RELEASED) ================================================================================================== diff --git a/src/daqd/daqd.hh b/src/daqd/daqd.hh index 58b21a1ae2159e4bf155c232cfdaf5017074216b..81e54385ca760dd3ee39d4a55559370fa961b44a 100644 --- a/src/daqd/daqd.hh +++ b/src/daqd/daqd.hh @@ -227,6 +227,12 @@ private: parameter_set _params; public: + static std::string + default_nds_jobs_dir( ) + { + return "/var/run/nds"; + } + daqd_c( ) : _configuration_number( 0 ), b1( 0 ), producer1( 0 ), num_channels( 0 ), num_active_channels( 0 ), @@ -245,8 +251,9 @@ public: shutting_down( 0 ), num_listeners( 0 ), block_size( 0 ), thread_stack_size( 10 * 1024 * 1024 ), config_file_name( 0 ), offline_disabled( 0 ), profile( (char*)"main" ), - do_scan_frame_reads( 0 ), fsd( 1 ), science_fsd( 1 ), nds_jobs_dir( ), - detector_name( "" ), detector_prefix( "" ), detector_longitude( 0. ), + do_scan_frame_reads( 0 ), fsd( 1 ), science_fsd( 1 ), + nds_jobs_dir( default_nds_jobs_dir( ) ), detector_name( "" ), + detector_prefix( "" ), detector_longitude( 0. ), detector_latitude( 0. ), detector_elevation( .0 ), detector_arm_x_azimuth( .0 ), detector_arm_y_azimuth( .0 ), detector_arm_x_altitude( .0 ), detector_arm_y_altitude( .0 ), diff --git a/src/daqd/net_writer.cc b/src/daqd/net_writer.cc index b3930dc0416f9a76672b7e00d3cc9c4b130660b4..fc374b4a5895f7efe7a7b6a5984395f00ca6c50e 100644 --- a/src/daqd/net_writer.cc +++ b/src/daqd/net_writer.cc @@ -81,7 +81,7 @@ net_writer_c::send_files( void ) sprintf( jobn_buf, "%ld", job_num ); string spec_filename = daqd.nds_jobs_dir + "/jobs/" + jobn_buf; string pipe = daqd.nds_jobs_dir + - "/pipe"; // unix domain socket communication endpoint + "/daqd_socket"; // unix domain socket communication endpoint // connect UNIX socket on pipe int socketfd; @@ -516,8 +516,8 @@ net_writer_c::producer( ) &prop ); // cerr << "net_writer_c::producer(): put() of " << - //source_buffptr -> block_prop (nb) -> bytes << " bytes" << - //endl; + // source_buffptr -> block_prop (nb) -> bytes << " bytes" << + // endl; if ( nb16th == 0xf ) break; } @@ -552,8 +552,8 @@ net_writer_c::producer( ) &prop ); // cerr << "net_writer_c::producer(): put() of " << - //source_buffptr -> block_prop (nb) -> bytes << " bytes" << - //endl; + // source_buffptr -> block_prop (nb) -> bytes << " bytes" << + // endl; } source_buffptr->unlock( cnum ); } @@ -700,7 +700,7 @@ net_writer_c::consumer( ) dec_vec[ i ].vec_bps / dec_vec[ i ].vec_rate; // DEBUG1(cerr << //"net_writer_c::consumer(decimation): averaging " << - //samples_per_point << " samples" << endl); + // samples_per_point << " samples" << endl); DEBUG1( cerr << "net_writer_c::consumer(decimation) decimating" << samples_per_point << " samples" << endl ); diff --git a/src/daqd/tests/test_daqd_nds.sh.in b/src/daqd/tests/test_daqd_nds.sh.in index 272b41d7adeb08487bdc2d02ebbc718917e6060f..258101a9050d13cb7bb627f7ce089fc6a8794440 100644 --- a/src/daqd/tests/test_daqd_nds.sh.in +++ b/src/daqd/tests/test_daqd_nds.sh.in @@ -82,7 +82,7 @@ mkdir "$TDIR/logs" mkdir "$TDIR/frames" mkdir "$TDIR/frames/full" mkdir "$TDIR/frames/nds" -mkdir "$TDIR/frames/nds/jobs" +#mkdir "$TDIR/frames/nds/jobs" echo "Ini dir = $TDIR/ini_files" @@ -103,7 +103,7 @@ PID_DAQD=$! sleep 5 echo "Starting the nds service" -"$NDS" "$TDIR/frames/nds/pipe" > "$TDIR/logs/nds" & +"$NDS" --rundir "$TDIR/frames/nds" > "$TDIR/logs/nds" & PID_NDS=$! echo "Sleeping to allow the daq to finish startup" diff --git a/src/nds/CMakeLists.txt b/src/nds/CMakeLists.txt index 5bb7e777d67503b534e73d13aa965fb2051e8e11..356a947811e5176936ee2620d0ca7bd68586cf9b 100644 --- a/src/nds/CMakeLists.txt +++ b/src/nds/CMakeLists.txt @@ -51,8 +51,12 @@ target_include_directories(nds PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/framelib/src ${CMAKE_CURRENT_SOURCE_DIR}/framelib/src/zlib ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${Boost_INCLUDE_DIRS} ) -target_link_libraries(nds PRIVATE ldastools::framecpp) +target_link_libraries(nds PRIVATE + args + ldastools::framecpp + ${Boost_LIBRARIES}) install(TARGETS nds DESTINATION bin) diff --git a/src/nds/main.cc b/src/nds/main.cc index 437c8f21d09c112708029fc0082095e6eac55903..cf7b8315de0c5d6d805d0d7cfcaa06b64e272b4d 100644 --- a/src/nds/main.cc +++ b/src/nds/main.cc @@ -1,14 +1,34 @@ #include <stdio.h> #include <stdlib.h> #include <iostream> +#include <sstream> #include <unistd.h> #include "nds.hh" -//#include "framecpp/dictionary.hh" +#include "args.h" + +#include <boost/filesystem.hpp> using namespace CDS_NDS; +namespace fs = boost::filesystem; -std::string programname; // Set to the program's executable name during run time +struct NDSConfigOpts +{ + fs::path run_dir{}; + fs::path log_path{}; + bool exit{ false }; + fs::path + socket_path( ) const + { + return run_dir / "daqd_socket"; + } + + fs::path + jobs_dir( ) const + { + return run_dir / "jobs"; + }; +}; // // Set log level 2 in the production system // @@ -18,53 +38,95 @@ int nds_log_level = 4; // Controls volume of log messages int _debug = 4; // Controls volume of the debugging messages that is printed out #endif -// FrameCPP::Dictionary *dict = FrameCPP::library.getCurrentVersionDictionary(); -// +NDSConfigOpts +parse_args( int argc, char* argv[] ) +{ + NDSConfigOpts opts; + + const char* log_dest = nullptr; + const char* run_dir = nullptr; + const char* default_run_dir = "/var/run/nds"; + + auto arg_parser = args_create_parser( + "The archive data retrieval service for daqd data" ); + args_add_string_ptr( arg_parser, + 'l', + ARGS_NO_LONG, + "filename", + "Send log information to the given file", + &log_dest, + nullptr ); + args_add_string_ptr( + arg_parser, + 'd', + "rundir", + "path", + "Directory that the jobs dir and daqd_socket reside in", + &run_dir, + default_run_dir ); + opts.exit = ( args_parse( arg_parser, argc, argv ) < 1 ); + args_destroy( &arg_parser ); + + opts.run_dir = run_dir; + opts.log_path = ( log_dest ? log_dest : "" ); + return opts; +} void -usage( int c ) +setup_logging( const std::string& programname, const NDSConfigOpts& opts ) { - system_log( 1, "nds usage: nds [-l logfilename ] <pipe file name>" ); - exit( c ); + openlog( programname.c_str( ), LOG_PID | LOG_CONS, LOG_USER ); + if ( !opts.log_path.empty( ) ) + { + FILE* f = freopen( opts.log_path.c_str( ), "w", stdout ); + setvbuf( stdout, NULL, _IOLBF, 0 ); + stderr = stdout; + } } -int -parse_args( int argc, char* argv[] ) +void +ensure_jobs_dir( const NDSConfigOpts& opts ) { - int c; - extern char* optarg; - extern int optind; + namespace fs = boost::filesystem; - while ( ( c = getopt( argc, argv, "Hhl:" ) ) != -1 ) + fs::path jobs_dir = opts.jobs_dir( ); + if ( fs::exists( jobs_dir ) ) { - FILE* f; - switch ( c ) + if ( fs::is_directory( jobs_dir ) ) { - case 'H': - case 'h': - usage( 0 ); - break; - case 'l': - f = freopen( optarg, "w", stdout ); - setvbuf( stdout, NULL, _IOLBF, 0 ); - stderr = stdout; - break; - default: - usage( 1 ); + return; } + std::ostringstream os; + os << "The jobs directory '" << jobs_dir + << "' exists and is not a directory"; + throw std::runtime_error( os.str( ) ); } - return optind; + std::cout << "The jobs directory does not exist, attempting to create '" + << jobs_dir << "'" << std::endl; + fs::create_directories( jobs_dir ); } int main( int argc, char* argv[] ) { - programname = Nds::basename( argv[ 0 ] ); - openlog( programname.c_str( ), LOG_PID | LOG_CONS, LOG_USER ); - int optind = parse_args( argc, argv ); - if ( argc != optind + 1 ) - usage( 1 ); - Nds nds( argv[ optind ] ); + auto opts = parse_args( argc, argv ); + if ( opts.exit ) + { + return 1; + } + + std::string programname = Nds::basename( argv[ 0 ] ); + setup_logging( programname, opts ); + + std::string socket_path = opts.socket_path( ).string( ); + std::cout << "NDS server starting\nRun dir = " << opts.run_dir; + std::cout << "\nSocket path = " << socket_path; + std::cout << "\nJobs dir = " << opts.jobs_dir( ) << std::endl; + + fs::current_path( opts.run_dir ); + ensure_jobs_dir( opts ); + + Nds nds( socket_path ); int res = nds.run( ); return res; }