dotnet3.1 package is retired on branch c10s for CS-2551

This commit is contained in:
Johnny Hughes 2024-10-02 16:24:13 +00:00
parent 7017399bce
commit bfeca282d6
19 changed files with 4 additions and 1620 deletions

13
.gitignore vendored
View File

@ -1,13 +0,0 @@
/dotnet-v3.1.101-SDK.tar.gz
/dotnet-v3.1.102-SDK.tar.gz
/dotnet-v3.1.103.2-SDK.tar.gz
/dotnet-v3.1.104-SDK.tar.gz
/dotnet-v3.1.105-SDK.tar.gz
/dotnet-v3.1.105-SDK-arm64.tar.gz
/dotnet-v3.1.105-SDK-x64.tar.gz
/dotnet-v3.1.106-SDK.tar.gz
/dotnet-v3.1.107-SDK.tar.gz
/dotnet-v3.1.108-SDK.tar.gz
/dotnet-v3.1.109-SDK.tar.gz
/dotnet-v3.1.110-SDK.tar.gz
/dotnet-v3.1.111-SDK.tar.gz

136
README.md
View File

@ -1,133 +1,3 @@
# Overview
This is the .NET Core 3.1 package for Fedora.
This package is maintained by the Fedora DotNet SIG (Special Interest
Group). You can find out more about the DotNet SIG at:
- https://fedoraproject.org/wiki/SIGs/DotNet
- https://fedoraproject.org/wiki/DotNet
- https://lists.fedoraproject.org/archives/list/dotnet-sig@lists.fedoraproject.org/
Please report any issues [using
bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=dotnet3.1).
# Specification
This package follows [package naming and contents suggested by
upstream](https://docs.microsoft.com/en-us/dotnet/core/build/distribution-packaging),
with one exception. It installs dotnet to `/usr/lib64/dotnet` (aka
`%{_libdir}`).
# Contributing
## General Changes
1. Fork the repo.
2. Checkout the forked repository.
- `git clone ssh://$USER@pkgs.fedoraproject.org/forks/$USER/rpms/dotnet3.1.git`
- `cd dotnet3.1`
3. Make your changes. Don't forget to add a changelog.
4. Do local builds.
- `fedpkg local`
5. Fix any errors that come up and rebuild until it works locally.
6. Do builds in koji.
- `fedpkg scratch-build --srpm`
8. Commit the changes to the git repo.
- `git add` any new patches
- `git remove` any now-unnecessary patches
- `git commit -a`
- `git push`
9. Create a pull request with your changes.
10. Once the tests in the pull-request pass, and reviewers are happy, do a real
build.
- `fedpkg build`
11. For non-rawhide releases, file updates using bodhi to ship the just-built
package out to users.
- https://bodhi.fedoraproject.org/updates/new
OR
- `fedpkg update`
## Updating to an new upstream release
1. Fork the repo.
2. Checkout the forked repository.
- `git clone ssh://$USER@pkgs.fedoraproject.org/forks/$USER/rpms/dotnet3.1.git`
- `cd dotnet3.1`
3. Build the new upstream source tarball. Update the versions in the
spec file. Add a changelog. This is generally automated by the
following.
- `./update-release <sdk-version> <runtime-version>`
If this fails because of compiler errors, you might have to figure
out a fix, then add the patch in `build-dotnet-tarball` script
rather than the spec file.
4. Do local builds.
- `fedpkg local`
5. Fix any errors that come up and rebuild until it works locally. Any
patches that are needed at this point should be added to the spec file.
6. Do builds in koji.
- `fedpkg scratch-build --srpm`
7. Upload the source archive to the Fedora look-aside cache.
- `fedpkg new-sources path-to-generated-dotnet-source-tarball.tar.gz`
8. Commit the changes to the git repo.
- `git add` any new patches
- `git remove` any now-unnecessary patches
- `git commit -a`
- `git push`
9. Create a pull request with your changes.
10. Once the tests in the pull-request pass, and reviewers are happy, do a real
build.
- `fedpkg build`
11. For non-rawhide releases, file updates using bodhi to ship the just-built
package out to users.
- https://bodhi.fedoraproject.org/updates/new
OR
- `fedpkg update`
# Testing
This package uses CI tests as defined in `tests/test.yml`. Creating a
pull-request or running a build will fire off tests and flag any issues. We have
enabled gating (via `gating.yaml`) on the tests. That prevents a build
that fails any test from being released until the failures are waived.
The tests themselves are contained in this external repository:
https://github.com/redhat-developer/dotnet-regular-tests/
# Package Not Available
This package is not available on CentOS Stream 10.
It may be available on another branch.

View File

@ -1,50 +0,0 @@
#!/bin/bash
set -euo pipefail
set -x
sdk_version=3.1.105
arch=$(uname -m)
if [[ $arch == "x86_64" ]]; then
arch=x64
elif [[ $arch == "aarch64" ]]; then
arch=arm64
fi
if rpm -qa | grep libunwind; then
echo "error: libunwind is installed. Not a good idea for bootstrapping."
exit 1
fi
if rpm -qa | grep dotnet ; then
echo "error: dotnet is installed. Not a good idea for bootstrapping."
exit 1
fi
if [ -d /usr/lib/dotnet ] || [ -d /usr/lib64/dotnet ] || [ -d /usr/share/dotnet ] ; then
echo "error: one of /usr/lib/dotnet /usr/lib64/dotnet or /usr/share/dotnet/ exists. Not a good idea for bootstrapping."
exit 1
fi
if command -v dotnet ; then
echo "error: dotnet is in $PATH. Not a good idea for bootstrapping."
exit 1
fi
if [ ! -d dotnet-source-build-tarball ]; then
if [ ! -d source-build ]; then
git clone https://github.com/dotnet/source-build
fi
pushd source-build
sed -i -e 's|cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE||' repos/coreclr.common.props
git clean -xdf
./build-source-tarball.sh ../dotnet-source-build-tarball/ -- -p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000
popd
fi
rm -rf dotnet-v${sdk_version}-SDK dotnet-v${sdk_version}-SDK.tar.gz
cp -a dotnet-source-build-tarball dotnet-v${sdk_version}-SDK
cp -a source-build/artifacts/$arch/Release/Private.SourceBuilt.Artifacts.*.tar.gz dotnet-v${sdk_version}-SDK/packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz
tar czf dotnet-v${sdk_version}-SDK-$arch.tar.gz dotnet-v${sdk_version}-SDK

View File

@ -1,12 +0,0 @@
diff --git a/configurecompiler.cmake b/configurecompiler.cmake
index d769e82f57..4936c8b00d 100644
--- a/configurecompiler.cmake
+++ b/configurecompiler.cmake
@@ -474,6 +474,7 @@ if (CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-Wno-unused-variable)
add_compile_options(-Wno-unused-value)
add_compile_options(-Wno-unused-function)
+ add_compile_options(-Wno-error=misleading-indentation)
#These seem to indicate real issues
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)

View File

@ -1,127 +0,0 @@
#!/bin/bash
# Usage:
# build-dotnet-tarball <tag-from-source-build>
#
# Creates a source archive from a tag (or commit) at github.com/dotnet/source-build
# Source-build is a little strange, we need to clone it, check out the
# tag, build it and then create a tarball from the archive directory
# it creates. Also, it is likely that the source archive is only
# buildable on the OS it was initially created in.
set -euo pipefail
IFS=$'\n\t'
print_usage() {
echo "Usage:"
echo "$0 <tag-from-source-build>"
echo
echo "Creates a source archive from a tag at https://github.com/dotnet/source-build"
}
clean_dotnet_cache() {
rm -rf ~/.aspnet ~/.dotnet/ ~/.nuget/ ~/.local/share/NuGet ~/.templateengine
rm -rf /tmp/NuGet /tmp/NuGetScratch /tmp/.NETCore* /tmp/.NETStandard* /tmp/.dotnet /tmp/dotnet.* /tmp/clr-debug-pipe* /tmp/Razor-Server /tmp/CoreFxPipe* /tmp/VBCSCompiler /tmp/.NETFramework*
}
function runtime_id {
declare -A archmap
archmap=(
["aarch64"]="arm64"
["amd64"]="x64"
["armv8l"]="arm"
["i686"]="x86"
["i386"]="x86"
["x86_64"]="x64"
)
arch=${archmap["$(uname -m)"]}
source /etc/os-release
case "${ID}" in
# Remove the RHEL minor version
rhel) rid_version=${VERSION_ID%.*} ;;
*) rid_version=${VERSION_ID} ;;
esac
echo "${ID}.${rid_version}-${arch}"
}
positional_args=()
while [[ "$#" -gt 0 ]]; do
arg="${1}"
case "${arg}" in
-h|--help)
print_usage
exit 0
;;
*)
positional_args+=("$1")
shift
;;
esac
done
tag=${positional_args[0]:-}
if [[ -z ${tag} ]]; then
echo "error: missing tag to build"
exit 1
fi
set -x
dir_name="dotnet-${tag}"
unmodified_tarball_name="${dir_name}-original"
tarball_name="${dir_name}"
if [ -f "${tarball_name}.tar.gz" ]; then
echo "error: ${tarball_name}.tar.gz already exists"
exit 1
fi
if [ ! -f "${unmodified_tarball_name}.tar.gz" ]; then
temp_dir=$(mktemp -d -p "$(pwd)")
pushd "${temp_dir}"
git clone https://github.com/dotnet/source-build
pushd source-build
git checkout "${tag}"
git submodule update --init --recursive
clean_dotnet_cache
sed -i -e 's|cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE||' repos/coreclr.proj
mkdir -p patches/coreclr/
cp ../../build-coreclr-clang10.patch patches/coreclr/
cp ../../coreclr-libunwind-fno-common.patch patches/coreclr/
mkdir -p patches/corefx/
cp ../../corefx-42900-clang-10.patch patches/corefx/
mkdir -p patches/aspnetcore/
cp ../../disable-aspnetcore-targetingpackoverride.patch patches/aspnetcore/
./build.sh /p:ArchiveDownloadedPackages=true /p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000 /p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000
./build-source-tarball.sh "${unmodified_tarball_name}" --skip-build
popd
popd
tar czf "${unmodified_tarball_name}.tar.gz" -C "${temp_dir}/source-build" "${unmodified_tarball_name}"
rm -rf "${temp_dir}"
fi
rm -rf "${tarball_name}"
tar xf "${unmodified_tarball_name}.tar.gz"
mv "${unmodified_tarball_name}" "${tarball_name}"
pushd "${tarball_name}"
# Remove files with funny licenses, crypto implementations and other
# not-very-useful artifacts to reduce tarball size
find -type f -iname '*.tar.gz' -delete
rm -rf .dotnet
rm -r src/aspnetcore.*/src/SignalR/clients/java/signalr/gradle*
find src/aspnetcore.*/src -type d -name samples -print0 | xargs -0 rm -r
rm -r src/NuGet.Client.*/test/EndToEnd/ProjectTemplates/NetCoreWebApplication1.0.zip
find src/coreclr.*/ -depth -name tests -print0 | xargs -0 rm -r
popd
tar czf "${tarball_name}.tar.gz" "${tarball_name}"

View File

@ -1,136 +0,0 @@
#!/usr/bin/python3
"""
Check debug symbols are present in shared object and can identify
code.
It starts scanning from a directory and recursively scans all ELF
files found in it for various symbols to ensure all debuginfo is
present and nothing has been stripped.
Usage:
./check-debug-symbols /path/of/dir/to/scan/
Example:
./check-debug-symbols /usr/lib64
"""
# This technique was explained to me by Mark Wielaard (mjw).
import collections
import os
import re
import subprocess
import sys
ScanResult = collections.namedtuple('ScanResult',
'file_name debug_info debug_abbrev file_symbols gnu_debuglink')
def scan_file(file):
"Scan the provided file and return a ScanResult containing results of the scan."
# Test for .debug_* sections in the shared object. This is the main test.
# Stripped objects will not contain these.
readelf_S_result = subprocess.run(['eu-readelf', '-S', file],
stdout=subprocess.PIPE, encoding='utf-8', check=True)
has_debug_info = any(line for line in readelf_S_result.stdout.split('\n') if '] .debug_info' in line)
has_debug_abbrev = any(line for line in readelf_S_result.stdout.split('\n') if '] .debug_abbrev' in line)
# Test FILE symbols. These will most likely be removed by anyting that
# manipulates symbol tables because it's generally useless. So a nice test
# that nothing has messed with symbols.
def contains_file_symbols(line):
parts = line.split()
if len(parts) < 8:
return False
return \
parts[2] == '0' and parts[3] == 'FILE' and parts[4] == 'LOCAL' and parts[5] == 'DEFAULT' and \
parts[6] == 'ABS' and re.match(r'((.*/)?[-_a-zA-Z0-9]+\.(c|cc|cpp|cxx))?', parts[7])
readelf_s_result = subprocess.run(["eu-readelf", '-s', file],
stdout=subprocess.PIPE, encoding='utf-8', check=True)
has_file_symbols = any(line for line in readelf_s_result.stdout.split('\n') if contains_file_symbols(line))
# Test that there are no .gnu_debuglink sections pointing to another
# debuginfo file. There shouldn't be any debuginfo files, so the link makes
# no sense either.
has_gnu_debuglink = any(line for line in readelf_s_result.stdout.split('\n') if '] .gnu_debuglink' in line)
return ScanResult(file, has_debug_info, has_debug_abbrev, has_file_symbols, has_gnu_debuglink)
def is_elf(file):
result = subprocess.run(['file', file], stdout=subprocess.PIPE, encoding='utf-8', check=True)
return re.search('ELF 64-bit LSB (?:executable|shared object)', result.stdout)
def scan_file_if_sensible(file):
if is_elf(file):
# print(file)
return scan_file(file)
return None
def scan_dir(dir):
results = []
for root, _, files in os.walk(dir):
for name in files:
result = scan_file_if_sensible(os.path.join(root, name))
if result:
results.append(result)
return results
def scan(file):
file = os.path.abspath(file)
if os.path.isdir(file):
return scan_dir(file)
elif os.path.isfile(file):
return [scan_file_if_sensible(file)]
def is_bad_result(result):
return not result.debug_info or not result.debug_abbrev or not result.file_symbols or result.gnu_debuglink
def print_scan_results(results, verbose):
# print(results)
for result in results:
file_name = result.file_name
found_issue = False
if not result.debug_info:
found_issue = True
print('error: missing .debug_info section in', file_name)
if not result.debug_abbrev:
found_issue = True
print('error: missing .debug_abbrev section in', file_name)
if not result.file_symbols:
found_issue = True
print('error: missing FILE symbols in', file_name)
if result.gnu_debuglink:
found_issue = True
print('error: unexpected .gnu_debuglink section in', file_name)
if verbose and not found_issue:
print('OK: ', file_name)
def main(args):
verbose = False
files = []
for arg in args:
if arg == '--verbose' or arg == '-v':
verbose = True
else:
files.append(arg)
results = []
for file in files:
results.extend(scan(file))
print_scan_results(results, verbose)
if any(is_bad_result(result) for result in results):
return 1
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -1,18 +0,0 @@
diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs
index de1ebb9e6..6bbf479de 100644
--- a/src/dotnet/Program.cs
+++ b/src/dotnet/Program.cs
@@ -28,6 +28,13 @@ public class Program
public static int Main(string[] args)
{
+ // opt out of telemetry by default if the env var is unset
+ string telemetryValue = Environment.GetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT");
+ if (String.IsNullOrEmpty(telemetryValue))
+ {
+ Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
+ }
+
DebugHelper.HandleDebugSwitch(ref args);
new MulticoreJitActivator().TryActivateMulticoreJit();

View File

@ -1,19 +0,0 @@
diff --git a/src/corehost/cli/test/nativehost/host_context_test.cpp b/src/corehost/cli/test/nativehost/host_context_test.cpp
index e6dc9f6d8..d42c0e0f2 100644
--- a/src/corehost/cli/test/nativehost/host_context_test.cpp
+++ b/src/corehost/cli/test/nativehost/host_context_test.cpp
@@ -11,6 +11,7 @@
#include <corehost_context_contract.h>
#include "host_context_test.h"
#include <utils.h>
+#include <thread>
namespace
{
@@ -539,4 +540,4 @@ bool host_context_test::load_assembly_and_get_function_pointer(
hostfxr_exports hostfxr{ hostfxr_path };
return load_assembly_and_get_function_pointer(hostfxr, config_path, argc, argv, config_log_prefix, test_output);
-}
\ No newline at end of file
+}

View File

@ -1,11 +0,0 @@
diff --git a/src/settings.cmake b/src/settings.cmake
--- a/src/settings.cmake
+++ b/src/settings.cmake
@@ -218,6 +218,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic -Bsymbolic-functions")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=sha1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
add_compile_options(-fstack-protector-strong)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_compile_options(-fstack-protector)

View File

@ -1,11 +0,0 @@
diff --git a/src/debug/createdump/CMakeLists.txt b/src/debug/createdump/CMakeLists.txt
--- a/src/debug/createdump/CMakeLists.txt
+++ b/src/debug/createdump/CMakeLists.txt
@@ -21,6 +21,7 @@ include_directories(BEFORE ${VM_DIR})
add_definitions(-DPAL_STDCPP_COMPAT)
add_compile_options(-fPIE)
+add_link_options(-pie)
set(CREATEDUMP_SOURCES
createdump.cpp

View File

@ -1,402 +0,0 @@
From 29e17d8d2ccbca07c423e3089a6d5ae8a1c9cb6e Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Tue, 31 Mar 2020 00:43:32 -0400
Subject: [PATCH] Fix compilation with -fno-common.
Making all other archs consistent with IA64 which should not have this problem.
Also move the FIXME to the correct place.
Also add some minimum comments about this...
---
src/aarch64/Ginit.c | 15 +++++++--------
src/arm/Ginit.c | 15 +++++++--------
src/coredump/_UPT_get_dyn_info_list_addr.c | 5 +++++
src/hppa/Ginit.c | 15 +++++++--------
src/ia64/Ginit.c | 1 +
src/mi/Gfind_dynamic_proc_info.c | 1 +
src/mips/Ginit.c | 15 +++++++--------
src/ppc32/Ginit.c | 11 +++++++----
src/ppc64/Ginit.c | 11 +++++++----
src/ptrace/_UPT_get_dyn_info_list_addr.c | 5 +++++
src/s390x/Ginit.c | 15 +++++++--------
src/sh/Ginit.c | 15 +++++++--------
src/tilegx/Ginit.c | 15 +++++++--------
src/x86/Ginit.c | 15 +++++++--------
src/x86_64/Ginit.c | 15 +++++++--------
15 files changed, 89 insertions(+), 80 deletions(-)
diff --git a/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/pal/src/libunwind/src/aarch64/Ginit.c
index dec235c82..35389762f 100644
--- a/src/pal/src/libunwind/src/aarch64/Ginit.c
+++ b/src/pal/src/libunwind/src/aarch64/Ginit.c
@@ -61,13 +61,6 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -78,7 +71,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/arm/Ginit.c b/ssrc/pal/src/libunwind/src/arm/Ginit.c
index 2720d063a..0bac0d72d 100644
--- a/src/pal/src/libunwind/src/arm/Ginit.c
+++ b/src/pal/src/libunwind/src/arm/Ginit.c
@@ -57,18 +57,17 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
index 0d1190556..739ed0569 100644
--- a/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
+++ b/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
@@ -74,6 +74,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
#else
+/* XXX fix me: there is currently no way to locate the dyn-info list
+ by a remote unwinder. On ia64, this is done via a special
+ unwind-table entry. Perhaps something similar can be done with
+ DWARF2 unwind info. */
+
static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp)
diff --git a/src/pal/src/libunwind/src/hppa/Ginit.c b/src/pal/src/libunwind/src/hppa/Ginit.c
index 461e4b93d..265455a68 100644
--- a/src/pal/src/libunwind/src/hppa/Ginit.c
+++ b/src/pal/src/libunwind/src/hppa/Ginit.c
@@ -64,13 +64,6 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -81,7 +74,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ia64/Ginit.c b/src/pal/src/libunwind/src/ia64/Ginit.c
index b09a2ad57..8601bb3ca 100644
--- a/src/pal/src/libunwind/src/ia64/Ginit.c
+++ b/src/pal/src/libunwind/src/ia64/Ginit.c
@@ -68,6 +68,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
if (!_U_dyn_info_list_addr)
return -UNW_ENOINFO;
#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
*dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
index 98d350128..2e7c62e5e 100644
--- a/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
+++ b/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
@@ -49,6 +49,7 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
return -UNW_ENOINFO;
#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr ();
for (di = list->first; di; di = di->next)
if (ip >= di->start_ip && ip < di->end_ip)
diff --git a/src/pal/src/libunwind/src/mips/Ginit.c b/src/pal/src/libunwind/src/mips/Ginit.c
index 3df170c75..bf7a8f5a8 100644
--- a/src/pal/src/libunwind/src/mips/Ginit.c
+++ b/src/pal/src/libunwind/src/mips/Ginit.c
@@ -69,13 +69,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -86,7 +79,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/pal/src/libunwind/src/ppc32/Ginit.c
index ba302448a..7b4545580 100644
--- a/src/pal/src/libunwind/src/ppc32/Ginit.c
+++ b/src/pal/src/libunwind/src/ppc32/Ginit.c
@@ -91,9 +91,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -104,7 +101,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/pal/src/libunwind/src/ppc64/Ginit.c
index 4c88cd6e7..7bfb395a7 100644
--- a/src/pal/src/libunwind/src/ppc64/Ginit.c
+++ b/src/pal/src/libunwind/src/ppc64/Ginit.c
@@ -95,9 +95,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -108,7 +105,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
index cc5ed0441..16671d453 100644
--- a/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
+++ b/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
@@ -71,6 +71,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
#else
+/* XXX fix me: there is currently no way to locate the dyn-info list
+ by a remote unwinder. On ia64, this is done via a special
+ unwind-table entry. Perhaps something similar can be done with
+ DWARF2 unwind info. */
+
static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp)
diff --git a/src/pal/src/libunwind/src/sh/Ginit.c b/src/pal/src/libunwind/src/sh/Ginit.c
index 52988a721..9fe96d2bd 100644
--- a/src/pal/src/libunwind/src/sh/Ginit.c
+++ b/src/pal/src/libunwind/src/sh/Ginit.c
@@ -58,13 +58,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -75,7 +68,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/pal/src/libunwind/src/tilegx/Ginit.c
index 7564a558b..925e64132 100644
--- a/src/pal/src/libunwind/src/tilegx/Ginit.c
+++ b/src/pal/src/libunwind/src/tilegx/Ginit.c
@@ -64,13 +64,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -81,7 +74,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/x86/Ginit.c b/src/pal/src/libunwind/src/x86/Ginit.c
index f6b8dc27d..3cec74a21 100644
--- a/src/pal/src/libunwind/src/x86/Ginit.c
+++ b/src/pal/src/libunwind/src/x86/Ginit.c
@@ -54,13 +54,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -71,7 +64,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/pal/src/libunwind/src/x86_64/Ginit.c
index a865d3385..fd8d418b1 100644
--- a/src/pal/src/libunwind/src/x86_64/Ginit.c
+++ b/src/pal/src/libunwind/src/x86_64/Ginit.c
@@ -49,13 +49,6 @@ static struct unw_addr_space local_addr_space;
unw_addr_space_t unw_local_addr_space = &local_addr_space;
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -66,7 +59,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}

View File

@ -1,46 +0,0 @@
From 1864630f762160e1cb439362cc0577471624192a Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 19 Jul 2019 19:18:51 -0400
Subject: [PATCH] Fix up cgroup2fs in Interop.MountPoints.FormatInfo
`stat -fc %T /sys/fs/cgroup` calls this file system `cgroup2fs`
Add the cgroup2fs file system magic number. Available from:
- https://www.kernel.org/doc/Documentation/cgroup-v2.txt
- man 2 statfs
Move cgroup2fs next to cgroupfs in the drive type list, since it is also
DriveType.Ram.
---
.../Unix/System.Native/Interop.MountPoints.FormatInfo.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs b/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
index af38a2285ba2..4240bd4853ab 100644
--- a/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
+++ b/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
@@ -47,6 +47,7 @@ internal enum UnixFileSystemTypes : long
btrfs = 0x9123683E,
ceph = 0x00C36400,
cgroupfs = 0x0027E0EB,
+ cgroup2fs = 0x63677270,
cifs = 0xFF534D42,
coda = 0x73757245,
coherent = 0x012FF7B7,
@@ -231,7 +232,6 @@ private static DriveType GetDriveType(string fileSystemName)
case "bpf_fs":
case "btrfs":
case "btrfs_test":
- case "cgroup2fs":
case "coh":
case "daxfs":
case "drvfs":
@@ -384,6 +384,7 @@ private static DriveType GetDriveType(string fileSystemName)
case "binfmt_misc":
case "cgroup":
case "cgroupfs":
+ case "cgroup2fs":
case "configfs":
case "cramfs":
case "cramfs-wend":

View File

@ -1,391 +0,0 @@
From 2b2273ea4ea1c28472fa0d6ad2ffeb6374500550 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Wed, 23 Oct 2019 17:45:59 -0400
Subject: [PATCH 1/2] Add cgroup v2 support to Interop.cgroups
Fix up code to adjust cgroup v1 assumptions and check cgroup v2 paths,
locations and values.
Continue using the older cgroup v1 terminology for APIs.
---
.../Interop/Linux/cgroups/Interop.cgroups.cs | 116 ++++++++++++++----
src/Common/tests/Common.Tests.csproj | 4 +
.../tests/Tests/Interop/cgroupsTests.cs | 107 ++++++++++++++++
.../tests/DescriptionNameTests.cs | 2 +-
4 files changed, 206 insertions(+), 23 deletions(-)
create mode 100644 src/Common/tests/Tests/Interop/cgroupsTests.cs
diff --git a/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs b/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
index 0ffd4d7b7c03..186fe0516c5b 100644
--- a/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
+++ b/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
@@ -9,17 +9,22 @@
internal static partial class Interop
{
+ /// <summary>Provides access to some cgroup (v1 and v2) features</summary>
internal static partial class cgroups
{
+ // For cgroup v1, see https://www.kernel.org/doc/Documentation/cgroup-v1/
+ // For cgroup v2, see https://www.kernel.org/doc/Documentation/cgroup-v2.txt
+
+ /// <summary>The version of cgroup that's being used </summary>
+ internal enum CGroupVersion { None, CGroup1, CGroup2 };
+
/// <summary>Path to mountinfo file in procfs for the current process.</summary>
private const string ProcMountInfoFilePath = "/proc/self/mountinfo";
/// <summary>Path to cgroup directory in procfs for the current process.</summary>
private const string ProcCGroupFilePath = "/proc/self/cgroup";
- /// <summary>Path to the found cgroup location, or null if it couldn't be found.</summary>
- internal static readonly string s_cgroupMemoryPath = FindCGroupPath("memory");
- /// <summary>Path to the found cgroup memory limit_in_bytes path, or null if it couldn't be found.</summary>
- private static readonly string s_cgroupMemoryLimitPath = s_cgroupMemoryPath != null ? s_cgroupMemoryPath + "/memory.limit_in_bytes" : null;
+ /// <summary>Path to the found cgroup memory limit path, or null if it couldn't be found.</summary>
+ internal static readonly string s_cgroupMemoryLimitPath = FindCGroupMemoryLimitPath();
/// <summary>Tries to read the memory limit from the cgroup memory location.</summary>
/// <param name="limit">The read limit, or 0 if it couldn't be read.</param>
@@ -42,7 +47,7 @@ public static bool TryGetMemoryLimit(out ulong limit)
/// <param name="path">The path to the file to parse.</param>
/// <param name="result">The parsed result, or 0 if it couldn't be parsed.</param>
/// <returns>true if the value was read successfully; otherwise, false.</returns>
- private static bool TryReadMemoryValueFromFile(string path, out ulong result)
+ internal static bool TryReadMemoryValueFromFile(string path, out ulong result)
{
if (File.Exists(path))
{
@@ -79,6 +84,11 @@ private static bool TryReadMemoryValueFromFile(string path, out ulong result)
result = checked(ulongValue * multiplier);
return true;
}
+
+ // 'max' is also a possible valid value
+ //
+ // Treat this as 'no memory limit' and let the caller
+ // fallback to reading the real limit via other means
}
catch (Exception e)
{
@@ -90,12 +100,35 @@ private static bool TryReadMemoryValueFromFile(string path, out ulong result)
return false;
}
+ /// <summary>Find the cgroup memory limit path.</summary>
+ /// <returns>The limit path if found; otherwise, null.</returns>
+ private static string FindCGroupMemoryLimitPath()
+ {
+ string cgroupMemoryPath = FindCGroupPath("memory", out CGroupVersion version);
+ if (cgroupMemoryPath != null)
+ {
+ if (version == CGroupVersion.CGroup1)
+ {
+ return cgroupMemoryPath + "/memory.limit_in_bytes";
+ }
+
+ if (version == CGroupVersion.CGroup2)
+ {
+ // 'memory.high' is a soft limit; the process may get throttled
+ // 'memory.max' is where OOM killer kicks in
+ return cgroupMemoryPath + "/memory.max";
+ }
+ }
+
+ return null;
+ }
+
/// <summary>Find the cgroup path for the specified subsystem.</summary>
/// <param name="subsystem">The subsystem, e.g. "memory".</param>
/// <returns>The cgroup path if found; otherwise, null.</returns>
- private static string FindCGroupPath(string subsystem)
+ private static string FindCGroupPath(string subsystem, out CGroupVersion version)
{
- if (TryFindHierarchyMount(subsystem, out string hierarchyRoot, out string hierarchyMount) &&
+ if (TryFindHierarchyMount(subsystem, out version, out string hierarchyRoot, out string hierarchyMount) &&
TryFindCGroupPathForSubsystem(subsystem, out string cgroupPathRelativeToMount))
{
// For a host cgroup, we need to append the relative path.
@@ -113,19 +146,24 @@ private static string FindCGroupPath(string subsystem)
/// <param name="root">The path of the directory in the filesystem which forms the root of this mount; null if not found.</param>
/// <param name="path">The path of the mount point relative to the process's root directory; null if not found.</param>
/// <returns>true if the mount was found; otherwise, null.</returns>
- private static bool TryFindHierarchyMount(string subsystem, out string root, out string path)
+ private static bool TryFindHierarchyMount(string subsystem, out CGroupVersion version, out string root, out string path)
{
- if (File.Exists(ProcMountInfoFilePath))
+ return TryFindHierarchyMount(ProcMountInfoFilePath, subsystem, out version, out root, out path);
+ }
+
+ internal static bool TryFindHierarchyMount(string mountInfoFilePath, string subsystem, out CGroupVersion version, out string root, out string path)
+ {
+ if (File.Exists(mountInfoFilePath))
{
try
{
- using (var reader = new StreamReader(ProcMountInfoFilePath))
+ using (var reader = new StreamReader(mountInfoFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Look for an entry that has cgroup as the "filesystem type"
- // and that has options containing the specified subsystem.
+ // and, for cgroup1, that has options containing the specified subsystem
// See man page for /proc/[pid]/mountinfo for details, e.g.:
// (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
// 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
@@ -148,17 +186,35 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
continue;
}
- if (postSeparatorlineParts[0] != "cgroup" ||
- Array.IndexOf(postSeparatorlineParts[2].Split(','), subsystem) < 0)
+ bool validCGroup1Entry = ((postSeparatorlineParts[0] == "cgroup") &&
+ (Array.IndexOf(postSeparatorlineParts[2].Split(','), subsystem) >= 0));
+ bool validCGroup2Entry = postSeparatorlineParts[0] == "cgroup2";
+
+ if (!validCGroup1Entry && !validCGroup2Entry)
{
// Not the relevant entry.
continue;
}
- // Found the relevant entry. Extract the mount root and path.
+ // Found the relevant entry. Extract the cgroup version, mount root and path.
+ switch (postSeparatorlineParts[0])
+ {
+ case "cgroup":
+ version = CGroupVersion.CGroup1;
+ break;
+ case "cgroup2":
+ version = CGroupVersion.CGroup2;
+ break;
+ default:
+ version = CGroupVersion.None;
+ Debug.Fail($"invalid value for CGroupVersion \"{postSeparatorlineParts[0]}\"");
+ break;
+ }
+
string[] lineParts = line.Substring(0, endOfOptionalFields).Split(' ');
root = lineParts[3];
path = lineParts[4];
+
return true;
}
}
@@ -169,6 +225,7 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
}
}
+ version = CGroupVersion.None;
root = null;
path = null;
return false;
@@ -180,27 +237,42 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
/// <returns></returns>
private static bool TryFindCGroupPathForSubsystem(string subsystem, out string path)
{
- if (File.Exists(ProcCGroupFilePath))
+ return TryFindCGroupPathForSubsystem(ProcCGroupFilePath, subsystem, out path);
+ }
+
+ internal static bool TryFindCGroupPathForSubsystem(string procCGroupFilePath, string subsystem, out string path)
+ {
+ if (File.Exists(procCGroupFilePath))
{
try
{
- using (var reader = new StreamReader(ProcCGroupFilePath))
+ using (var reader = new StreamReader(procCGroupFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
- // Find the first entry that has the subsystem listed in its controller
- // list. See man page for cgroups for /proc/[pid]/cgroups format, e.g:
- // hierarchy-ID:controller-list:cgroup-path
- // 5:cpuacct,cpu,cpuset:/daemons
-
string[] lineParts = line.Split(':');
+
if (lineParts.Length != 3)
{
// Malformed line.
continue;
}
+ // cgroup v2: Find the first entry that matches the cgroup v2 hierarchy:
+ // 0::$PATH
+
+ if ((lineParts[0] == "0") && (string.Empty == lineParts[1]))
+ {
+ path = lineParts[2];
+ return true;
+ }
+
+ // cgroup v1: Find the first entry that has the subsystem listed in its controller
+ // list. See man page for cgroups for /proc/[pid]/cgroups format, e.g:
+ // hierarchy-ID:controller-list:cgroup-path
+ // 5:cpuacct,cpu,cpuset:/daemons
+
if (Array.IndexOf(lineParts[1].Split(','), subsystem) < 0)
{
// Not the relevant entry.
@@ -214,7 +286,7 @@ private static bool TryFindCGroupPathForSubsystem(string subsystem, out string p
}
catch (Exception e)
{
- Debug.Fail($"Failed to read or parse \"{ProcMountInfoFilePath}\": {e}");
+ Debug.Fail($"Failed to read or parse \"{procCGroupFilePath}\": {e}");
}
}
diff --git a/src/Common/tests/Common.Tests.csproj b/src/Common/tests/Common.Tests.csproj
index a189d856348b..979c8dd7fbe6 100644
--- a/src/Common/tests/Common.Tests.csproj
+++ b/src/Common/tests/Common.Tests.csproj
@@ -12,6 +12,9 @@
<Compile Include="$(CommonTestPath)\System\Security\Cryptography\ByteUtils.cs">
<Link>Common\System\Security\Cryptography\ByteUtils.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)\Interop\Linux\cgroups\Interop.cgroups.cs">
+ <Link>Common\Interop\Linux\cgroups\Interop.cgroups.cs</Link>
+ </Compile>
<Compile Include="$(CommonPath)\Interop\Linux\procfs\Interop.ProcFsStat.cs">
<Link>Common\Interop\Linux\procfs\Interop.ProcFsStat.cs</Link>
</Compile>
@@ -69,6 +72,7 @@
<Compile Include="$(CommonPath)\CoreLib\System\PasteArguments.cs">
<Link>Common\CoreLib\System\PasteArguments.cs</Link>
</Compile>
+ <Compile Include="Tests\Interop\cgroupsTests.cs" />
<Compile Include="Tests\Interop\procfsTests.cs" />
<Compile Include="Tests\System\CharArrayHelpersTests.cs" />
<Compile Include="Tests\System\IO\PathInternal.Tests.cs" />
diff --git a/src/Common/tests/Tests/Interop/cgroupsTests.cs b/src/Common/tests/Tests/Interop/cgroupsTests.cs
new file mode 100644
index 000000000000..f16d9242879c
--- /dev/null
+++ b/src/Common/tests/Tests/Interop/cgroupsTests.cs
@@ -0,0 +1,107 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace Common.Tests
+{
+ public class cgroupsTests
+ {
+ [Theory]
+ [InlineData(true, "0", 0)]
+ [InlineData(false, "max", 0)]
+ [InlineData(true, "1k", 1024)]
+ [InlineData(true, "1K", 1024)]
+ public static void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, valueText);
+
+ bool result = Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val);
+
+ Assert.Equal(expectedResult, result);
+ if (result)
+ {
+ Assert.Equal(expectedValue, val);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+
+ [Theory]
+ [InlineData(false, "0 0 0:0 / /foo ignore ignore - overlay overlay ignore", "ignore", 0, "/", "/")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "ignore", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "memory", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo-with-dashes ignore ignore - cgroup2 cgroup2 ignore", "ignore", 2, "/", "/foo-with-dashes")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory", "memory", 1, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo-with-dashes ignore ignore - cgroup cgroup memory", "memory", 1, "/", "/foo-with-dashes")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu,memory", "memory", 1, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory,cpu", "memory", 1, "/", "/foo")]
+ [InlineData(false, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu", "memory", 0, "/", "/foo")]
+ public static void ParseValidateMountInfo(bool found, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, procSelfMountInfoText);
+
+ bool result = Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount);
+
+ Assert.Equal(found, result);
+ if (found)
+ {
+ Assert.Equal(expectedVersion, (int)version);
+ Assert.Equal(expectedRoot, root);
+ Assert.Equal(expectedMount, mount);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+
+ [Theory]
+ [InlineData(true, "0::/foo", "ignore", "/foo")]
+ [InlineData(true, "0::/bar", "ignore", "/bar")]
+ [InlineData(true, "0::frob", "ignore", "frob")]
+ [InlineData(false, "1::frob", "ignore", "ignore")]
+ [InlineData(true, "1:foo:bar", "foo", "bar")]
+ [InlineData(true, "2:foo:bar", "foo", "bar")]
+ [InlineData(false, "2:foo:bar", "bar", "ignore")]
+ [InlineData(true, "1:foo:bar\n2:eggs:spam", "foo", "bar")]
+ [InlineData(true, "1:foo:bar\n2:eggs:spam", "eggs", "spam")]
+ public static void ParseValidateProcCGroup(bool found, string procSelfCgroupText, string subsystem, string expectedMountPath)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, procSelfCgroupText);
+
+ bool result = Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath);
+
+ Assert.Equal(found, result);
+ if (found)
+ {
+ Assert.Equal(expectedMountPath, mountPath);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+ }
+}
diff --git a/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs b/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
index 910af2fd82b4..73f692898dbc 100644
--- a/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
+++ b/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
@@ -40,7 +40,7 @@ public void DumpRuntimeInformationToConsole()
Console.WriteLine($"### CURRENT DIRECTORY: {Environment.CurrentDirectory}");
- string cgroupsLocation = Interop.cgroups.s_cgroupMemoryPath;
+ string cgroupsLocation = Interop.cgroups.s_cgroupMemoryLimitPath;
if (cgroupsLocation != null)
{
Console.WriteLine($"### CGROUPS MEMORY: {cgroupsLocation}");

View File

@ -1,129 +0,0 @@
From 9a8c5e4014ffca8aff70808cc0e50a403d38c292 Mon Sep 17 00:00:00 2001
From: Stephen Toub <stoub@microsoft.com>
Date: Wed, 23 Oct 2019 20:35:49 -0400
Subject: [PATCH 2/2] Clean up new tests
---
.../tests/Tests/Interop/cgroupsTests.cs | 79 ++++++-------------
1 file changed, 25 insertions(+), 54 deletions(-)
diff --git a/src/Common/tests/Tests/Interop/cgroupsTests.cs b/src/Common/tests/Tests/Interop/cgroupsTests.cs
index f16d9242879c..fc6ab5c9753c 100644
--- a/src/Common/tests/Tests/Interop/cgroupsTests.cs
+++ b/src/Common/tests/Tests/Interop/cgroupsTests.cs
@@ -2,38 +2,27 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.IO;
-using System.Text;
using Xunit;
namespace Common.Tests
{
- public class cgroupsTests
+ public class cgroupsTests : FileCleanupTestBase
{
[Theory]
- [InlineData(true, "0", 0)]
- [InlineData(false, "max", 0)]
- [InlineData(true, "1k", 1024)]
- [InlineData(true, "1K", 1024)]
- public static void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
+ [InlineData(true, "0", 0)]
+ [InlineData(false, "max", 0)]
+ [InlineData(true, "1k", 1024)]
+ [InlineData(true, "1K", 1024)]
+ public void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, valueText);
-
- bool result = Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, valueText);
- Assert.Equal(expectedResult, result);
- if (result)
- {
- Assert.Equal(expectedValue, val);
- }
- }
- finally
+ Assert.Equal(expectedResult, Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val));
+ if (expectedResult)
{
- File.Delete(path);
+ Assert.Equal(expectedValue, val);
}
}
@@ -50,26 +39,17 @@ public static void ValidateTryReadMemoryValue(bool expectedResult, string valueT
[InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu,memory", "memory", 1, "/", "/foo")]
[InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory,cpu", "memory", 1, "/", "/foo")]
[InlineData(false, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu", "memory", 0, "/", "/foo")]
- public static void ParseValidateMountInfo(bool found, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
+ public void ParseValidateMountInfo(bool expectedFound, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, procSelfMountInfoText);
-
- bool result = Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, procSelfMountInfoText);
- Assert.Equal(found, result);
- if (found)
- {
- Assert.Equal(expectedVersion, (int)version);
- Assert.Equal(expectedRoot, root);
- Assert.Equal(expectedMount, mount);
- }
- }
- finally
+ Assert.Equal(expectedFound, Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount));
+ if (expectedFound)
{
- File.Delete(path);
+ Assert.Equal(expectedVersion, (int)version);
+ Assert.Equal(expectedRoot, root);
+ Assert.Equal(expectedMount, mount);
}
}
@@ -83,24 +63,15 @@ public static void ParseValidateMountInfo(bool found, string procSelfMountInfoTe
[InlineData(false, "2:foo:bar", "bar", "ignore")]
[InlineData(true, "1:foo:bar\n2:eggs:spam", "foo", "bar")]
[InlineData(true, "1:foo:bar\n2:eggs:spam", "eggs", "spam")]
- public static void ParseValidateProcCGroup(bool found, string procSelfCgroupText, string subsystem, string expectedMountPath)
+ public void ParseValidateProcCGroup(bool expectedFound, string procSelfCgroupText, string subsystem, string expectedMountPath)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, procSelfCgroupText);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, procSelfCgroupText);
- bool result = Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath);
-
- Assert.Equal(found, result);
- if (found)
- {
- Assert.Equal(expectedMountPath, mountPath);
- }
- }
- finally
+ Assert.Equal(expectedFound, Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath));
+ if (expectedFound)
{
- File.Delete(path);
+ Assert.Equal(expectedMountPath, mountPath);
}
}
}

View File

@ -1,70 +0,0 @@
From 58d6cd09bd2d5b1085c6572c1d97b8533cf8294b Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 3 Apr 2020 13:53:09 -0400
Subject: [PATCH] Fix corefx to build on clang 10
Clang 10 adds/enables new warnings, some of which is affecting
the corefx code.
Clang 10 has added -Walloca to warn about uses of alloca. This commit
replaces the only non-compliant use of that with a single fixed
stack-allocated buffer.
Clang 10 has also added -Wimplicit-int-float-conversion. This commit
uses explicit casts to double to avoid the warnings.
This is a backport of dotnet/runtime#33734 to corefx.
After this commit, I can build all of corefx with Clang 10.
---
src/Native/Unix/System.Native/pal_io.c | 20 +++++++++++---------
src/Native/Unix/System.Native/pal_time.c | 2 +-
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/src/Native/Unix/System.Native/pal_io.c b/src/Native/Unix/System.Native/pal_io.c
index 2d51edacf5ee..c7c42eb3e72b 100644
--- a/src/Native/Unix/System.Native/pal_io.c
+++ b/src/Native/Unix/System.Native/pal_io.c
@@ -906,18 +906,20 @@ int32_t SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t mi
return Error_EINVAL;
}
- size_t bufferSize;
- if (!multiply_s(sizeof(struct pollfd), (size_t)eventCount, &bufferSize))
+ struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))];
+ int useStackBuffer = eventCount <= (sizeof(stackBuffer)/sizeof(stackBuffer[0]));
+ struct pollfd* pollfds = NULL;
+ if (useStackBuffer)
{
- return SystemNative_ConvertErrorPlatformToPal(EOVERFLOW);
+ pollfds = (struct pollfd*)&stackBuffer[0];
}
-
-
- int useStackBuffer = bufferSize <= 2048;
- struct pollfd* pollfds = (struct pollfd*)(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));
- if (pollfds == NULL)
+ else
{
- return Error_ENOMEM;
+ pollfds = (struct pollfd*)calloc(eventCount, sizeof(*pollfds));
+ if (pollfds == NULL)
+ {
+ return Error_ENOMEM;
+ }
}
for (uint32_t i = 0; i < eventCount; i++)
diff --git a/src/Native/Unix/System.Native/pal_time.c b/src/Native/Unix/System.Native/pal_time.c
index 1a7c862749d1..54ebde60a83b 100644
--- a/src/Native/Unix/System.Native/pal_time.c
+++ b/src/Native/Unix/System.Native/pal_time.c
@@ -169,7 +169,7 @@ int32_t SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo)
uint64_t resolution = SystemNative_GetTimestampResolution();
uint64_t timestamp = SystemNative_GetTimestamp();
- uint64_t currentTime = (uint64_t)(timestamp * ((double)SecondsToNanoSeconds / resolution));
+ uint64_t currentTime = (uint64_t)((double)timestamp * ((double)SecondsToNanoSeconds / (double)resolution));
uint64_t lastRecordedCurrentTime = previousCpuInfo->lastRecordedCurrentTime;
uint64_t lastRecordedKernelTime = previousCpuInfo->lastRecordedKernelTime;

View File

@ -1,40 +0,0 @@
diff --git a/src/Native/Unix/CMakeLists.txt b/src/Native/Unix/CMakeLists.txt
index 7d804a1e54..717c2718d7 100644
--- a/src/Native/Unix/CMakeLists.txt
+++ b/src/Native/Unix/CMakeLists.txt
@@ -25,7 +25,7 @@ add_compile_options(-fPIC)
add_compile_options(-Wthread-safety)
add_compile_options(-Wno-thread-safety-analysis)
+ add_compile_options(-Wno-alloca)
endif()
-add_compile_options(-Werror)
if(CMAKE_SYSTEM_NAME STREQUAL Emscripten)
set(CLR_CMAKE_PLATFORM_WASM 1)
diff --git a/src/Native/Unix/configure.cmake b/src/Native/Unix/configure.cmake
index f4a30ad6cb..f2db68402a 100644
--- a/src/Native/Unix/configure.cmake
+++ b/src/Native/Unix/configure.cmake
@@ -27,6 +27,12 @@ else ()
message(FATAL_ERROR "Unknown platform. Cannot define PAL_UNIX_NAME, used by RuntimeInformation.")
endif ()
+
+set (PREVIOUS_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+set (CMAKE_CXX_FLAGS "-D_GNU_SOURCE")
+set (PREVIOUS_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+set (CMAKE_C_FLAGS "-D_GNU_SOURCE")
+
# We compile with -Werror, so we need to make sure these code fragments compile without warnings.
# Older CMake versions (3.8) do not assign the result of their tests, causing unused-value errors
# which are not distinguished from the test failing. So no error for that one.
@@ -698,6 +704,9 @@ endif()
set (CMAKE_REQUIRED_LIBRARIES)
+set (CMAKE_CXX_FLAGS "${PREVIOUS_CMAKE_CXX_FLAGS}")
+set (CMAKE_C_FLAGS "${PREVIOUS_CMAKE_C_FLAGS}")
+
check_c_source_compiles(
"
#include <sys/inotify.h>

1
dead.package Normal file
View File

@ -0,0 +1 @@
dotnet3.1 package is retired on branch c10s for CS-2551

View File

@ -1 +0,0 @@
dotnet3.1 package is retired for CS-1038

View File

@ -1,11 +0,0 @@
--- Directory.Build.props 2020-06-04 17:54:26.587622453 -0500
+++ Directory.Build.props 2020-06-04 17:54:43.948536557 -0500
@@ -145,8 +145,6 @@
<!-- The location of the local installation of the .NET Core shared framework. -->
<PropertyGroup>
<LocalDotNetRoot>$(RepoRoot).dotnet\</LocalDotNetRoot>
- <!-- Override the SDK default and point to local .dotnet folder. -->
- <NetCoreTargetingPackRoot>$(LocalDotNetRoot)packs\</NetCoreTargetingPackRoot>
</PropertyGroup>
<Import Project="eng\tools\RepoTasks\RepoTasks.tasks" Condition="'$(MSBuildProjectName)' != 'RepoTasks' AND '$(DesignTimeBuild)' != 'true'" />