diff --git a/.gitignore b/.gitignore index 58eae60023b9f2e2e18e81d6f2a940735a0d68a5..ba2a5fce5df810bbe49706397f5f1d473bcaadc9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ Makefile .version maestro-core-*/ maestro-core-*.tar.gz +maestro-*/ +maestro-*.tar.gz *\# TAGS tags @@ -104,3 +106,4 @@ tests/check_subscribe_local tests/subscribe-archiver.c tests/check_cdo_selectors /tests/check_memlock +MaestroConfig.cmake diff --git a/MaestroConfig.cmake.in b/MaestroConfig.cmake.in new file mode 100644 index 0000000000000000000000000000000000000000..7e1e7f7e507fc53b8e4dbf909692667dea279b5c --- /dev/null +++ b/MaestroConfig.cmake.in @@ -0,0 +1,35 @@ +# +# Copyright (C) 2021 HPE Computer GmbH +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +set(PREFIX @prefix@) + +set(Maestro_INCLUDE_DIRS ${PREFIX}/include/maestro) +set(Maestro_LIBRARIES ${PREFIX}/lib/libmaestro.a) diff --git a/Makefile.am b/Makefile.am index 6362694845fdd2fe933c805726a729822e103c11..14faf1158dcd005478ecb50df51853ce54e6854d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,6 +65,10 @@ libmaestro_la_LIBADD = \ # README dist_doc_DATA = README.md +# CMake package +cmakepackagedir = $(libdir)/cmake/maestro/ +cmakepackage_DATA = MaestroConfig.cmake + if WITH_FREQUENT_TAGS all-local: TAGS tags endif diff --git a/attributes/maestro-schema.c b/attributes/maestro-schema.c index eb7db7b9ffd700ff7178db840caba1575ab50269..d08fe67b7095cf03bfb267215d1e911b40864504 100644 --- a/attributes/maestro-schema.c +++ b/attributes/maestro-schema.c @@ -2516,7 +2516,8 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, } if(copy_value) { - status = mstro_attribute_val__compute_size(entry->kind, NULL, val, &entry->valsize); + status = mstro_attribute_val__compute_size(entry->kind, NULL, + val, &entry->valsize); if(status!=MSTRO_OK) { ERR("Cannot compute value size\n"); goto BAILOUT; @@ -2709,7 +2710,18 @@ mstro_attribute_entry_to_mapentry(const struct mstro_attribute_entry_ *entry, case MSTRO_STP_STR: case MSTRO_STP_REGEX: res->val->val_case = MSTRO__POOL__AVAL__VAL_STRING; - res->val->string = (char *)entry->val; + /* we need to duplicate strings, since the deallocation of + * protobuf messages descends into char* members, and so the + * entry in the dictionary where the entry is will be invalid + * when the message is deallocated (or vice versa) */ + res->val->string = strdup((char *)entry->val); + if(res->val->string==NULL) { + ERR("Failed to allocat string value for KV entry\n"); + free(res->val); + free(res); + s=MSTRO_NOMEM; + goto BAILOUT; + } break; case MSTRO_STP_BLOB: res->val->val_case = MSTRO__POOL__AVAL__VAL_BYTES; diff --git a/build-envs/README b/build-envs/README index 234f7a826822a05acc1bf23e885adc30771bf6ba..e48c4ffd8d92db5ad508ee37fa278c4cdf285b75 100644 --- a/build-envs/README +++ b/build-envs/README @@ -25,6 +25,13 @@ Running things by hand $ docker pull registry.gitlab.com/cerl/maestro/maestro-core/buildenv/debian $ docker run --ulimit memlock=133000:133000 -i -t registry.gitlab.com/cerl/maestro/maestro-core/buildenv/debian /bin/bash + + # but since you're reading this, you may be interested in debugging. In that + # case, to permit gdb to work inside the docker container you might want to + # use + # docker run --cap-add=SYS_PTRACE --ulimit memlock=133000:133000 -i -t registry.gitlab.com/cerl/maestro/maestro-core/buildenv/debian /bin/bash + # instead + # now you have a shell in the docker container that is currently used on gitlab for CI $ mkdir /builds $ cd /builds diff --git a/build/clang/Makefile b/build/clang/Makefile deleted file mode 100644 index 907900239586445b6d24a684d690bc33a8d3785b..0000000000000000000000000000000000000000 --- a/build/clang/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -CC=clang -CFLAGS_D=-O0 -g2 -Wall -CFLAGS_R=-O2 -Wall -DNDEBUG -LDFLAGS_D= -LDFLAGS_R= - -SRCDIR=../../src -TMPDIR_D=tmp/debug -TMPDIR_R=tmp/release -BINDIR_D=bin/debug -BINDIR_R=bin/release - -EXAMPLES:=$(patsubst $(SRCDIR)/examples/%.peg,examples/%,$(wildcard $(SRCDIR)/examples/*.peg)) - -BINS= \ - $(BINDIR_D)/packcc \ - $(BINDIR_R)/packcc \ - $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \ - $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES)) -SRCS= \ - $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES)) - -.PHONY: all clean - -.SECONDARY: $(SRCS) - -all: $(BINS) - -$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c - mkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D) - -$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c - mkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R) - -$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h - mkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D) - -$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h - mkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R) - -$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(SRCDIR)/examples/%.peg $(BINDIR_D)/packcc - mkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $< - -$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(SRCDIR)/examples/%.peg $(BINDIR_R)/packcc - mkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $< - -clean: - rm -f $(BINS) $(SRCS) diff --git a/build/gcc/Makefile b/build/gcc/Makefile deleted file mode 100644 index eb6e4893328f3e5e5a65d33fc870d205abd73a1c..0000000000000000000000000000000000000000 --- a/build/gcc/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -CC=gcc -CFLAGS_D=-O0 -g2 -Wall -CFLAGS_R=-O2 -Wall -DNDEBUG -LDFLAGS_D= -LDFLAGS_R= - -SRCDIR=../../src -TMPDIR_D=tmp/debug -TMPDIR_R=tmp/release -BINDIR_D=bin/debug -BINDIR_R=bin/release - -EXAMPLES:=$(patsubst $(SRCDIR)/examples/%.peg,examples/%,$(wildcard $(SRCDIR)/examples/*.peg)) - -BINS= \ - $(BINDIR_D)/packcc \ - $(BINDIR_R)/packcc \ - $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \ - $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES)) -SRCS= \ - $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \ - $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES)) - -.PHONY: all clean - -.SECONDARY: $(SRCS) - -all: $(BINS) - -$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c - mkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D) - -$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c - mkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R) - -$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h - mkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D) - -$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h - mkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R) - -$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(SRCDIR)/examples/%.peg $(BINDIR_D)/packcc - mkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $< - -$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(SRCDIR)/examples/%.peg $(BINDIR_R)/packcc - mkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $< - -clean: - rm -f $(BINS) $(SRCS) diff --git a/build/msvc/examples/calc/calc.vcxproj b/build/msvc/examples/calc/calc.vcxproj deleted file mode 100644 index a586bbb58eb05f56f7951f3644101f8e3f98ec6c..0000000000000000000000000000000000000000 --- a/build/msvc/examples/calc/calc.vcxproj +++ /dev/null @@ -1,210 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="..\..\..\..\src\examples\calc.peg"> - <FileType>Document</FileType> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)tmp\$(PlatformTarget)\$(Configuration)\%(Filename).c;%(Outputs)</Outputs> - <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects> - <OutputItemType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ClCompile</OutputItemType> - <TreatOutputAsContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatOutputAsContent> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)tmp\$(PlatformTarget)\$(Configuration)\%(Filename).c;%(Outputs)</Outputs> - <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects> - <OutputItemType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ClCompile</OutputItemType> - <TreatOutputAsContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</TreatOutputAsContent> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)tmp\$(PlatformTarget)\$(Configuration)\%(Filename).c;%(Outputs)</Outputs> - <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects> - <OutputItemType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ClCompile</OutputItemType> - <TreatOutputAsContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatOutputAsContent> - <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)tmp\$(PlatformTarget)\$(Configuration)\%(Filename).c;%(Outputs)</Outputs> - <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects> - <OutputItemType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ClCompile</OutputItemType> - <TreatOutputAsContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatOutputAsContent> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild> - <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DeploymentContent> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> - <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DeploymentContent> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild> - <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DeploymentContent> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild> - <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DeploymentContent> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformTarget)\$(Configuration)\packcc -o tmp\$(PlatformTarget)\$(Configuration)\%(Filename) %(FullPath)</Command> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(PlatformTarget)\$(Configuration)\packcc -o tmp\$(PlatformTarget)\$(Configuration)\%(Filename) %(FullPath)</Command> - <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(PlatformTarget)\$(Configuration)\packcc -o tmp\$(PlatformTarget)\$(Configuration)\%(Filename) %(FullPath)</Command> - <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(PlatformTarget)\$(Configuration)\packcc -o tmp\$(PlatformTarget)\$(Configuration)\%(Filename) %(FullPath)</Command> - </CustomBuild> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>16.0</VCProjectVersion> - <ProjectGuid>{5EB5881F-0182-4E32-A3E8-6940E5016770}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>calc</RootNamespace> - <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> - <ProjectName>calc</ProjectName> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(ProjectDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - <TargetName>$(ProjectName)</TargetName> - <IncludePath>.\;$(IncludePath)</IncludePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(ProjectDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - <TargetName>$(ProjectName)</TargetName> - <IncludePath>.\;$(IncludePath)</IncludePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(ProjectDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - <TargetName>$(ProjectName)</TargetName> - <IncludePath>.\;$(IncludePath)</IncludePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(ProjectDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - <TargetName>$(ProjectName)</TargetName> - <IncludePath>.\;$(IncludePath)</IncludePath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - <PreBuildEvent> - <Command> - </Command> - </PreBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file diff --git a/build/msvc/examples/calc/calc.vcxproj.filters b/build/msvc/examples/calc/calc.vcxproj.filters deleted file mode 100644 index 7c4e44f391f148b650560ac64f9fbfc5bb1614ae..0000000000000000000000000000000000000000 --- a/build/msvc/examples/calc/calc.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="..\..\..\..\src\examples\calc.peg"> - <Filter>Source Files</Filter> - </CustomBuild> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/build/msvc/examples/calc/calc.vcxproj.user b/build/msvc/examples/calc/calc.vcxproj.user deleted file mode 100644 index 0f14913f3c72094bb7b1e695e153ade04b17d5b0..0000000000000000000000000000000000000000 --- a/build/msvc/examples/calc/calc.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup /> -</Project> \ No newline at end of file diff --git a/build/msvc/msvc.sln b/build/msvc/msvc.sln deleted file mode 100644 index 97f234da09bc5df82b98dc459f0efd972f141f90..0000000000000000000000000000000000000000 --- a/build/msvc/msvc.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29209.62 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "packcc", "packcc.vcxproj", "{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "calc", "examples\calc\calc.vcxproj", "{5EB5881F-0182-4E32-A3E8-6940E5016770}" - ProjectSection(ProjectDependencies) = postProject - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C} = {9A1A5538-7127-4B2F-9C82-3282A69F3C9C} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{16C15CF5-EA71-4DEB-A758-CC52E0CA2558}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x64.ActiveCfg = Debug|x64 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x64.Build.0 = Debug|x64 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x86.ActiveCfg = Debug|Win32 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x86.Build.0 = Debug|Win32 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x64.ActiveCfg = Release|x64 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x64.Build.0 = Release|x64 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x86.ActiveCfg = Release|Win32 - {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x86.Build.0 = Release|Win32 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x64.ActiveCfg = Debug|x64 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x64.Build.0 = Debug|x64 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x86.ActiveCfg = Debug|Win32 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x86.Build.0 = Debug|Win32 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x64.ActiveCfg = Release|x64 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x64.Build.0 = Release|x64 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x86.ActiveCfg = Release|Win32 - {5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {5EB5881F-0182-4E32-A3E8-6940E5016770} = {16C15CF5-EA71-4DEB-A758-CC52E0CA2558} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {BD6C24C6-47A2-40C5-87E8-F72C92F9D5FF} - EndGlobalSection -EndGlobal diff --git a/build/msvc/packcc.vcxproj b/build/msvc/packcc.vcxproj deleted file mode 100644 index ee0441d064d1145ba42059281a852fdbbcc73859..0000000000000000000000000000000000000000 --- a/build/msvc/packcc.vcxproj +++ /dev/null @@ -1,175 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>16.0</VCProjectVersion> - <ProjectGuid>{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>packcc</RootNamespace> - <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(SolutionDir)$(PlatformTarget)\$(Configuration)\</OutDir> - <IntDir>$(PlatformTarget)\$(Configuration)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <DisableLanguageExtensions>true</DisableLanguageExtensions> - <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\..\src\packcc.c" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file diff --git a/build/msvc/packcc.vcxproj.filters b/build/msvc/packcc.vcxproj.filters deleted file mode 100644 index 3de6784b22e987f2fe74ba443358ce53648d5688..0000000000000000000000000000000000000000 --- a/build/msvc/packcc.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\src\packcc.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/build/msvc/packcc.vcxproj.user b/build/msvc/packcc.vcxproj.user deleted file mode 100644 index 0f14913f3c72094bb7b1e695e153ade04b17d5b0..0000000000000000000000000000000000000000 --- a/build/msvc/packcc.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup /> -</Project> \ No newline at end of file diff --git a/configure.ac b/configure.ac index 8a029a626991cf1710feab7a83dd65da2cbffd03..d0243cd30d83fc04733da09bc838fab245f6490c 100644 --- a/configure.ac +++ b/configure.ac @@ -58,9 +58,18 @@ dnl silent automake requires version 1.11 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -AC_ARG_ENABLE([libnuma], - AS_HELP_STRING([--disable-libnuma], - [Disable the Linux libnuma])) +AC_ARG_ENABLE([numa], + [AS_HELP_STRING([--enable-numa],[Disable libnuma usage (default: use if detected)])], + [enable_numa=$enableval],[enable_numa=yes]) +AS_IF([test "x$enable_numa" = xyes], + [AC_CHECK_HEADERS([numa.h numaif.h], + [AC_CHECK_LIB([numa],[numa_available], + AC_DEFINE([HAVE_NUMA]) + LIBS="-lnuma $LIBS") + have_numa=yes], + [have_numa=no])]) +AM_CONDITIONAL([NUMA_ENABLED], [test "x$have_numa" = "xyes"]) +AC_SUBST([NUMA_ENABLED], [$have_numa]) AC_CONFIG_SRCDIR([maestro/version.c]) AX_CHECK_ENABLE_DEBUG() @@ -115,7 +124,6 @@ AC_COMPILE_IFELSE( [AC_MSG_NOTICE([C compiler understands C11 well])], [AC_MSG_ERROR([C compiler does not handle constant initializers to structures, not fully C11 compatible])]) - dnl check for code-coverage option. This needs to stay at the start of checks AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], @@ -536,6 +544,7 @@ AC_CONFIG_FILES([ deps/libyaml/src/Makefile deps/libcyaml/Makefile deps/c-timestamp/Makefile + MaestroConfig.cmake ]) dnl AC_SUBST does not preserve executable bit on scripts, so do diff --git a/include/maestro/attributes.h b/include/maestro/attributes.h index ecd390a637ccf41a8f81b082e0304f85cc8a6d21..0788c5d2b6f124f4d313a6694c2971dda7dcc31f 100644 --- a/include/maestro/attributes.h +++ b/include/maestro/attributes.h @@ -68,6 +68,15 @@ typedef struct mstro_attribute_dict_* mstro_cdo_attributes; Predefined symbolic key strings exist for the well-known attributes **/ +/**@brief maestro.core.cdo.name + ** + ** The name of the CDO + ** + ** C-side data type: `char *' + ** default value: false (set automatically by mstro_cdo_declare()) + **/ +extern const char *MSTRO_ATTR_CORE_CDO_NAME; + /**@brief maestro.core.cdo.allocate-now ** ** Indicate that Maestro should perform allocation before DECLARE completes diff --git a/include/maestro/env.h b/include/maestro/env.h index a6714bec111bbf7300a146b46cb7ade958808fe5..8129cba1f79033118804603a93a4708ec8065e14 100644 --- a/include/maestro/env.h +++ b/include/maestro/env.h @@ -206,7 +206,18 @@ /** - ** @brief Path to the MIO transport config file + ** @brief Directory for GFS transport + ** + ** Must be visible on all workflow components that want to use GFS + ** transport. Should be a high-performance global file system location. + ** + ** Default is "./", the directory where the application is started + ** (which will often work, but not always). + **/ +#define MSTRO_ENV_TRANSPORT_GFS_DIR "MSTRO_TRANSPORT_GFS_DIR" + +/** + ** @brief Path to the MIO transport config file ** ** This is needed to initialize MIO ** diff --git a/include/maestro/i_cdo.h b/include/maestro/i_cdo.h index d4e2fbd4203dee4eda01434746b401bca5126270..8200877e463b4c04c228329eded3f8d793f8949e 100644 --- a/include/maestro/i_cdo.h +++ b/include/maestro/i_cdo.h @@ -156,7 +156,14 @@ typedef uint32_t mstro_cdo_state; /** The NIL UUID */ #define MSTRO_CDO_ID_INVALID { .id = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 } } -/** return a string describing the CDO state @arg s */ +/** return a string describing the CDO state @arg s + ** + ** The string is owned by this function, but this function can safely + ** be called from multiple threads (the buffer is thread-local). The + ** buffer will be re-used by subsequent calls in the same thread + ** after a small number of invocations (currently: 3, see @ref + ** MAX_STATE_DESCRIPTION_BUFFERS). + **/ const char * mstro_cdo_state_describe(mstro_cdo_state s); @@ -321,6 +328,10 @@ struct mstro_cdo_ { char *name; /**< user-provided name */ + int preferred_numa_node; /**< the preferred NUMA node for this CDO. -1 + for don't care. Typically set from raw-ptr + or mamba-array information */ + /* Cached copies of the data attributes. Caching occirs at SEAL * time, after which the attribute setters will refuse chaning the * dictionary entries, so caching is safe */ diff --git a/include/maestro/i_globals.h b/include/maestro/i_globals.h index 60c432eb04abf1e235611fad00ba8ad2776796d0..62dfea09f968a521ffee23ea8c182b05a1cc48bc 100644 --- a/include/maestro/i_globals.h +++ b/include/maestro/i_globals.h @@ -111,6 +111,8 @@ extern Mstro__Pool__Appid g_pool_appid; /** the fundamental built-in attribute schema. Filled early in mstro_core_init(), then constant */ extern mstro_schema g_mstro_core_schema_instance; +/** flag set if numa is working */ +extern bool g_have_numa; /** flag set if we are connected to a pool manager service */ extern bool g_have_pool_manager; @@ -159,4 +161,12 @@ extern union mstro_component_descriptor g_component_descriptor; | (MSTRO_POOL_PROTOCOL_VERSION_MINOR << 8) \ | (MSTRO_POOL_PROTOCOL_VERSION_PATCH << 0))) + + +/** the precomputed default path for GFS transport (incl. trailing '/') */ +extern char *g_mstro_transport_gfs_dir; +/** string length of @ref g_mstro_transport_gfs_dir */ +extern size_t g_mstro_transport_gfs_dir_len; + + #endif /* MAESTRO_I_GLOBALS_H_ */ diff --git a/maestro/Makefile.am b/maestro/Makefile.am index 26b9feedcccab128d44ca5b7f9347932cd1197dd..e85e2723928c4a64a01f6db4e5aec1f2bef776ff 100644 --- a/maestro/Makefile.am +++ b/maestro/Makefile.am @@ -68,6 +68,7 @@ libmaestro_core_la_SOURCES = \ i_event.h event.c \ cdo_sel_parse.c cdo_sel_parse.h \ i_groups.h groups.c \ + i_maestro_numa.h \ memlock.c \ cdo-attributes-default.txt @@ -78,6 +79,10 @@ cdo_sel_parse.c cdo_sel_parse.h: cdo_sel_parse.peg libmaestro_core_la_LIBADD=$(top_builddir)/deps/libcyaml/libcyaml.la $(top_builddir)/deps/mamba/libmmb.la $(top_builddir)/deps/c-timestamp/libtimestamp.la +if NUMA_ENABLED +libmaestro_core_la_LIBADD+=-lnuma +endif + # Conductor implementation varies depending on configuration if WITH_OFI_POOL_MANAGER libmaestro_core_la_SOURCES+=pool_manager_ofi.c ofi.c drc.c diff --git a/maestro/attributes.c b/maestro/attributes.c index e9105e845c3564fbe1abd80ec21a919ae77a4b7b..8a3250ad128fbd37cab2f289edaf82a01de5ae32 100644 --- a/maestro/attributes.c +++ b/maestro/attributes.c @@ -50,6 +50,9 @@ /* FIXME: we should have a table of name/type/... and make the const * char* refer to the entries in that */ +const char *MSTRO_ATTR_CORE_CDO_NAME = + ".maestro.core.cdo.name"; + const char *MSTRO_ATTR_CORE_CDO_ALLOCATE_NOW = ".maestro.core.cdo.allocate-now"; diff --git a/maestro/cdo.c b/maestro/cdo.c index 37f25ccaacc2b9e92ac52866c76956aded77c3ec..15c2d4990328c3a8ac3b9f27b54c24ba746d8971 100644 --- a/maestro/cdo.c +++ b/maestro/cdo.c @@ -46,6 +46,7 @@ #include "maestro/status.h" #include "maestro/i_statistics.h" +#include "i_maestro_numa.h" #include "transformation/transformation.h" #include <mamba.h> @@ -144,6 +145,9 @@ mstro_cdo__alloc(void) } /* we need to zero out the hash-table relevant parts. For simplicity we zero everything */ memset(res, 0, sizeof(struct mstro_cdo_)); + + /* default: same region as handle is in */ + res->preferred_numa_node = mstro_numa__node_for_addr(res); /* initialize parts that need special handling */ atomic_init(&(res->state), MSTRO_CDO_STATE_INVALID); @@ -639,6 +643,47 @@ mstro_cdo_declaration_seal(mstro_cdo cdo) goto BAILOUT; } } + + /* Ensure a sane name is filled in. The attribute is, in fact, only + * needed for subscription handling (so users can match on names the + * same way that they can for other attributes). + * + * The user does not typically set the name attribute explicitly, + * but if they do we need to ensure it's not in disagreement with + * the name specified at mstro_cdo_declare() time. */ + const void *cdo_name_attrval=NULL; + enum mstro_cdo_attr_value_type valtype; + + mstro_status s_cdoname = mstro_attribute_dict_get( + cdo->attributes, MSTRO_ATTR_CORE_CDO_NAME, + &valtype, &cdo_name_attrval, NULL, false); + if(s_cdoname==MSTRO_OK || s_cdoname==MSTRO_NOENT) { + const char *n_cdo = mstro_cdo_name(cdo); + if(s_cdoname==MSTRO_OK) { + /* ok, already have a name, check it matches */ + const char *n_attr = (const char *)cdo_name_attrval; + + if(0!=strcmp(n_cdo,n_attr)) { + ERR("CDO |%s| has name attribute set to |%s|, overriding\n", + cdo->name, cdo_name_attrval); + } + } + + s_cdoname = mstro_attribute_dict_set(cdo->attributes, + MSTRO_ATTR_CORE_CDO_NAME, + MSTRO_CDO_ATTR_VALUE_cstring, + &n_cdo, true); + if(s_cdoname!=MSTRO_OK) { + ERR("Failed to set CDO name attribute: %d (%s)\n", s_cdoname, + mstro_status_description(s_cdoname)); + status = s_cdoname; + goto BAILOUT; + } + } else { + ERR("Failed to inquire about CDO name attribute\n"); + status = s_cdoname; + goto BAILOUT; + } /* we're done, but we need to ensure we've seen the DECLARE_ACK with * the global ID by now */ @@ -1592,29 +1637,43 @@ struct { /** a reasonably safe way to count the number of entries in an array of structures */ #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + +/** we support this many concurrent state buffers in flight per + * thread. Hideous, but callers typically will use this function in a + * PRINT statement, with up to two states (to compare them) at most + */ + +#define MAX_STATE_DESCRIPTION_BUFFERS 3 const char * mstro_cdo_state_describe(mstro_cdo_state s) { - static _Thread_local char buf[sizeof(states_and_names)]; + static _Thread_local char buf[MAX_STATE_DESCRIPTION_BUFFERS][sizeof(states_and_names)]; + static _Thread_local size_t bufid = 0; - buf[0]='\0'; + // switch to new buffer + bufid = (bufid+1) % MAX_STATE_DESCRIPTION_BUFFERS; + + buf[bufid][0]='\0'; if(s==MSTRO_CDO_STATE_INVALID) return "INVALID"; else { for(size_t i=0; i<COUNT_OF(states_and_names); i++) { if(s&states_and_names[i].state) { - strcat(buf, states_and_names[i].name); + strcat(buf[bufid], states_and_names[i].name); } } - return buf+1; /* cut off leading '|' we put there for simplicity + + return buf[bufid]+1; /* cut off leading '|' we put there for simplicity * of the loop above */ } } mstro_status -mstro_cdo_attributes_update_incoming(mstro_cdo cdo, const Mstro__Pool__Attributes *attr, - size_t num_precious_attr, const char **precious_attributes) +mstro_cdo_attributes_update_incoming(mstro_cdo cdo, + const Mstro__Pool__Attributes *attr, + size_t num_precious_attr, + const char **precious_attributes) { if(cdo==NULL || attr==NULL) return MSTRO_INVARG; diff --git a/maestro/cdo_sel_parse.c b/maestro/cdo_sel_parse.c index a8612ff82ebce2272e71cd7ef1ecf188618e4fdb..c6f1aa9215996e53817aa83f3e60c16cfca2cb2b 100644 --- a/maestro/cdo_sel_parse.c +++ b/maestro/cdo_sel_parse.c @@ -1429,7 +1429,23 @@ static void pcc_action_value_1(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pc static void pcc_action_value_2(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) { #define auxil (__pcc_ctx->auxil) #define __ (*__pcc_out) -#define i (*__pcc_in->data.leaf.values.buf[2]) +#define n (*__pcc_in->data.leaf.values.buf[2]) +#define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0) +#define _0s ((const)__pcc_in->data.leaf.capt0.range.start) +#define _0e ((const)__pcc_in->data.leaf.capt0.range.end) + __=n; DEBUG("numeric value\n"); +#undef _0e +#undef _0s +#undef _0 +#undef n +#undef __ +#undef auxil +} + +static void pcc_action_value_3(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) { +#define auxil (__pcc_ctx->auxil) +#define __ (*__pcc_out) +#define i (*__pcc_in->data.leaf.values.buf[3]) #define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0) #define _0s ((const)__pcc_in->data.leaf.capt0.range.start) #define _0e ((const)__pcc_in->data.leaf.capt0.range.end) @@ -1593,7 +1609,7 @@ static void pcc_action_string_0(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__p __=mstro_csq_val__alloc(MSTRO_CSQ_STRING); __->strval = strdup(_1); if(__->strval==NULL) { - ERR("Failed to allocate string value (for regex) parser node\n"); + ERR("Failed to allocate string value (for string) parser node\n"); abort(); } #undef _1e @@ -1618,7 +1634,7 @@ static void pcc_action_string_1(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__p __=mstro_csq_val__alloc(MSTRO_CSQ_STRING); __->strval = strdup(_2); if(__->strval==NULL) { - ERR("Failed to allocate string value (for regex) parser node\n"); + ERR("Failed to allocate string value (for string) parser node\n"); abort(); } #undef _2e @@ -1631,6 +1647,58 @@ static void pcc_action_string_1(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__p #undef auxil } +static void pcc_action_numeric_val_0(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) { +#define auxil (__pcc_ctx->auxil) +#define __ (*__pcc_out) +#define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0) +#define _0s ((const)__pcc_in->data.leaf.capt0.range.start) +#define _0e ((const)__pcc_in->data.leaf.capt0.range.end) +#define _1 pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[0]) +#define _1s __pcc_in->data.leaf.capts.buf[0]->range.start +#define _1e __pcc_in->data.leaf.capts.buf[0]->range.end + // signed integer, stored as string + __=mstro_csq_val__alloc(MSTRO_CSQ_STRING); + __->strval = strdup(_1); + if(__->strval==NULL) { + ERR("Failed to allocate string value (for integral) parser node\n"); + abort(); + } +#undef _1e +#undef _1s +#undef _1 +#undef _0e +#undef _0s +#undef _0 +#undef __ +#undef auxil +} + +static void pcc_action_numeric_val_1(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) { +#define auxil (__pcc_ctx->auxil) +#define __ (*__pcc_out) +#define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0) +#define _0s ((const)__pcc_in->data.leaf.capt0.range.start) +#define _0e ((const)__pcc_in->data.leaf.capt0.range.end) +#define _2 pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[1]) +#define _2s __pcc_in->data.leaf.capts.buf[1]->range.start +#define _2e __pcc_in->data.leaf.capts.buf[1]->range.end + // exponential notation + __=mstro_csq_val__alloc(MSTRO_CSQ_STRING); + __->strval = strdup(_2); + if(__->strval==NULL) { + ERR("Failed to allocate string value (for exponential numeric) parser node\n"); + abort(); + } +#undef _2e +#undef _2s +#undef _2 +#undef _0e +#undef _0s +#undef _0 +#undef __ +#undef auxil +} + static void pcc_action_space_0(mstro_csq_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) { #define auxil (__pcc_ctx->auxil) #define __ (*__pcc_out) @@ -1658,6 +1726,7 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_regex_i(mstro_csq_context_t *ctx); static pcc_thunk_chunk_t *pcc_evaluate_rule_identifier(mstro_csq_context_t *ctx); static pcc_thunk_chunk_t *pcc_evaluate_rule_simple_regex(mstro_csq_context_t *ctx); static pcc_thunk_chunk_t *pcc_evaluate_rule_string(mstro_csq_context_t *ctx); +static pcc_thunk_chunk_t *pcc_evaluate_rule_numeric_val(mstro_csq_context_t *ctx); static pcc_thunk_chunk_t *pcc_evaluate_rule_space(mstro_csq_context_t *ctx); static pcc_thunk_chunk_t *pcc_evaluate_rule_EOF(mstro_csq_context_t *ctx); @@ -2488,7 +2557,7 @@ L0000:; static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx->auxil); chunk->pos = ctx->pos; - pcc_value_table__resize(ctx->auxil, &chunk->values, 3); + pcc_value_table__resize(ctx->auxil, &chunk->values, 4); pcc_capture_table__resize(ctx->auxil, &chunk->capts, 0); { const int p = ctx->pos; @@ -2509,7 +2578,7 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { L0004:; } { - pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_0, 3, 0); + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_0, 4, 0); thunk->data.leaf.values.buf[0] = &(chunk->values.buf[0]); thunk->data.leaf.capt0.range.start = chunk->pos; thunk->data.leaf.capt0.range.end = ctx->pos; @@ -2535,7 +2604,7 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { L0007:; } { - pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_1, 3, 0); + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_1, 4, 0); thunk->data.leaf.values.buf[1] = &(chunk->values.buf[1]); thunk->data.leaf.capt0.range.start = chunk->pos; thunk->data.leaf.capt0.range.end = ctx->pos; @@ -2552,7 +2621,7 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { } L0009:; } - if (!pcc_apply_rule(ctx, pcc_evaluate_rule_identifier, &chunk->thunks, &(chunk->values.buf[2]))) goto L0008; + if (!pcc_apply_rule(ctx, pcc_evaluate_rule_numeric_val, &chunk->thunks, &(chunk->values.buf[2]))) goto L0008; { int i; for (i = 0;; i++) { @@ -2561,7 +2630,7 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { L0010:; } { - pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_2, 3, 0); + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_2, 4, 0); thunk->data.leaf.values.buf[2] = &(chunk->values.buf[2]); thunk->data.leaf.capt0.range.start = chunk->pos; thunk->data.leaf.capt0.range.end = ctx->pos; @@ -2569,6 +2638,32 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_value(mstro_csq_context_t *ctx) { } goto L0001; L0008:; + ctx->pos = p; + pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n); + { + int i; + for (i = 0;; i++) { + if (!pcc_apply_rule(ctx, pcc_evaluate_rule_space, &chunk->thunks, NULL)) goto L0012; + } + L0012:; + } + if (!pcc_apply_rule(ctx, pcc_evaluate_rule_identifier, &chunk->thunks, &(chunk->values.buf[3]))) goto L0011; + { + int i; + for (i = 0;; i++) { + if (!pcc_apply_rule(ctx, pcc_evaluate_rule_space, &chunk->thunks, NULL)) goto L0013; + } + L0013:; + } + { + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_value_3, 4, 0); + thunk->data.leaf.values.buf[3] = &(chunk->values.buf[3]); + thunk->data.leaf.capt0.range.start = chunk->pos; + thunk->data.leaf.capt0.range.end = ctx->pos; + pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk); + } + goto L0001; + L0011:; ctx->pos = p; pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n); goto L0000; @@ -2919,6 +3014,149 @@ L0000:; return NULL; } +static pcc_thunk_chunk_t *pcc_evaluate_rule_numeric_val(mstro_csq_context_t *ctx) { + pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx->auxil); + chunk->pos = ctx->pos; + pcc_value_table__resize(ctx->auxil, &chunk->values, 0); + pcc_capture_table__resize(ctx->auxil, &chunk->capts, 2); + { + const int p = ctx->pos; + const int n = chunk->thunks.len; + { + const int p = ctx->pos; + int q; + { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0003; + c = ctx->buffer.buf[ctx->pos]; + if (!( + c == '+' || + c == '-' + )) goto L0003; + ctx->pos++; + } + L0003:; + { + const int p = ctx->pos; + int i; + for (i = 0;; i++) { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0004; + c = ctx->buffer.buf[ctx->pos]; + if (!(c >= '0' && c <= '9')) goto L0004; + ctx->pos++; + } + L0004:; + if (i < 1) { + ctx->pos = p; + goto L0002; + } + } + q = ctx->pos; + chunk->capts.buf[0].range.start = p; + chunk->capts.buf[0].range.end = q; + } + { + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_numeric_val_0, 0, 2); + thunk->data.leaf.capts.buf[0] = &(chunk->capts.buf[0]); + thunk->data.leaf.capt0.range.start = chunk->pos; + thunk->data.leaf.capt0.range.end = ctx->pos; + pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk); + } + goto L0001; + L0002:; + ctx->pos = p; + pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n); + { + const int p = ctx->pos; + int q; + { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0005; + c = ctx->buffer.buf[ctx->pos]; + if (!( + c == '+' || + c == '-' + )) goto L0005; + ctx->pos++; + } + { + int i; + for (i = 0;; i++) { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0006; + c = ctx->buffer.buf[ctx->pos]; + if (!(c >= '0' && c <= '9')) goto L0006; + ctx->pos++; + } + L0006:; + } + if ( + pcc_refill_buffer(ctx, 1) < 1 || + ctx->buffer.buf[ctx->pos] != '.' + ) goto L0005; + ctx->pos++; + { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0005; + c = ctx->buffer.buf[ctx->pos]; + if (!( + c == 'E' || + c == 'e' + )) goto L0005; + ctx->pos++; + } + { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0007; + c = ctx->buffer.buf[ctx->pos]; + if (!( + c == '+' || + c == '-' + )) goto L0007; + ctx->pos++; + } + L0007:; + { + const int p = ctx->pos; + int i; + for (i = 0;; i++) { + char c; + if (pcc_refill_buffer(ctx, 1) < 1) goto L0008; + c = ctx->buffer.buf[ctx->pos]; + if (!(c >= '0' && c <= '9')) goto L0008; + ctx->pos++; + } + L0008:; + if (i < 1) { + ctx->pos = p; + goto L0005; + } + } + q = ctx->pos; + chunk->capts.buf[1].range.start = p; + chunk->capts.buf[1].range.end = q; + } + { + pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_numeric_val_1, 0, 2); + thunk->data.leaf.capts.buf[1] = &(chunk->capts.buf[1]); + thunk->data.leaf.capt0.range.start = chunk->pos; + thunk->data.leaf.capt0.range.end = ctx->pos; + pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk); + } + goto L0001; + L0005:; + ctx->pos = p; + pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n); + goto L0000; + L0001:; + } + return chunk; +L0000:; + pcc_thunk_chunk__destroy(ctx->auxil, chunk); + return NULL; +} + static pcc_thunk_chunk_t *pcc_evaluate_rule_space(mstro_csq_context_t *ctx) { pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx->auxil); chunk->pos = ctx->pos; @@ -2994,7 +3232,7 @@ void mstro_csq_destroy(mstro_csq_context_t *ctx) { #define MIN(x,y) ((x)<(y) ? (x) : (y)) -#line 358 "cdo_sel_parse.peg" +#line 370 "cdo_sel_parse.peg" void mstro_csq_val__describe(const struct mstro_csq_val *v, size_t indent) { diff --git a/maestro/cdo_sel_parse.peg b/maestro/cdo_sel_parse.peg index 8918fb0486af94ea7957b1f2027ab0e35d421146..8360d84e731726e0f8172c28d1cacf0d1b4d08b1 100644 --- a/maestro/cdo_sel_parse.peg +++ b/maestro/cdo_sel_parse.peg @@ -294,9 +294,10 @@ attribute_key <- ide:identifier { $$=ide; DEBUG("ide\n"); } # values will be stored as strings and parsed with type info later -value <- space* r:regex space* { $$=r; DEBUG("regex value\n");} - / space* s:string space* { $$=s; DEBUG("string value\n");} - / space* i:identifier space* { $$=i; DEBUG("ide value\n"); } +value <- space* r:regex space* { $$=r; DEBUG("regex value\n");} + / space* s:string space* { $$=s; DEBUG("string value\n");} + / space* n:numeric_val space* { $$=n; DEBUG("numeric value\n");} + / space* i:identifier space* { $$=i; DEBUG("ide value\n"); } regex <- r:regex_i { $$ = r; DEBUG("CI regex\n"); } / r:simple_regex { $$ = r; DEBUG("simple regex\n"); } @@ -337,7 +338,7 @@ string <- ["] < [^"]* > ["] { $$=mstro_csq_val__alloc(MSTRO_CSQ_STRING); $$->strval = strdup($1); if($$->strval==NULL) { - ERR("Failed to allocate string value (for regex) parser node\n"); + ERR("Failed to allocate string value (for string) parser node\n"); abort(); } } @@ -345,12 +346,29 @@ string <- ["] < [^"]* > ["] { $$=mstro_csq_val__alloc(MSTRO_CSQ_STRING); $$->strval = strdup($2); if($$->strval==NULL) { - ERR("Failed to allocate string value (for regex) parser node\n"); + ERR("Failed to allocate string value (for string) parser node\n"); abort(); } } - +numeric_val <- < [+-]?[0-9]+ > { + // signed integer, stored as string + $$=mstro_csq_val__alloc(MSTRO_CSQ_STRING); + $$->strval = strdup($1); + if($$->strval==NULL) { + ERR("Failed to allocate string value (for integral) parser node\n"); + abort(); + } + } + / < [+-][0-9]*[.][Ee][+-]?[0-9]+ > { + // exponential notation + $$=mstro_csq_val__alloc(MSTRO_CSQ_STRING); + $$->strval = strdup($2); + if($$->strval==NULL) { + ERR("Failed to allocate string value (for exponential numeric) parser node\n"); + abort(); + } + } ## isspace() space <- [ \t\n\v\f\r] { ; } @@ -366,7 +384,7 @@ EOF <- !. #define MIN(x,y) ((x)<(y) ? (x) : (y)) -#line 358 "cdo_sel_parse.peg" +#line 370 "cdo_sel_parse.peg" void mstro_csq_val__describe(const struct mstro_csq_val *v, size_t indent) { diff --git a/maestro/core.c b/maestro/core.c index 9d3d5477bf776aa40bdee1d5ad4932e3e64fb96d..accbf882ce442cf87ea08552cf5c417b5994b4c0 100644 --- a/maestro/core.c +++ b/maestro/core.c @@ -53,6 +53,10 @@ #include "maestro/i_state.h" #include "transport/transport.h" +#ifdef HAVE_NUMA_H +#include <numa.h> +#endif + /* simplify logging */ #define DEBUG(...) LOG_DEBUG(MSTRO_LOG_MODULE_CORE,__VA_ARGS__) @@ -80,6 +84,26 @@ mstro_i_destroy_initdata(void* initdata) return; } +static inline +mstro_status +mstro_core__numa_init(void) +{ +#ifdef HAVE_NUMA + g_have_numa = (numa_available()==-1 ? false : true); + if(g_have_numa) { + DEBUG("NUMA: available with %d/%d nodes, %d/%d cpus\n", + numa_num_task_nodes(), numa_num_configured_nodes(), + numa_num_task_cpus(), numa_num_configured_cpus()); + /* FIXME: consider initializing some global data structures with this info */ + } else { + DEBUG("NUMA: not available on system\n"); + } +#else + g_have_numa = false; + DEBUG("NUMA: not supported\n"); +#endif + return MSTRO_OK; +} static inline mstro_status @@ -307,7 +331,53 @@ mstro_core_init(const char *workflow_name, g_component_descriptor.component_name[MSTRO_WORKFLOW_NAME_MAX-1] = '\0'; strcpy(g_component_descriptor.version, mstro_version()); - + /* check GFS path setting */ + { + char *gfs_dir = getenv(MSTRO_ENV_TRANSPORT_GFS_DIR); + if(gfs_dir!=NULL) { + bool need_sep = false; + size_t l1 = strlen(gfs_dir); + assert(l1>0); + if(gfs_dir[l1-1]!='/') { + need_sep=true; + } + size_t l2 = strlen(data->workflow_name); + size_t l3 = strlen(data->component_name); + + g_mstro_transport_gfs_dir = malloc(l1 + (need_sep? 1 : 0) + + l2 + 1 + + l3 + 1 +1); + if(g_mstro_transport_gfs_dir==NULL) { + ERR("Failed to allocate GFS transport dir pathname\n"); + return MSTRO_NOMEM; + } + size_t pos = 0; + strcpy(g_mstro_transport_gfs_dir, gfs_dir); + pos += l1; + if(need_sep) { + g_mstro_transport_gfs_dir[pos] = '/'; + pos++; + } + strcpy(g_mstro_transport_gfs_dir+pos, data->workflow_name); + pos += l2; + + g_mstro_transport_gfs_dir[pos] = '/'; + pos++; + + strcpy(g_mstro_transport_gfs_dir+pos, data->component_name); + pos += l3; + g_mstro_transport_gfs_dir[pos] = '/'; + pos++; + g_mstro_transport_gfs_dir[pos] = '\0'; + g_mstro_transport_gfs_dir_len = pos; + assert(pos==strlen(g_mstro_transport_gfs_dir)); + + DEBUG("Set GFS transport directory to %s\n", + g_mstro_transport_gfs_dir); + } + } + + /*Reading and integrating attribute schemas*/ status = mstro_core_init__setup_schemata(); if(status!=MSTRO_OK) { goto BAILOUT; @@ -328,6 +398,12 @@ mstro_core_init(const char *workflow_name, } pthread_mutex_unlock(&g_initdata_mtx); + status = mstro_core__numa_init(); + if(status!=MSTRO_OK) { + ERR("Failed to initialize NUMA support infrastructure\n"); + goto BAILOUT; + } + status = mstro_core__mamba_init(); if(status!=MSTRO_OK) { goto BAILOUT; diff --git a/maestro/globals.c b/maestro/globals.c index 6bb1045630c41ba5f26cc102a81dcc186e80fa33..780928d3abbed2864bb55d7e7f01aa507d1fe4bd 100644 --- a/maestro/globals.c +++ b/maestro/globals.c @@ -85,3 +85,15 @@ mstro_schema g_mstro_core_schema_instance = NULL; bool g_have_pool_manager=false; union mstro_component_descriptor g_component_descriptor; + + +/** the precomputed default path for GFS transport (incl. trailing '/') */ +char *g_mstro_transport_gfs_dir = "./"; /* possibly overwritten at init + * time from env*/ + +/** string length of @ref g_mstro_transport_gfs_dir */ +size_t g_mstro_transport_gfs_dir_len = 2; /* possibly overwritten at + * init time */ + +/** NUMA supported and working? */ +bool g_have_numa = false; diff --git a/maestro/i_maestro_numa.h b/maestro/i_maestro_numa.h new file mode 100644 index 0000000000000000000000000000000000000000..001029f09d8b6c78e09cb0053be64f84ee9ca219 --- /dev/null +++ b/maestro/i_maestro_numa.h @@ -0,0 +1,88 @@ +/* -*- mode:c -*- */ +/** @file + ** @brief Maestro NUMA abstraction + **/ +/* + * Copyright (C) 2021 HPE Switzerland GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MAESTRO_I_NUMA_H_ +#define MAESTRO_I_NUMA_H_ 1 + +/**@addtogroup MSTRO_Internal + **@{ + **/ + +/**@defgroup MSTRO_I_NUMA Maestro NUMA abstraction + **@{ + ** + **/ + +#ifdef HAVE_NUMAIF_H +#include <numaif.h> +#endif + +#include "maestro/logging.h" + + +/** obtain node ID for a given address. + * + * Will always succeed, yielding '0' if NUMA is not supported or ID cannot be obtained */ +static inline +int +mstro_numa__node_for_addr(void * addr) +{ +#ifdef HAVE_NUMA + if(g_have_numa) { + int node = -1; + long s = get_mempolicy(&node, + NULL /* node mask */, + 0 /* max nodes in mask */, + addr, MPOL_F_NODE | MPOL_F_ADDR); + if(s<0) { + LOG_WARN(MSTRO_LOG_MODULE_CORE, + "Failed to obtain NUMA info for addr %p: %ld (%s)\n", + addr, s, strerror(-s)); + return 0; + } else { + return node; + } + } else { + return 0; + } +#else + return 0; +#endif +} +/**@} (end of group MSTRO_I_NUMA) */ +/**@} (end of group MSTRO_Internal) */ + +#endif /* MAESTRO_I_NUMA_H_ */ + diff --git a/maestro/pool.c b/maestro/pool.c index 201fc667c1b85f8b1b2cae148e364aa05e3626d6..4fd09ec46454ba78be1c2856a735984a6a13c08b 100644 --- a/maestro/pool.c +++ b/maestro/pool.c @@ -1816,10 +1816,3 @@ mstro_subscription_dispose(mstro_subscription s) -mstro_status -mstro_pool__resolve_cdoid(const struct mstro_cdo_id *id, - const char **name_p) -{ - /* we use the subscription infrastructure for this */ - return mstro_pool_resolve_cdoid(id, name_p); -} diff --git a/maestro/pool_client.c b/maestro/pool_client.c index 774d091190795c977ad40f313e881e400fa4d5de..87a15d014032296c3db66ad2f5bfbe5eb0c8681b 100644 --- a/maestro/pool_client.c +++ b/maestro/pool_client.c @@ -78,15 +78,19 @@ mstro_pc__handle_resolve_reply(const Mstro__Pool__ResolveReply *reply) } -/* store @arg new_attributes in the serialized attributes slot of @arg cdo, and replace the attribute dict values accordingly. Consumes @arg new_attributes. */ +/* store @arg new_attributes in the serialized attributes slot of @arg + * cdo, and replace the attribute dict values accordingly. Consumes + * @arg new_attributes. */ static inline mstro_status -mstro_cdo__replace_attributes(mstro_cdo cdo, Mstro__Pool__Attributes *new_attributes) +mstro_cdo__replace_attributes(mstro_cdo cdo, + Mstro__Pool__Attributes *new_attributes) { /* We can't lock a CDO on it's own. But this function should only be - * called before SEAL state change completes, and so users can't be - * accessing the CDO legally, and it's way before the CDO could be - * in the pool, so transport etc can't touch it either. */ + * called before SEAL state change completes, or during WITHDRAW + * etc. and so users can't be accessing the CDO legally, and it's + * way before or after the CDO could be in the pool, so transport + * etc can't touch it either. */ assert(mstro_cdo_state_check(cdo, MSTRO_CDO_STATE_DECLARED)); mstro_status s = MSTRO_UNIMPL; @@ -269,6 +273,31 @@ mstro_pc__select_transfer_method(mstro_cdo cdo, return MSTRO_OK; } +static inline +mstro_status +mstro_pc__construct_gfs_path_for_cdo(const mstro_cdo src_cdo, + char **path) +{ + mstro_status s=MSTRO_UNIMPL; + assert(path!=NULL); + assert(src_cdo!=NULL); + + size_t l = g_mstro_transport_gfs_dir_len + strlen(src_cdo->name) + 1; + *path = malloc(l); + if(*path==NULL) { + return MSTRO_NOMEM; + } + strcpy(*path, g_mstro_transport_gfs_dir); + + /* FIXME: possibly add a (configurable?) number of subdirectories + * based on first segment of CDO name */ + + strcpy((*path)+g_mstro_transport_gfs_dir_len, src_cdo->name); + DEBUG("Constructed GFS transport path %s\n", *path); + return MSTRO_OK; +} + + static inline mstro_status mstro_pc__handle_initiate_transfer(const Mstro__Pool__InitiateTransfer* init) @@ -398,7 +427,12 @@ mstro_pc__handle_initiate_transfer(const Mstro__Pool__InitiateTransfer* init) switch(ticket.ticket_case) { case MSTRO__POOL__TRANSFER_TICKET__TICKET_GFS: INFO("TICKET CASE GFS\n"); - gfs.path = src_cdo->name; + status= mstro_pc__construct_gfs_path_for_cdo(src_cdo, &gfs.path); + if(status!=MSTRO_OK) { + ERR("Failed to construct GFS path for SRC-CDO: %d (%s)\n", + status, mstro_status_description(status)); + return status; + } gfs.keep_file = 0; // Arbitrarily rm the transport file on dst break; case MSTRO__POOL__TRANSFER_TICKET__TICKET_MIO: diff --git a/maestro/pool_manager.c b/maestro/pool_manager.c index 95fff9b67c9e4e78435e71ceca4a7e3e9b3a6939..5627de67fa04c3cef9b60f3f99e990fac9af2bda 100644 --- a/maestro/pool_manager.c +++ b/maestro/pool_manager.c @@ -441,6 +441,31 @@ mstro_pm__msg_free(Mstro__Pool__MstroMsg *msg) mstro__pool__mstro_msg__free_unpacked(msg, NULL); } } + + +/** if the application receiving EV needs to be told the name, send + * it, otherwise set it to NULL in the EV structure */ +static inline +mstro_status +mstro_pm__possibly_fill_event_cdoname( + const struct mstro_cdo_id *cdoid, + mstro_app_id recipient, + Mstro__Pool__Event *ev) +{ + recipient = recipient; /* avoid unused warning */ + + /** FIXME: for the moment we just always send the name, could be improved */ + mstro_status s= + mstro_pm_cdo_registry_cdo_name_lookup(cdoid, + (const char **)&ev->cdo_name); + if(s!=MSTRO_OK) { + WITH_CDO_ID_STR(idstr, cdoid, { + ERR("Cannot find CDO registry entry for |%s|\n", + idstr);}); + return MSTRO_NOENT; + } + return MSTRO_OK; +} /*** DECLARE ***/ @@ -505,6 +530,7 @@ mstro_pm__handle_declare_phase2(mstro_event event, * on stack and will only be alive until notify-and-continue is * done */ ev.origin_id = cont->msg->token->appid; + ev.cdo_name = cont->msg->declare->cdo_name; status = mstro_pm__event_notify_and_continue( &ev, @@ -513,7 +539,7 @@ mstro_pm__handle_declare_phase2(mstro_event event, mstro_pm__handle_declare_phase3, cont->msg, NULL, NULL); if(status!=MSTRO_OK) { - ERR("Failed notifying subscribers of DECALRE:after event: %d (%s)\n", + ERR("Failed notifying subscribers of DECLARE:after event: %d (%s)\n", status, mstro_status_description(status)); goto BAILOUT_FREE; } @@ -543,6 +569,7 @@ mstro_pm__handle_declare(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_DECLARE; ev.declare = msg->declare; ev.origin_id = msg->token->appid; + ev.cdo_name = msg->declare->cdo_name; mstro_status status = mstro_pm__event_notify_and_continue( @@ -966,6 +993,10 @@ mstro_pm__handle_seal_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_SEAL; ev.seal = cont->msg->seal; ev.origin_id = cont->msg->token->appid; + mstro_status s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } status = mstro_pm__event_notify_and_continue( &ev, @@ -1020,6 +1051,10 @@ mstro_pm__handle_seal(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_SEAL; ev.seal = msg->seal; ev.origin_id = msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1088,6 +1123,10 @@ mstro_pm__handle_offer_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_OFFER; ev.offer = cont->msg->offer; ev.origin_id = cont->msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1114,8 +1153,10 @@ mstro_pm__handle_offer(Mstro__Pool__MstroMsg *msg) { Mstro__Pool__Offer *offer = msg->offer; mstro_app_id app_id = msg->token->appid->id; - assert(offer!=NULL); assert(app_id!=MSTRO_APP_ID_INVALID); + struct mstro_cdo_id cdoid = { .qw[0] = offer->cdoid->qw0, + .qw[1] = offer->cdoid->qw1 }; + DEBUG("CDO OFFER from %zu\n", app_id); mstro_status s=MSTRO_FAIL; @@ -1130,6 +1171,10 @@ mstro_pm__handle_offer(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_OFFER; ev.offer = msg->offer; ev.origin_id = msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1201,7 +1246,11 @@ mstro_pm__handle_require_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_REQUIRE; ev.require = cont->msg->require; ev.origin_id = cont->msg->token->appid; - + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } + s = mstro_pm__event_notify_and_continue( &ev, false, @@ -1229,6 +1278,9 @@ mstro_pm__handle_require(Mstro__Pool__MstroMsg *msg) Mstro__Pool__Require *require = msg->require; mstro_app_id app_id = msg->token->appid->id; assert(require!=NULL); assert(app_id!=MSTRO_APP_ID_INVALID); + struct mstro_cdo_id cdoid = { .qw[0] = require->cdoid->qw0, + .qw[1] = require->cdoid->qw1 }; + DEBUG("CDO REQUIRE from %zu\n", app_id); mstro_status s; @@ -1243,6 +1295,10 @@ mstro_pm__handle_require(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_REQUIRE; ev.require = msg->require; ev.origin_id = msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1295,8 +1351,12 @@ mstro_pm__handle_retract_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_RETRACT; ev.retract = cont->msg->retract; ev.origin_id = cont->msg->token->appid; + mstro_status s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } - mstro_status s = mstro_pm__event_notify_and_continue( + s = mstro_pm__event_notify_and_continue( &ev, false, NULL, @@ -1322,7 +1382,13 @@ mstro_pm__handle_retract(Mstro__Pool__MstroMsg *msg) { Mstro__Pool__Retract *retract = msg->retract; mstro_app_id app_id = msg->token->appid->id; - retract = retract; app_id=app_id; /* avoid unused arg warning */ + assert(retract!=NULL); + + app_id=app_id; /* avoid unused arg warning */ + struct mstro_cdo_id cdoid = { .qw[0] = retract->cdoid->qw0, + .qw[1] = retract->cdoid->qw1 }; + + Mstro__Pool__Event ev = MSTRO__POOL__EVENT__INIT; /* serial and handle set later */ @@ -1330,8 +1396,13 @@ mstro_pm__handle_retract(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_RETRACT; ev.retract = msg->retract; ev.origin_id = msg->token->appid; + mstro_status s = + mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } - mstro_status s = mstro_pm__event_notify_and_continue( + s = mstro_pm__event_notify_and_continue( &ev, true, NULL, @@ -1401,6 +1472,10 @@ mstro_pm__handle_demand_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_DEMAND; ev.demand = cont->msg->demand; ev.origin_id = cont->msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1429,6 +1504,11 @@ mstro_pm__handle_demand(Mstro__Pool__MstroMsg *msg) Mstro__Pool__Demand *demand = msg->demand; mstro_app_id app_id = msg->token->appid->id; assert(demand!=NULL); assert(app_id!=MSTRO_APP_ID_INVALID); + + struct mstro_cdo_id cdoid = { .qw[0] = demand->cdoid->qw0, + .qw[1] = demand->cdoid->qw1 }; + + DEBUG("CDO DEMAND from %zu\n", app_id); mstro_status s; @@ -1443,6 +1523,10 @@ mstro_pm__handle_demand(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_DEMAND; ev.demand = msg->demand; ev.origin_id = msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1511,6 +1595,10 @@ mstro_pm__handle_withdraw_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_WITHDRAW; ev.withdraw = cont->msg->withdraw; ev.origin_id = cont->msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1555,6 +1643,10 @@ mstro_pm__handle_withdraw(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_WITHDRAW; ev.withdraw = msg->withdraw; ev.origin_id = msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1610,6 +1702,10 @@ mstro_pm__handle_dispose_phase2(mstro_event event, ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_DISPOSE; ev.dispose = cont->msg->dispose; ev.origin_id = cont->msg->token->appid; + s = mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } s = mstro_pm__event_notify_and_continue( &ev, @@ -1636,7 +1732,12 @@ mstro_pm__handle_dispose(Mstro__Pool__MstroMsg *msg) { Mstro__Pool__Dispose *dispose = msg->dispose; mstro_app_id app_id = msg->token->appid->id; - dispose=dispose; app_id=app_id; /* avoid unused arg warning */ + app_id=app_id; /* avoid unused arg warning */ + assert(dispose!=NULL); + + struct mstro_cdo_id cdoid = { .qw[0] = dispose->cdoid->qw0, + .qw[1] = dispose->cdoid->qw1 }; + Mstro__Pool__Event ev = MSTRO__POOL__EVENT__INIT; /* serial and handle set later */ @@ -1644,8 +1745,13 @@ mstro_pm__handle_dispose(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_DISPOSE; ev.dispose = msg->dispose; ev.origin_id = msg->token->appid; + mstro_status s = + mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } - mstro_status s = mstro_pm__event_notify_and_continue( + s = mstro_pm__event_notify_and_continue( &ev, true, NULL, @@ -1684,6 +1790,9 @@ mstro_pm__handle_transfer_completed(Mstro__Pool__MstroMsg *msg) mstro_app_id app_id = msg->token->appid->id; assert(completion!=NULL); assert(app_id!=MSTRO_APP_ID_INVALID); + struct mstro_cdo_id cdoid = { .qw[0] = completion->cdoid->qw0, + .qw[1] = completion->cdoid->qw1 }; + DEBUG("TRANSFER COMPLETION from %zu\n", app_id); /* produce completed:after event */ @@ -1693,8 +1802,13 @@ mstro_pm__handle_transfer_completed(Mstro__Pool__MstroMsg *msg) ev.payload_case = MSTRO__POOL__EVENT__PAYLOAD_TRANSFER_COMPLETED; ev.transfer_completed = msg->transfer_completed; ev.origin_id = msg->token->appid; + mstro_status s = + mstro_pm__possibly_fill_event_cdoname(&cdoid, app_id, &ev); + if(s!=MSTRO_OK) { + goto BAILOUT_FREE; + } - mstro_status s = mstro_pm__event_notify_and_continue( + s = mstro_pm__event_notify_and_continue( &ev, false, NULL, diff --git a/maestro/pool_manager_registry.c b/maestro/pool_manager_registry.c index bda4204003eeeeedaeb3976072700327dc49d180..af22504a0e1f9541b2bc38052a4c92df542f8685 100644 --- a/maestro/pool_manager_registry.c +++ b/maestro/pool_manager_registry.c @@ -1133,7 +1133,7 @@ mstro_pm_cdo_app_match(mstro_app_id origin, const struct mstro_cdo_id *id, /* str, origin, cdo_selector, cdo_selector->query); */ /* }); */ mstro_status status = MSTRO_FAIL; - /* now fetcch attributes from per-app-CDO entry, call subscription-module checker and return result */ + /* now fetch attributes from per-app-CDO entry, call subscription-module checker and return result */ WITH_LOCKED_CDO_REGISTRY({ struct per_app_cdo_entry *entry; status = mstro_pm_cdo_app_lookup(id, origin, &entry); diff --git a/maestro/subscription_registry.c b/maestro/subscription_registry.c index db4402a3d2912abf35f85155a9dc6fa8e5b594da..cb34610d24b8a738ae25ae3859dc5c0d310c942b 100644 --- a/maestro/subscription_registry.c +++ b/maestro/subscription_registry.c @@ -324,6 +324,7 @@ mstro__subscr_resolver_lookup_cdoid(const struct mstro_cdo_id *id, goto ABORT; } } + DEBUG("Entering wait for resolver lookup reply\n"); /* setup done, time to wait. ResolveReply will be handled by * @ref mstro_pool_resolve_reply_bh will will trigger our * event */ @@ -1424,13 +1425,15 @@ const Mstro__Pool__KvEntry * mstro_subscription__pool_attr_find(const Mstro__Pool__Attributes__Map *kv_map, const char *key) { - if(kv_map==NULL) + if(kv_map==NULL) { + DEBUG("Empty kv map when looking for key |%s|\n", key); return NULL; - else { - for(size_t i=0; i<kv_map->n_map; i++) + } else { + for(size_t i=0; i<kv_map->n_map; i++) { if(strcmp(key,kv_map->map[i]->key)==0) { return kv_map->map[i]; } + } return NULL; } } @@ -1487,18 +1490,18 @@ mstro_subscription__csq_eval(const struct mstro_csq_val *csq, entry = mstro_subscription__pool_attr_find(attributes->kv_map, key); if(entry==NULL) { if(complement) { - DEBUG("has-not matched for |%s|\n", key); + DEBUG("HAS-NOT matched for |%s|\n", key); return MSTRO_OK; } else { - DEBUG("has did not match for |%s|\n", key); + DEBUG("HAS did not match for |%s|\n", key); return MSTRO_NOMATCH; } } else { if(complement) { - DEBUG("has-not did not match for |%s|\n", key); + DEBUG("HAS-NOT did not match for |%s|\n", key); return MSTRO_NOMATCH; } else { - DEBUG("has matched for |%s|\n", key); + DEBUG("HAS matched for |%s|\n", key); return MSTRO_OK; } } @@ -1526,7 +1529,8 @@ mstro_subscription__csq_eval(const struct mstro_csq_val *csq, return MSTRO_NOMATCH; } } else { - /* key matched. Now need to parse the value in the csq and call the appropriate comparison function */ + /* key matched. Now need to parse the value in the csq and + * call the appropriate comparison function */ const Mstro__Pool__AVal *aval = entry->val; void *rhsval=NULL; size_t rhsval_size=0; @@ -1605,7 +1609,8 @@ mstro_subscription_selector_eval(const struct mstro_cdo_id *cdoid, struct mstro_csq_val *csq = sel->csq; if(csq==NULL) { - /* FIXME: maybe we need to create it on the first use of SEL if we're on the PM? */ + /* FIXME: maybe we need to create it on the first use of SEL if + * we're on the PM? */ ERR("No parsed query (CSQ) available\n"); return MSTRO_FAIL; } @@ -1633,7 +1638,7 @@ mstro_subscription_selector_check(struct mstro_subscription_ *s, /* declare is special: no CDOID known yet, no attribuites, only * string name. Efficient subscriptions will subscribe to * DECLARE_ACK instead. */ - WARN("DECLARE event always matches -- FIXME\n"); + WARN("DECLARE event always matches -- FIXME: only name could be checked (and we don't)\n"); return MSTRO_OK; } else { /* we always need the CDO id. Unfortunately it's slightly buried in the EV */ @@ -1656,7 +1661,8 @@ mstro_subscription_selector_check(struct mstro_subscription_ *s, ERR("Failed to serialized attribute message for CDO\n"); return status; } - status = mstro_subscription_selector_eval(&id, s->cdo_selector, attributes); + status = mstro_subscription_selector_eval(&id, s->cdo_selector, + attributes); } } return status; @@ -1756,12 +1762,15 @@ mstro_pool_event_advertise(Mstro__Pool__Event *ev, if(s->subscription->needs_ack) { uint64_t num_outstanding - = atomic_fetch_add_explicit(&ctx->nr_outstanding_acks, 1, memory_order_release); - DEBUG("Now %" PRIu64 " outstanding acks for this event\n", num_outstanding); + = atomic_fetch_add_explicit(&ctx->nr_outstanding_acks, + 1, memory_order_release); + DEBUG("Now %" PRIu64 " outstanding acks for this event\n", + num_outstanding); mstro_event ack_event; status = mstro_event_create(g_subscription_table.edom, - event_ack_cb, ctx, NULL, true, &ack_event); + event_ack_cb, ctx, NULL, true, + &ack_event); if(status!=MSTRO_OK) { ERR("Failed to create event for subscription ack, skipping subscriber %" PRIu64 "\n", s->subscriber); @@ -1901,9 +1910,25 @@ mstro_pool_event_consume(const Mstro__Pool__Event *eventmsg) const char* cdo_name; cdo_name = malloc(MSTRO_CDO_NAME_MAX); assert(cdo_name!=NULL); - mstro_status s = mstro__subscr_resolver_lookup_cdoid( - (struct mstro_cdo_id*)eventmsg->offer->cdoid, &cdo_name); - ev->offer.cdo_name = (char*)cdo_name; + struct mstro_cdo_id id = { + .qw[0] = eventmsg->offer->cdoid->qw0, + .qw[1] = eventmsg->offer->cdoid->qw1 + }; + /* we cannot call the resolver in here, as that would lock up + * our thread in the PC. But CDO-related events should have a + * NAME value */ + if(eventmsg->cdo_name==NULL) { + ERR("OFFER event missing a CDO name\n"); + free(ev); + return MSTRO_FAIL; + } else { + ev->offer.cdo_name = strdup(eventmsg->cdo_name); + if(ev->declare.cdo_name == NULL) { + ERR("Failed to allocate event data\n"); + free(ev); + return MSTRO_NOMEM; + } + } DEBUG("Event: OFFER for |%s| from %" PRIu64 "\n", ev->offer.cdo_name, ev->offer.appid); break; @@ -1914,23 +1939,21 @@ mstro_pool_event_consume(const Mstro__Pool__Event *eventmsg) && eventmsg->origin_id->id!=MSTRO_APP_ID_INVALID); assert(eventmsg->seal->cdoid!=NULL); ev->seal.appid = eventmsg->origin_id->id; - { - WARN("FIXME: Missing CDO resolver, returning ID string\n"); - struct mstro_cdo_id id = {.qw[0] = eventmsg->seal->cdoid->qw0, - .qw[1] = eventmsg->seal->cdoid->qw1 }; - - WITH_CDO_ID_STR(idstr, &id, { - ev->seal.cdo_name = strdup(idstr); - }); + if(eventmsg->cdo_name==NULL) { + ERR("SEAL event missing a CDO name\n"); + free(ev); + return MSTRO_FAIL; + } else { + ev->seal.cdo_name = strdup(eventmsg->cdo_name); if(ev->seal.cdo_name == NULL) { ERR("Failed to allocate event data\n"); free(ev); return MSTRO_NOMEM; } - - DEBUG("Event: SEAL for |%s| from %" PRIu64 "\n", - ev->seal.cdo_name, ev->seal.appid); } + + DEBUG("Event: SEAL for |%s| from %" PRIu64 "\n", + ev->seal.cdo_name, ev->seal.appid); break; case MSTRO_POOL_EVENT_REQUIRE: @@ -1939,23 +1962,21 @@ mstro_pool_event_consume(const Mstro__Pool__Event *eventmsg) && eventmsg->origin_id->id!=MSTRO_APP_ID_INVALID); assert(eventmsg->require->cdoid!=NULL); ev->require.appid = eventmsg->origin_id->id; - { - WARN("FIXME: Missing CDO resolver, returning ID string\n"); - struct mstro_cdo_id id = {.qw[0] = eventmsg->require->cdoid->qw0, - .qw[1] = eventmsg->require->cdoid->qw1 }; - - WITH_CDO_ID_STR(idstr, &id, { - ev->require.cdo_name = strdup(idstr); - }); + if(eventmsg->cdo_name==NULL) { + ERR("REQUIRE event missing a CDO name\n"); + free(ev); + return MSTRO_FAIL; + } else { + ev->require.cdo_name = strdup(eventmsg->cdo_name); if(ev->require.cdo_name == NULL) { ERR("Failed to allocate event data\n"); free(ev); return MSTRO_NOMEM; } - - DEBUG("Event: REQUIRE for |%s| from %" PRIu64 "\n", - ev->require.cdo_name, ev->require.appid); } + + DEBUG("Event: REQUIRE for |%s| from %" PRIu64 "\n", + ev->require.cdo_name, ev->require.appid); break; case MSTRO_POOL_EVENT_WITHDRAW: @@ -1964,23 +1985,22 @@ mstro_pool_event_consume(const Mstro__Pool__Event *eventmsg) && eventmsg->origin_id->id!=MSTRO_APP_ID_INVALID); assert(eventmsg->withdraw->cdoid!=NULL); ev->withdraw.appid = eventmsg->origin_id->id; - { - WARN("FIXME: Missing CDO resolver, returning ID string\n"); - struct mstro_cdo_id id = {.qw[0] = eventmsg->withdraw->cdoid->qw0, - .qw[1] = eventmsg->withdraw->cdoid->qw1 }; - - WITH_CDO_ID_STR(idstr, &id, { - ev->withdraw.cdo_name = strdup(idstr); - }); + + if(eventmsg->cdo_name==NULL) { + ERR("WITHDRAW event missing a CDO name\n"); + free(ev); + return MSTRO_FAIL; + } else { + ev->withdraw.cdo_name = strdup(eventmsg->cdo_name); if(ev->withdraw.cdo_name == NULL) { ERR("Failed to allocate event data\n"); free(ev); return MSTRO_NOMEM; } - - DEBUG("Event: WITHDRAW for |%s| from %" PRIu64 "\n", - ev->withdraw.cdo_name, ev->withdraw.appid); } + + DEBUG("Event: WITHDRAW for |%s| from %" PRIu64 "\n", + ev->withdraw.cdo_name, ev->withdraw.appid); break; case MSTRO_POOL_EVENT_APP_BYE: @@ -2155,9 +2175,11 @@ mstro_subscriptions_finalize(void) return status; } +/* called on pool client to handle resolver reply */ mstro_status mstro_pool_resolve_reply_bh(const Mstro__Pool__ResolveReply *reply) { + DEBUG("Resolver reply received\n"); if(reply==NULL ||reply->query==NULL) { return MSTRO_INVMSG; } diff --git a/protocols/mstro_pool.pb-c.c b/protocols/mstro_pool.pb-c.c index b08e90ef01b64e05a8f8d64d80e1fb9cd576bd34..e241057209aa3eef7544237f28ab8682b6fbc8f7 100644 --- a/protocols/mstro_pool.pb-c.c +++ b/protocols/mstro_pool.pb-c.c @@ -4890,7 +4890,7 @@ const ProtobufCMessageDescriptor mstro__pool__unsubscribe__descriptor = (ProtobufCMessageInit) mstro__pool__unsubscribe__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor mstro__pool__event__field_descriptors[23] = +static const ProtobufCFieldDescriptor mstro__pool__event__field_descriptors[24] = { { "subscription_handle", @@ -4940,6 +4940,18 @@ static const ProtobufCFieldDescriptor mstro__pool__event__field_descriptors[23] 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "cdo_name", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Mstro__Pool__Event, cdo_name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, { "declare", 16, @@ -5170,36 +5182,37 @@ static const ProtobufCFieldDescriptor mstro__pool__event__field_descriptors[23] }, }; static const unsigned mstro__pool__event__field_indices_by_name[] = { - 20, /* field[20] = bye */ - 4, /* field[4] = declare */ - 5, /* field[5] = declare_ack */ - 11, /* field[11] = demand */ - 13, /* field[13] = dispose */ - 17, /* field[17] = join */ + 21, /* field[21] = bye */ + 4, /* field[4] = cdo_name */ + 5, /* field[5] = declare */ + 6, /* field[6] = declare_ack */ + 12, /* field[12] = demand */ + 14, /* field[14] = dispose */ + 18, /* field[18] = join */ 2, /* field[2] = kind */ - 19, /* field[19] = leave */ - 8, /* field[8] = offer */ + 20, /* field[20] = leave */ + 9, /* field[9] = offer */ 3, /* field[3] = origin_id */ - 9, /* field[9] = require */ - 12, /* field[12] = retract */ - 6, /* field[6] = seal */ - 7, /* field[7] = seal_group */ + 10, /* field[10] = require */ + 13, /* field[13] = retract */ + 7, /* field[7] = seal */ + 8, /* field[8] = seal_group */ 1, /* field[1] = serial */ - 21, /* field[21] = subscribe */ + 22, /* field[22] = subscribe */ 0, /* field[0] = subscription_handle */ - 16, /* field[16] = transfer_completed */ - 14, /* field[14] = transport_init */ - 15, /* field[15] = transport_ticket */ - 22, /* field[22] = unsubscribe */ - 18, /* field[18] = welcome */ - 10, /* field[10] = withdraw */ + 17, /* field[17] = transfer_completed */ + 15, /* field[15] = transport_init */ + 16, /* field[16] = transport_ticket */ + 23, /* field[23] = unsubscribe */ + 19, /* field[19] = welcome */ + 11, /* field[11] = withdraw */ }; static const ProtobufCIntRange mstro__pool__event__number_ranges[3 + 1] = { { 1, 0 }, - { 16, 4 }, - { 32, 17 }, - { 0, 23 } + { 16, 5 }, + { 32, 18 }, + { 0, 24 } }; const ProtobufCMessageDescriptor mstro__pool__event__descriptor = { @@ -5209,7 +5222,7 @@ const ProtobufCMessageDescriptor mstro__pool__event__descriptor = "Mstro__Pool__Event", "mstro.pool", sizeof(Mstro__Pool__Event), - 23, + 24, mstro__pool__event__field_descriptors, mstro__pool__event__field_indices_by_name, 3, mstro__pool__event__number_ranges, diff --git a/protocols/mstro_pool.pb-c.h b/protocols/mstro_pool.pb-c.h index 553abf0d71b41bfc28fdab7022608418d7f3d72f..7c17cfeea05b198482f42d01174d0ccfa581c87e 100644 --- a/protocols/mstro_pool.pb-c.h +++ b/protocols/mstro_pool.pb-c.h @@ -1143,7 +1143,8 @@ struct _Mstro__Pool__Event { ProtobufCMessage base; /* - ** the (workflow-unique) event id. IDs can be reused over the course of a workflow. + ** the (workflow-unique) event id. + *IDs can be reused over the course of a workflow. */ Mstro__Pool__SubscriptionHandle *subscription_handle; uint64_t serial; @@ -1152,9 +1153,14 @@ struct _Mstro__Pool__Event */ Mstro__Pool__EventKind kind; /* - ** the application that caused the event. Can be invalid or pool manager, or a joined component + ** the application that caused the event. + *Can be invalid or pool manager, or a joined component */ Mstro__Pool__Appid *origin_id; + /* + ** the CDO concerned. Will be unset for non-CDO events + */ + char *cdo_name; Mstro__Pool__Event__PayloadCase payload_case; union { /* @@ -1240,7 +1246,7 @@ struct _Mstro__Pool__Event }; #define MSTRO__POOL__EVENT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&mstro__pool__event__descriptor) \ - , NULL, 0, MSTRO__POOL__EVENT_KIND__INVALID_EVENT, NULL, MSTRO__POOL__EVENT__PAYLOAD__NOT_SET, {0} } + , NULL, 0, MSTRO__POOL__EVENT_KIND__INVALID_EVENT, NULL, (char *)protobuf_c_empty_string, MSTRO__POOL__EVENT__PAYLOAD__NOT_SET, {0} } struct _Mstro__Pool__EventAck diff --git a/protocols/mstro_pool.proto b/protocols/mstro_pool.proto index d0bc27f0ee865de7d0053b4c055e04f742c0378c..8cc097b041ebc218bb4f6845b31b652a5b750bb8 100644 --- a/protocols/mstro_pool.proto +++ b/protocols/mstro_pool.proto @@ -660,17 +660,22 @@ message Unsubscribe { /** Events that match a subscription */ message Event { - /** the (workflow-unique) event id. IDs can be reused over the course of a workflow. */ + /** the (workflow-unique) event id. + IDs can be reused over the course of a workflow. */ SubscriptionHandle subscription_handle = 1; fixed64 serial = 2; /** The kind of event */ EventKind kind = 3; - /** the application that caused the event. Can be invalid or pool manager, or a joined component */ + /** the application that caused the event. + Can be invalid or pool manager, or a joined component */ Appid origin_id = 4; + /** the CDO concerned. Will be unset for non-CDO events */ + string cdo_name = 5; /** the data associated with the event * * In most cases this conincides with the payload sent int the - * original message associated with the event, except that VSM messages are unsupported. + * original message associated with the event, + * except that VSM messages are unsupported. */ oneof payload { /** for kind DECLARE */ diff --git a/tests/check_cdo_selectors.c b/tests/check_cdo_selectors.c index e2ed5bfb75127893f7ce435c2026fef5ba8ddab2..6a55f3c22992cea584e74fc88925cf90f42446a8 100644 --- a/tests/check_cdo_selectors.c +++ b/tests/check_cdo_selectors.c @@ -154,4 +154,12 @@ CHEAT_TEST(core_cdo_selector_or_and, ) - +CHEAT_TEST(ecmwf_int_comparison, + /* https://gitlab.version.fz-juelich.de/maestro/maestro-core/-/issues/16 */ + /* parsing of integral CDO selector values */ + const char *s = "(.maestro.ecmwf.param = 2)"; + cheat_assert(MSTRO_OK==mstro_selector_parse(s,&q)); + cheat_yield(); + cheat_assert(MSTRO_OK==mstro_csq_val_dispose(q)); + cheat_yield(); + ) diff --git a/tests/simple_archiver.c b/tests/simple_archiver.c index 1bf74c66d8330495b876358186c10691e265f87f..85c24ada8e1355ca775da8c0094511f50de9afa8 100644 --- a/tests/simple_archiver.c +++ b/tests/simple_archiver.c @@ -144,24 +144,43 @@ CHEAT_TEST(simple_archiver, mstro_pool_event tmp=e; /* handle all */ while(tmp) { + const char *event_name=NULL; + const char *cdo_name=NULL; + event_name = mstro_pool_event_description(tmp->kind); + switch(tmp->kind) { case MSTRO_POOL_EVENT_OFFER: /* FIXME: Immediately post a REQUIRE for it */ - fprintf(stderr, "Spotted an OFFER for CDO (`%s`)\n", e->offer.cdo_name); + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_DECLARE: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_DISPOSE: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_SEAL: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_DEMAND: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_REQUIRE: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_RETRACT: + cdo_name = tmp->offer.cdo_name; + break; case MSTRO_POOL_EVENT_WITHDRAW: - fprintf(stdout, "CDO event %s\n", - mstro_pool_event_description(tmp->kind)); + cdo_name = tmp->offer.cdo_name; break; default: fprintf(stderr, "Unexpected CDO event %d\n", tmp->kind); } + fprintf(stdout, "CDO event %s for CDO |%s|\n", + event_name, cdo_name ? cdo_name : "??"); + tmp=tmp->next; } /* acknowledge all */ diff --git a/tests/simple_telemetry_listener.c b/tests/simple_telemetry_listener.c index 3a3b7e70513fb17e5bbb466383a48a9bb4c800ab..7ae3372cd2b012329e24bae70525daa26a95369d 100644 --- a/tests/simple_telemetry_listener.c +++ b/tests/simple_telemetry_listener.c @@ -212,7 +212,7 @@ parse_arguments(int argc, char **argv) } if(g_verbose) { - fprintf(stderr, "Configuration: %s/%s/%s/%llu/%d\n", + fprintf(stderr, "Configuration: %s/%s/%s/%" PRIu64 "/%d\n", g_conf_workflow_name, g_conf_component_name, g_conf_terminate_after, g_conf_max_wait, g_conf_logdst); } diff --git a/transport/gfs.c b/transport/gfs.c index 7d3090c46c3f17152c5609ec7b6cc64b1b17a36a..a8844e5d345b9fc50130e45281a3c97888f74e87 100644 --- a/transport/gfs.c +++ b/transport/gfs.c @@ -69,7 +69,7 @@ mstro_transport_gfs_src_execute(mstro_cdo src, Mstro__Pool__TransferTicket* tick FILE *f = NULL; char* path = ticket->gfs->path; - INFO("Path src app will use for transport: %s\n", path); + DEBUG("Path src app will use for transport: %s\n", path); if (path == NULL) { ERR("Ticket for GFS transport does not contain a path\n"); return MSTRO_INVARG; @@ -77,21 +77,25 @@ mstro_transport_gfs_src_execute(mstro_cdo src, Mstro__Pool__TransferTicket* tick f = fopen(path,"w"); if (f == NULL) { - ERR("Failed to open %s for GFS transport\n", path); + ERR("Failed to open %s for GFS transport (errno: %d -- %s)\n", + path, errno, strerror(errno)); return MSTRO_FAIL; } if (fwrite(dl.data, sizeof(char), dl.len/sizeof(char), f) != dl.len) { - ERR("Partial write on %s for GFS transport\n", path); + ERR("Partial write on %s (buf: %p) for GFS transport (errno: %d -- %s)\n", + path, dl.data, errno, strerror(errno)); return MSTRO_FAIL; } if (fclose(f) != 0) { - ERR("Failed to close %s for GFS transport\n", path); + ERR("Failed to close %s for GFS transport (errno: %d -- %s)\n", + path, errno, strerror(errno)); return MSTRO_FAIL; } - INFO("src app successfully executed transport CDO %s\n", src->name); + DEBUG("src app successfully executed transport CDO %s\n", + src->name); return MSTRO_OK; } @@ -125,11 +129,11 @@ mstro_transport_gfs_dst_execute(mstro_cdo dst, /* data is the raw-ptr or freshly allocated, CDO attribute is correct */ FILE *f = NULL; char* path = ticket->gfs->path; - INFO("Path src app will use for transport: %s\n", path); if (path == NULL) { ERR("Ticket for GFS transport does not contain a path\n"); return MSTRO_INVARG; } + DEBUG("Path dst app will use for transport: %s\n", path); f = fopen(path,"rb"); if (f == NULL) { ERR("Failed to open %s for GFS transport: %d (%s)\n", @@ -138,12 +142,14 @@ mstro_transport_gfs_dst_execute(mstro_cdo dst, } if (fread(data, sizeof(char), len, f) != (size_t)len) { - ERR("Partial read on %s for GFS transport\n", path); + ERR("Partial read on %s for GFS transport (errno: %d -- %s)\n", + path, errno, strerror(errno)); return MSTRO_FAIL; } if (fclose(f) != 0) { - ERR("Failed to close %s for GFS transport\n", path); + ERR("Failed to close %s for GFS transport (errno: %d -- %s)\n", + path, errno, strerror(errno)); return MSTRO_FAIL; } @@ -170,7 +176,7 @@ mstro_transport_gfs_dst_execute(mstro_cdo dst, /* abort(); */ /* } */ - INFO("dst app successfully executed transport CDO %s\n", dst->name); + DEBUG("dst app successfully executed transport CDO %s\n", dst->name); if (! (ticket->gfs->keep_file)) { int s = unlink(ticket->gfs->path); @@ -178,7 +184,7 @@ mstro_transport_gfs_dst_execute(mstro_cdo dst, WARN("Couldn't unlink file used for gfs transfer (%s): %d (%s)\n", ticket->gfs->path, s, strerror(s)); } else { - INFO("Removed the transfer file from GFS\n"); + DEBUG("Removed the transfer file\n"); } } diff --git a/transport/transport.c b/transport/transport.c index 230260565a21e2c389e83f271cb4e4a8e69cd571..4c3f6d73c038e50792a953809daa591e908582ca 100644 --- a/transport/transport.c +++ b/transport/transport.c @@ -43,6 +43,8 @@ #include "maestro/i_cdo.h" #include <inttypes.h> +#include <sys/stat.h> + #include "transport/transport_gfs.h" #ifdef HAVE_MIO @@ -170,11 +172,63 @@ mstro_transport__src_datalen_get(mstro_cdo src, return MSTRO_OK; } +/** find next separator in PATH. Return the start of that segment */ +static inline +const char * next_sep (const char *path) +{ + while (*path) + if (*path == '/' || *path == '\\') + return path; + else + path++; + return NULL; +} + +/** ensure all directories in DIRNAME exist. If not, try creating them */ +static inline +mstro_status +mkdirhier(char *dirname) +{ + char buf[PATH_MAX]; + const char *prev = dirname; + const char *next; + struct stat sb; + + while(NULL!=(next = next_sep(prev))) { + strncpy(buf, dirname, next - dirname) ; + buf[next - dirname] = '\0'; + if(stat(buf,&sb)) { + mkdir(buf, 0777); /* umask taken into account by system */ + /* we ignore errors, as we'll see an error on the last part */ + } + prev=next+1; + } + /* handle last part */ + if(stat(dirname, &sb)) { + int s = mkdir(dirname, 0777); + if(s!=0) { + ERR("Failed to create GFS transport directory %s: %d (%s)\n", + dirname, errno, strerror(errno)); + return MSTRO_FAIL; + } + } + return MSTRO_OK; +} + mstro_status mstro_transport_init() { srand(time(NULL)); /* We'll need that to generate random IDs */ + + /* ensure GFS dir is set up */ + mstro_status s = mkdirhier(g_mstro_transport_gfs_dir); + if(s!=MSTRO_OK) { + ERR("Failed to initialize GFS transport. Check your setting of %s\n", + MSTRO_ENV_TRANSPORT_GFS_DIR); + return s; + } + #ifdef HAVE_MIO /* MIO */ if(g_mio_available) {