Skip to content

Commit

Permalink
Merge pull request #287 from sy-c/master
Browse files Browse the repository at this point in the history
v2.27.0
  • Loading branch information
sy-c authored Jan 21, 2025
2 parents 3b75a2f + eb3d0ff commit 1d57ee0
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 33 deletions.
9 changes: 7 additions & 2 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,13 @@ General settings are defined in section `[readout]`.
Section names ending with `-*` can be used to define default parameters. They are applied to all section with similar names. Existing key-value pairs are not overwritten, but are defined according to defaults if they don't exist. For example, it is possible to define the TFperiod for all equipments by adding a section named `[equipment-*]` with `TFperiod=32`.

Values can be symbolic links to a value stored in another configuration file. The syntax is: @LINK,URI,entryPoint,path
For example: @LINK,file:/local/readout-test-config-link1.cfg,,bank.size
Parameters are similar to the command-line arguments of o2-readout-exe, see ```Usage``` below.
The URI can be absolute (file:, consul-ini://) or relative (./, ../) to the current configuration URI used by o2-readout-exe (whatever the backend).
For example:
- @LINK,file:/local/readout-test-config-link1.cfg,,bank.size
- @LINK,consul-ini://alio2-cr1-hv-mvs00.cern.ch:8500/o2/components/readout/ANY/any/readout-global-params,,bank.size
- @LINK,./readout-test-config-link1.cfg,,bank.size
- @LINK,../readout-test-config-link1.cfg,,bank.size
Parameters URI and entryPoint are similar to the command-line arguments of o2-readout-exe, see ```Usage``` below.
Files are cached, i.e. the corresponding configuration tree is loaded only once if several values use a link to the same URI/entryPoint.
Links substitutions are done at the end of the configuration tree aggregation (sections merging, etc).
It is done recursively (up to 5 iterations, after which it fails to avoid circular dependencies).
Expand Down
4 changes: 4 additions & 0 deletions doc/releaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -648,3 +648,7 @@ This file describes the main feature changes for each readout.exe released versi

## v2.26.3 - 22/10/2024
- Minor release for osx compatibility.

## v2.27.0 - 21/01/2024
- Added symbolic links with relative path in configuration. See @LINK syntax.
- Fixed o2-readout-config-generator for RHEL9 compatibility.
48 changes: 48 additions & 0 deletions src/ReadoutUtils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,51 @@ void setThreadName(const char* name) {
(void)name;
#endif
}


// @brief Splits a URI string into its scheme and the rest of the URI.
//
// This function parses a given URI and separates it into two parts:
// 1. The scheme (including the colon and double slashes if present)
// 2. The rest of the URI
//
// The function handles the following cases:
// - URIs with "://" (e.g., "http://", "consul-ini://")
// - URIs with only ":" (e.g., "file:")
// - File URIs with varying numbers of slashes (e.g., "file:", "file:/", "file:///")
// - URIs without a scheme
//
// @param uri The input URI string to be split.
// @return A std::pair where:
// - first: The scheme part of the URI (including ":" or "://")
// - second: The rest of the URI after the scheme
// If no scheme is found, first will be empty and second will contain the entire input string.
//
// @note The function does not validate the URI format beyond identifying the scheme.
// It assumes the input is a well-formed URI string.
//
// @example
// auto [scheme, rest] = splitURI("http://example.com");
// // scheme = "http://", rest = "example.com"
//
// auto [scheme, rest] = splitURI("file:///path/to/file");
// // scheme = "file://", rest = "/path/to/file"
//
// This code was generated with the assistance of GitLab Duo Chat, an AI-powered coding assistant.

std::pair<std::string, std::string> splitURI(const std::string& uri) {
constexpr std::string_view double_slash = "://";
auto double_slash_pos = uri.find(double_slash);
if (double_slash_pos != std::string::npos) {
std::string scheme = uri.substr(0, double_slash_pos + double_slash.length());
std::string rest = uri.substr(double_slash_pos + double_slash.length());
return {std::move(scheme), std::move(rest)};
}
auto single_colon_pos = uri.find(':');
if (single_colon_pos != std::string::npos) {
std::string scheme = uri.substr(0, single_colon_pos + 1);
std::string rest = uri.substr(single_colon_pos + 1);
return {std::move(scheme), std::move(rest)};
}
return {"", uri}; // No scheme found, return empty scheme and the whole string as rest
}
6 changes: 6 additions & 0 deletions src/ReadoutUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include <stdint.h>
#include <string>
#include <vector>
#include <string_view>
#include <utility>


#include "RAWDataHeader.h"

Expand Down Expand Up @@ -85,6 +88,9 @@ int numaGetNodeFromAddress(void *ptr, int &node);
// function to set a name for current thread
void setThreadName(const char*name);

// function to split string into URI / path
std::pair<std::string, std::string> splitURI(const std::string& uri);

// end of _READOUTUTILS_H
#endif

2 changes: 1 addition & 1 deletion src/ReadoutVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#define READOUT_VERSION "2.26.3"
#define READOUT_VERSION "2.27.0"

14 changes: 13 additions & 1 deletion src/mainReadout.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ int Readout::_configure(const boost::property_tree::ptree& properties)
std::vector<ConfigCache> cfgCache;
int nSubstitutions = 0;
std::function<void(boost::property_tree::ptree &, const std::string &)> resolveLinks;
resolveLinks = [&resolveLinks, &cfgLinksErrors, &cfgCache, &loadConfig, &nSubstitutions](boost::property_tree::ptree &pt, const std::string &key) -> void {
resolveLinks = [&resolveLinks, &cfgLinksErrors, &cfgCache, &loadConfig, &nSubstitutions, this](boost::property_tree::ptree &pt, const std::string &key) -> void {
if (pt.empty()) {
std::string value = pt.data();
const std::string keywordLink = "@LINK";
Expand All @@ -952,6 +952,18 @@ int Readout::_configure(const boost::property_tree::ptree& properties)
const char* cfgLinkUri = linkArgs[1].c_str();
const char* cfgLinkEntryPoint = linkArgs[2].c_str();
const char* cfgLinkPath = linkArgs[3].c_str();

// check if link URI starts with a relative path - and if so, compute address from current URI
// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
// theLog.log(LogInfoSupport, "Resolving %s / %s", cfgFileURI, cfgLinkUri);
std::string resolvedUri;
if (!strncmp(cfgLinkUri, "../", 3) || !strncmp(cfgLinkUri, "./", 2)) {
std::pair<std::string, std::string> splitPath = splitURI(cfgFileURI);
resolvedUri = splitPath.first + std::filesystem::path((std::filesystem::path(splitPath.second).parent_path().string() + "/" + cfgLinkUri)).lexically_normal().string();
theLog.log(LogInfoSupport, "Using relative path: %s -> %s", cfgLinkUri, resolvedUri.c_str());
cfgLinkUri = resolvedUri.c_str();
}

// search for file in cache
unsigned int ix = 0;
for(;ix < cfgCache.size(); ix++) {
Expand Down
42 changes: 13 additions & 29 deletions src/readoutAutoConfigure.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -152,28 +152,17 @@ if {[llength $ldev]==0} {
}

# get memory configuration

if {[catch {set hugeOutput [exec hugeadm --pool-list]} err]} {
doLog "hugeadm failed: $err"
exit 1
}
set hugeOutputLines [split $hugeOutput "\n"]
set nHuge1G 0
set nHuge1Gfile "/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages"
if {[catch {
set hugeHeader "Size Minimum Current Maximum Default"
if {[string trim [lindex $hugeOutputLines 0]]!=$hugeHeader} {
# throw only in tcl 8.7... but if not it generates an error anyway, which is what we want
throw
}
for {set i 1} {$i<[llength $hugeOutputLines]} {incr i} {
set l [lindex $hugeOutputLines $i]
set size [string trim [string range $l 0 11]]
set min [string trim [string range $l 12 20]]
set current [string trim [string range $l 21 29]]
set max [string trim [string range $l 30 38]]
lappend lmem "$size" "$current"
set nHugeFd [open $nHuge1Gfile "r"]
gets $nHugeFd line
close $nHugeFd
if {[scan $line "%d" nHuge1G]!=1} {
doLog "Failed to parse $nHuge1Gfile"
}
} err]} {
doLog "Failed to parse hugeadm output: $err"
doLog "Failed to get number of hugepages: $err"
}


Expand Down Expand Up @@ -202,9 +191,10 @@ if {[catch {
throw
}
set l [lindex $memOutputLines 1]
set memTotal [string trim [string range $l 7 18]]
set memUsed [string trim [string range $l 19 30]]
set memFree [string trim [string range $l 31 42]]
set theWords [regexp -all -inline {\S+} $l]
set memTotal [lindex $theWords 1]
set memUsed [lindex $theWords 2]
set memFree [lindex $theWords 3]
} err]} {
doLog "Failed to parse free output: $err"
}
Expand All @@ -226,13 +216,7 @@ if {$numaNodes==0} {
}

doLog "Memory available (hugepages):"
set nHuge1G 0
foreach {pageSize pagesAvailable} $lmem {
doLog " $pagesAvailable * $pageSize bytes"
if {$pageSize==1073741824} {
set nHuge1G $pagesAvailable
}
}
doLog " $nHuge1G * 1048576kB"
if {$nHuge1G==0} {
doLog "1G pages should not be zero"
incr err
Expand Down

0 comments on commit 1d57ee0

Please sign in to comment.